324 Tris0,27 × 0,56 × 0,91 m
Im Code verwenden
Im Editor remixenfox.js · 209 Zeilen
Eigenständiges ES-Modul — hängt nur von three ab. Ruf die Factory auf und füge die Gruppe deiner Szene hinzu.
/**
* Fox — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 324 · Size (W × H × D): 0.27 × 0.56 × 0.91 m
*
* Usage:
* import { createFox } from './fox.js';
*
* const model = createFox();
* model.position.set(0, 0, 0);
* scene.add(model);
*/
import * as THREE from 'three';
const deg = THREE.MathUtils.degToRad;
// Extrude a 2D outline along Z (centered). bevel = [thickness, size, segments].
function extrude(outline, depth, holes = [], bevel = null) {
const shape = new THREE.Shape(outline.map(([x, y]) => new THREE.Vector2(x, y)));
for (const hole of holes) shape.holes.push(new THREE.Path(hole.map(([x, y]) => new THREE.Vector2(x, y))));
const options = bevel
? { depth, bevelEnabled: true, bevelThickness: bevel[0], bevelSize: bevel[1], bevelSegments: bevel[2] }
: { depth, bevelEnabled: false };
return new THREE.ExtrudeGeometry(shape, options).translate(0, 0, -depth / 2);
}
export function createFox() {
const root = new THREE.Group();
root.name = 'Fox';
// Materials
const furMat = new THREE.MeshStandardMaterial({ name: 'fur', color: 0xe57a2e, roughness: 0.85, flatShading: true });
const whiteMat = new THREE.MeshStandardMaterial({ name: 'white', color: 0xf7efe2, roughness: 0.9, flatShading: true });
const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x3b2b27, roughness: 0.8, flatShading: true });
const eyeMat = new THREE.MeshStandardMaterial({ name: 'eye', color: 0x1a1515, roughness: 0.35, flatShading: true });
const shineMat = new THREE.MeshStandardMaterial({ name: 'shine', color: 0xffffff, roughness: 0.4, flatShading: true });
// Shared geometries
const boxGeo = new THREE.BoxGeometry(0.055, 0.06, 0.055);
const boxGeo2 = new THREE.BoxGeometry(0.06, 0.09, 0.06);
const boxGeo3 = new THREE.BoxGeometry(0.035, 0.045, 0.01);
const boxGeo4 = new THREE.BoxGeometry(0.014, 0.014, 0.006);
const extrudeGeo = extrude([[-0.055, 0], [0.055, 0], [0, 0.13]], 0.03);
const extrudeGeo2 = extrude([[-0.032, 0.012], [0.032, 0.012], [0, 0.085]], 0.01);
const extrudeGeo3 = extrude([[-0.0285, 0.068], [0.0285, 0.068], [0, 0.135]], 0.036);
// Parts
const legFL = new THREE.Group();
legFL.name = 'legFL';
legFL.position.set(0.065, 0.15, 0.11);
root.add(legFL);
const legFLUpper = new THREE.Mesh(boxGeo, furMat);
legFLUpper.name = 'legFLUpper';
legFLUpper.position.set(0, -0.03, 0);
legFL.add(legFLUpper);
const legFLSock = new THREE.Mesh(boxGeo2, darkMat);
legFLSock.name = 'legFLSock';
legFLSock.position.set(0, -0.105, 0.003);
legFL.add(legFLSock);
const legFR = new THREE.Group();
legFR.name = 'legFR';
legFR.position.set(-0.065, 0.15, 0.11);
root.add(legFR);
const legFRUpper = new THREE.Mesh(boxGeo, furMat);
legFRUpper.name = 'legFRUpper';
legFRUpper.position.set(0, -0.03, 0);
legFR.add(legFRUpper);
const legFRSock = new THREE.Mesh(boxGeo2, darkMat);
legFRSock.name = 'legFRSock';
legFRSock.position.set(0, -0.105, 0.003);
legFR.add(legFRSock);
const legBL = new THREE.Group();
legBL.name = 'legBL';
legBL.position.set(0.065, 0.15, -0.12);
root.add(legBL);
const legBLUpper = new THREE.Mesh(boxGeo, furMat);
legBLUpper.name = 'legBLUpper';
legBLUpper.position.set(0, -0.03, 0);
legBL.add(legBLUpper);
const legBLSock = new THREE.Mesh(boxGeo2, darkMat);
legBLSock.name = 'legBLSock';
legBLSock.position.set(0, -0.105, 0.003);
legBL.add(legBLSock);
const legBR = new THREE.Group();
legBR.name = 'legBR';
legBR.position.set(-0.065, 0.15, -0.12);
root.add(legBR);
const legBRUpper = new THREE.Mesh(boxGeo, furMat);
legBRUpper.name = 'legBRUpper';
legBRUpper.position.set(0, -0.03, 0);
legBR.add(legBRUpper);
const legBRSock = new THREE.Mesh(boxGeo2, darkMat);
legBRSock.name = 'legBRSock';
legBRSock.position.set(0, -0.105, 0.003);
legBR.add(legBRSock);
const body = new THREE.Group();
body.name = 'body';
root.add(body);
const torso = new THREE.Mesh(new THREE.BoxGeometry(0.19, 0.17, 0.36), furMat);
torso.name = 'torso';
torso.position.set(0, 0.205, 0);
body.add(torso);
const chest = new THREE.Mesh(new THREE.BoxGeometry(0.15, 0.11, 0.04), whiteMat);
chest.name = 'chest';
chest.position.set(0, 0.195, 0.19);
body.add(chest);
const belly = new THREE.Mesh(new THREE.BoxGeometry(0.13, 0.012, 0.24), whiteMat);
belly.name = 'belly';
belly.position.set(0, 0.116, 0.02);
body.add(belly);
const tail = new THREE.Group();
tail.name = 'tail';
tail.position.set(0, 0.25, -0.16);
tail.rotation.set(deg(18), 0, 0);
root.add(tail);
const tailBase = new THREE.Mesh(new THREE.BoxGeometry(0.09, 0.09, 0.12), furMat);
tailBase.name = 'tailBase';
tailBase.position.set(0, 0, -0.06);
tail.add(tailBase);
const tailBush = new THREE.Mesh(new THREE.BoxGeometry(0.14, 0.14, 0.16), furMat);
tailBush.name = 'tailBush';
tailBush.position.set(0, 0.02, -0.18);
tail.add(tailBush);
const tailTip = new THREE.Mesh(new THREE.BoxGeometry(0.12, 0.12, 0.09), whiteMat);
tailTip.name = 'tailTip';
tailTip.position.set(0, 0.025, -0.3);
tail.add(tailTip);
const head = new THREE.Group();
head.name = 'head';
head.position.set(0, 0.26, 0.15);
root.add(head);
const skull = new THREE.Mesh(new THREE.BoxGeometry(0.26, 0.2, 0.2), furMat);
skull.name = 'skull';
skull.position.set(0, 0.08, 0.05);
head.add(skull);
const cheeks = new THREE.Mesh(new THREE.BoxGeometry(0.268, 0.075, 0.12), whiteMat);
cheeks.name = 'cheeks';
cheeks.position.set(0, 0.0135, 0.094);
head.add(cheeks);
const snout = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.06, 0.09), furMat);
snout.name = 'snout';
snout.position.set(0, 0.05, 0.195);
head.add(snout);
const jaw = new THREE.Mesh(new THREE.BoxGeometry(0.108, 0.03, 0.098), whiteMat);
jaw.name = 'jaw';
jaw.position.set(0, 0.031, 0.195);
head.add(jaw);
const nose = new THREE.Mesh(new THREE.BoxGeometry(0.04, 0.03, 0.025), darkMat);
nose.name = 'nose';
nose.position.set(0, 0.07, 0.248);
head.add(nose);
const eyeL = new THREE.Mesh(boxGeo3, eyeMat);
eyeL.name = 'eyeL';
eyeL.position.set(0.07, 0.105, 0.154);
head.add(eyeL);
const eyeShineL = new THREE.Mesh(boxGeo4, shineMat);
eyeShineL.name = 'eyeShineL';
eyeShineL.position.set(0.075, 0.115, 0.16);
head.add(eyeShineL);
const eyeR = new THREE.Mesh(boxGeo3, eyeMat);
eyeR.name = 'eyeR';
eyeR.position.set(-0.07, 0.105, 0.154);
head.add(eyeR);
const eyeShineR = new THREE.Mesh(boxGeo4, shineMat);
eyeShineR.name = 'eyeShineR';
eyeShineR.position.set(-0.075, 0.115, 0.16);
head.add(eyeShineR);
const earL = new THREE.Group();
earL.name = 'earL';
earL.position.set(0.08, 0.17, 0.02);
earL.rotation.set(deg(-6), 0, deg(-12));
head.add(earL);
const earOuterL = new THREE.Mesh(extrudeGeo, furMat);
earOuterL.name = 'earOuterL';
earL.add(earOuterL);
const earInnerL = new THREE.Mesh(extrudeGeo2, whiteMat);
earInnerL.name = 'earInnerL';
earInnerL.position.set(0, 0, 0.019);
earL.add(earInnerL);
const earTipL = new THREE.Mesh(extrudeGeo3, darkMat);
earTipL.name = 'earTipL';
earL.add(earTipL);
const earR = new THREE.Group();
earR.name = 'earR';
earR.position.set(-0.08, 0.17, 0.02);
earR.rotation.set(deg(-6), 0, deg(12));
head.add(earR);
const earOuterR = new THREE.Mesh(extrudeGeo, furMat);
earOuterR.name = 'earOuterR';
earR.add(earOuterR);
const earInnerR = new THREE.Mesh(extrudeGeo2, whiteMat);
earInnerR.name = 'earInnerR';
earInnerR.position.set(0, 0, 0.019);
earR.add(earInnerR);
const earTipR = new THREE.Mesh(extrudeGeo3, darkMat);
earTipR.name = 'earTipR';
earR.add(earTipR);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createFox;
Bewertungen & Kommentare
—
Noch keine Bewertungen — gib die erste ab.
5
0
4
0
3
0
2
0
1
0
Melde dich an, um zu bewerten und zu kommentieren.
0 Kommentare
Noch keine Kommentare. Erzähl, wie du dieses Modell genutzt hast oder was besser sein könnte.
Ähnliche Modelle
Gleiche Kategorie oder ähnliche Tags









