1,3 mil tris0,27 × 0,22 × 0,28 m
Úsalo en código
Hacer remix en el editorboots.js · 294 líneas
Módulo ES autónomo — solo depende de three. Llama a la función factory y añade el grupo a tu escena.
/**
* Adventurer Boots — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 1,272 · Size (W × H × D): 0.27 × 0.22 × 0.28 m
*
* Usage:
* import { createBoots } from './boots.js';
*
* const model = createBoots();
* model.position.set(0, 0, 0);
* scene.add(model);
*/
import * as THREE from 'three';
const deg = THREE.MathUtils.degToRad;
// Revolve a 2D profile [[radius, y], ...] around the Y axis.
function lathe(points, segments, phiStart = 0, phiLength = Math.PI * 2) {
return new THREE.LatheGeometry(points.map(([x, y]) => new THREE.Vector2(x, y)), segments, phiStart, phiLength);
}
// 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);
}
// Tube along a smooth curve through the given points.
function tube(path, radius, tubularSegments, radialSegments, closed = false) {
const curve = new THREE.CatmullRomCurve3(path.map(([x, y, z]) => new THREE.Vector3(x, y, z)), closed);
return new THREE.TubeGeometry(curve, tubularSegments, radius, radialSegments, closed);
}
export function createBoots() {
const root = new THREE.Group();
root.name = 'Boots';
// Materials
const leatherMat = new THREE.MeshStandardMaterial({ name: 'leather', color: 0x8a5a35, roughness: 0.75, flatShading: true });
const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x563821, roughness: 0.8, flatShading: true });
const cuffMat = new THREE.MeshStandardMaterial({ name: 'cuff', color: 0xab8158, roughness: 0.9, flatShading: true });
const soleMat = new THREE.MeshStandardMaterial({ name: 'sole', color: 0x2f2620, roughness: 0.95, flatShading: true });
const weltMat = new THREE.MeshStandardMaterial({ name: 'welt', color: 0x6b4a2e, roughness: 0.9, flatShading: true });
const brassMat = new THREE.MeshStandardMaterial({ name: 'brass', color: 0xd2a64b, roughness: 0.35, metalness: 0.75, flatShading: true });
const laceMat = new THREE.MeshStandardMaterial({ name: 'lace', color: 0xe9dcbc, roughness: 0.9, flatShading: true });
const insideMat = new THREE.MeshStandardMaterial({ name: 'inside', color: 0x2a1a10, roughness: 1, flatShading: true });
// Shared geometries
const extrudeGeo = extrude([[0, -0.167], [0.0248, -0.1595], [0.0417, -0.1375], [0.0524, -0.1016], [0.056, -0.045], [0.0467, 0.0097], [0.0372, 0.0444], [0.0221, 0.0658], [0, 0.073], [-0.0221, 0.0658], [-0.0372, 0.0444], [-0.0467, 0.0097], [-0.05, -0.045], [-0.0524, -0.1016], [-0.0417, -0.1375], [-0.0248, -0.1595]], 0.022);
const extrudeGeo2 = extrude([[0, -0.1633], [0.024, -0.1561], [0.0405, -0.1347], [0.0508, -0.0999], [0.0543, -0.045], [0.0453, 0.0081], [0.0361, 0.0417], [0.0214, 0.0624], [0, 0.0695], [-0.0214, 0.0624], [-0.0361, 0.0417], [-0.0453, 0.0081], [-0.0485, -0.045], [-0.0508, -0.0999], [-0.0405, -0.1347], [-0.024, -0.1561]], 0.008);
const sphereGeo = new THREE.SphereGeometry(1, 10, 4, 0, Math.PI * 2, 0, Math.PI / 2);
const sphereGeo2 = new THREE.SphereGeometry(1, 10, 3, Math.PI, Math.PI, 0, 0.9);
const cylinderGeo = new THREE.CylinderGeometry(0.055, 0.05, 0.19, 12, 1, true);
const cylinderGeo2 = new THREE.CylinderGeometry(0.054, 0.056, 0.026, 12, 1, false, 1.7279, 2.8274);
const latheGeo = lathe([[0.053, 0.168], [0.064, 0.168], [0.066, 0.212], [0.064, 0.222], [0.047, 0.222], [0.047, 0.188]], 12);
const cylinderGeo3 = new THREE.CylinderGeometry(0.048, 0.048, 0.004, 12);
const boxGeo = new THREE.BoxGeometry(0.036, 0.142, 0.012);
const octahedronGeo = new THREE.OctahedronGeometry(0.0055, 0);
const boxGeo2 = new THREE.BoxGeometry(0.05, 0.005, 0.005);
const boxGeo3 = new THREE.BoxGeometry(0.016, 0.012, 0.009);
// Parts
const bootL = new THREE.Group();
bootL.name = 'bootL';
bootL.position.set(-0.068, 0, -0.012);
bootL.rotation.set(0, deg(-7), 0);
root.add(bootL);
const bootLSole = new THREE.Mesh(extrudeGeo, soleMat);
bootLSole.name = 'bootLSole';
bootLSole.position.set(0, 0.011, 0);
bootLSole.rotation.set(deg(-90), 0, 0);
bootL.add(bootLSole);
const bootLWelt = new THREE.Mesh(extrudeGeo2, weltMat);
bootLWelt.name = 'bootLWelt';
bootLWelt.position.set(0, 0.026, 0);
bootLWelt.rotation.set(deg(-90), 0, 0);
bootL.add(bootLWelt);
const bootLFootShell = new THREE.Group();
bootLFootShell.name = 'bootLFootShell';
bootLFootShell.position.set(0, 0.028, 0.044);
bootLFootShell.rotation.set(deg(9), 0, 0);
bootL.add(bootLFootShell);
const bootLFoot = new THREE.Mesh(sphereGeo, leatherMat);
bootLFoot.name = 'bootLFoot';
bootLFoot.scale.set(0.048, 0.072, 0.118);
bootLFootShell.add(bootLFoot);
const bootLToeCapShape = new THREE.Group();
bootLToeCapShape.name = 'bootLToeCapShape';
bootLToeCapShape.scale.set(0.0499, 0.0749, 0.1204);
bootLFootShell.add(bootLToeCapShape);
const bootLToeCap = new THREE.Mesh(sphereGeo2, darkMat);
bootLToeCap.name = 'bootLToeCap';
bootLToeCap.rotation.set(deg(90), 0, 0);
bootLToeCapShape.add(bootLToeCap);
const bootLShaft = new THREE.Mesh(cylinderGeo, leatherMat);
bootLShaft.name = 'bootLShaft';
bootLShaft.position.set(0, 0.123, -0.016);
bootLShaft.scale.set(1, 1, 1.08);
bootL.add(bootLShaft);
const bootLHeel = new THREE.Mesh(cylinderGeo2, darkMat);
bootLHeel.name = 'bootLHeel';
bootLHeel.position.set(0, 0.041, -0.016);
bootLHeel.scale.set(1, 1, 1.08);
bootL.add(bootLHeel);
const bootLCuff = new THREE.Mesh(latheGeo, cuffMat);
bootLCuff.name = 'bootLCuff';
bootLCuff.position.set(0, 0, -0.016);
bootLCuff.scale.set(1, 1, 1.08);
bootL.add(bootLCuff);
const bootLOpening = new THREE.Mesh(cylinderGeo3, insideMat);
bootLOpening.name = 'bootLOpening';
bootLOpening.position.set(0, 0.198, -0.016);
bootLOpening.scale.set(1, 1, 1.08);
bootL.add(bootLOpening);
const bootLTongue = new THREE.Mesh(boxGeo, cuffMat);
bootLTongue.name = 'bootLTongue';
bootLTongue.position.set(0, 0.147, 0.0386);
bootLTongue.rotation.set(deg(-3), 0, 0);
bootL.add(bootLTongue);
const bootLEyelet1R = new THREE.Mesh(octahedronGeo, brassMat);
bootLEyelet1R.name = 'bootLEyelet1R';
bootLEyelet1R.position.set(0.023, 0.088, 0.0426);
bootL.add(bootLEyelet1R);
const bootLLace1a = new THREE.Mesh(boxGeo2, laceMat);
bootLLace1a.name = 'bootLLace1a';
bootLLace1a.position.set(0, 0.1045, 0.0476);
bootLLace1a.rotation.set(0, 0, deg(35.658));
bootL.add(bootLLace1a);
const bootLEyelet1L = new THREE.Mesh(octahedronGeo, brassMat);
bootLEyelet1L.name = 'bootLEyelet1L';
bootLEyelet1L.position.set(-0.023, 0.088, 0.0426);
bootL.add(bootLEyelet1L);
const bootLLace1b = new THREE.Mesh(boxGeo2, laceMat);
bootLLace1b.name = 'bootLLace1b';
bootLLace1b.position.set(0, 0.1045, 0.0476);
bootLLace1b.rotation.set(0, 0, deg(-35.658));
bootL.add(bootLLace1b);
const bootLEyelet2R = new THREE.Mesh(octahedronGeo, brassMat);
bootLEyelet2R.name = 'bootLEyelet2R';
bootLEyelet2R.position.set(0.023, 0.121, 0.0426);
bootL.add(bootLEyelet2R);
const bootLLace2a = new THREE.Mesh(boxGeo2, laceMat);
bootLLace2a.name = 'bootLLace2a';
bootLLace2a.position.set(0, 0.1375, 0.0476);
bootLLace2a.rotation.set(0, 0, deg(35.658));
bootL.add(bootLLace2a);
const bootLEyelet2L = new THREE.Mesh(octahedronGeo, brassMat);
bootLEyelet2L.name = 'bootLEyelet2L';
bootLEyelet2L.position.set(-0.023, 0.121, 0.0426);
bootL.add(bootLEyelet2L);
const bootLLace2b = new THREE.Mesh(boxGeo2, laceMat);
bootLLace2b.name = 'bootLLace2b';
bootLLace2b.position.set(0, 0.1375, 0.0476);
bootLLace2b.rotation.set(0, 0, deg(-35.658));
bootL.add(bootLLace2b);
const bootLEyelet3R = new THREE.Mesh(octahedronGeo, brassMat);
bootLEyelet3R.name = 'bootLEyelet3R';
bootLEyelet3R.position.set(0.023, 0.154, 0.0426);
bootL.add(bootLEyelet3R);
const bootLEyelet3L = new THREE.Mesh(octahedronGeo, brassMat);
bootLEyelet3L.name = 'bootLEyelet3L';
bootLEyelet3L.position.set(-0.023, 0.154, 0.0426);
bootL.add(bootLEyelet3L);
const bootLLaceKnot = new THREE.Mesh(boxGeo3, laceMat);
bootLLaceKnot.name = 'bootLLaceKnot';
bootLLaceKnot.position.set(0, 0.158, 0.0486);
bootL.add(bootLLaceKnot);
const bootLLaceEnd = new THREE.Mesh(tube([[0, 0.156, 0.0506], [-0.012, 0.139, 0.0566], [-0.016, 0.119, 0.0526]], 0.0025, 6, 3), laceMat);
bootLLaceEnd.name = 'bootLLaceEnd';
bootL.add(bootLLaceEnd);
const bootR = new THREE.Group();
bootR.name = 'bootR';
bootR.position.set(0.068, 0, 0.012);
bootR.rotation.set(0, deg(9), 0);
root.add(bootR);
const bootRSole = new THREE.Mesh(extrudeGeo, soleMat);
bootRSole.name = 'bootRSole';
bootRSole.position.set(0, 0.011, 0);
bootRSole.rotation.set(deg(-90), 0, 0);
bootR.add(bootRSole);
const bootRWelt = new THREE.Mesh(extrudeGeo2, weltMat);
bootRWelt.name = 'bootRWelt';
bootRWelt.position.set(0, 0.026, 0);
bootRWelt.rotation.set(deg(-90), 0, 0);
bootR.add(bootRWelt);
const bootRFootShell = new THREE.Group();
bootRFootShell.name = 'bootRFootShell';
bootRFootShell.position.set(0, 0.028, 0.044);
bootRFootShell.rotation.set(deg(9), 0, 0);
bootR.add(bootRFootShell);
const bootRFoot = new THREE.Mesh(sphereGeo, leatherMat);
bootRFoot.name = 'bootRFoot';
bootRFoot.scale.set(0.048, 0.072, 0.118);
bootRFootShell.add(bootRFoot);
const bootRToeCapShape = new THREE.Group();
bootRToeCapShape.name = 'bootRToeCapShape';
bootRToeCapShape.scale.set(0.0499, 0.0749, 0.1204);
bootRFootShell.add(bootRToeCapShape);
const bootRToeCap = new THREE.Mesh(sphereGeo2, darkMat);
bootRToeCap.name = 'bootRToeCap';
bootRToeCap.rotation.set(deg(90), 0, 0);
bootRToeCapShape.add(bootRToeCap);
const bootRShaft = new THREE.Mesh(cylinderGeo, leatherMat);
bootRShaft.name = 'bootRShaft';
bootRShaft.position.set(0, 0.123, -0.016);
bootRShaft.scale.set(1, 1, 1.08);
bootR.add(bootRShaft);
const bootRHeel = new THREE.Mesh(cylinderGeo2, darkMat);
bootRHeel.name = 'bootRHeel';
bootRHeel.position.set(0, 0.041, -0.016);
bootRHeel.scale.set(1, 1, 1.08);
bootR.add(bootRHeel);
const bootRCuff = new THREE.Mesh(latheGeo, cuffMat);
bootRCuff.name = 'bootRCuff';
bootRCuff.position.set(0, 0, -0.016);
bootRCuff.scale.set(1, 1, 1.08);
bootR.add(bootRCuff);
const bootROpening = new THREE.Mesh(cylinderGeo3, insideMat);
bootROpening.name = 'bootROpening';
bootROpening.position.set(0, 0.198, -0.016);
bootROpening.scale.set(1, 1, 1.08);
bootR.add(bootROpening);
const bootRTongue = new THREE.Mesh(boxGeo, cuffMat);
bootRTongue.name = 'bootRTongue';
bootRTongue.position.set(0, 0.147, 0.0386);
bootRTongue.rotation.set(deg(-3), 0, 0);
bootR.add(bootRTongue);
const bootREyelet1R = new THREE.Mesh(octahedronGeo, brassMat);
bootREyelet1R.name = 'bootREyelet1R';
bootREyelet1R.position.set(0.023, 0.088, 0.0426);
bootR.add(bootREyelet1R);
const bootRLace1a = new THREE.Mesh(boxGeo2, laceMat);
bootRLace1a.name = 'bootRLace1a';
bootRLace1a.position.set(0, 0.1045, 0.0476);
bootRLace1a.rotation.set(0, 0, deg(35.658));
bootR.add(bootRLace1a);
const bootREyelet1L = new THREE.Mesh(octahedronGeo, brassMat);
bootREyelet1L.name = 'bootREyelet1L';
bootREyelet1L.position.set(-0.023, 0.088, 0.0426);
bootR.add(bootREyelet1L);
const bootRLace1b = new THREE.Mesh(boxGeo2, laceMat);
bootRLace1b.name = 'bootRLace1b';
bootRLace1b.position.set(0, 0.1045, 0.0476);
bootRLace1b.rotation.set(0, 0, deg(-35.658));
bootR.add(bootRLace1b);
const bootREyelet2R = new THREE.Mesh(octahedronGeo, brassMat);
bootREyelet2R.name = 'bootREyelet2R';
bootREyelet2R.position.set(0.023, 0.121, 0.0426);
bootR.add(bootREyelet2R);
const bootRLace2a = new THREE.Mesh(boxGeo2, laceMat);
bootRLace2a.name = 'bootRLace2a';
bootRLace2a.position.set(0, 0.1375, 0.0476);
bootRLace2a.rotation.set(0, 0, deg(35.658));
bootR.add(bootRLace2a);
const bootREyelet2L = new THREE.Mesh(octahedronGeo, brassMat);
bootREyelet2L.name = 'bootREyelet2L';
bootREyelet2L.position.set(-0.023, 0.121, 0.0426);
bootR.add(bootREyelet2L);
const bootRLace2b = new THREE.Mesh(boxGeo2, laceMat);
bootRLace2b.name = 'bootRLace2b';
bootRLace2b.position.set(0, 0.1375, 0.0476);
bootRLace2b.rotation.set(0, 0, deg(-35.658));
bootR.add(bootRLace2b);
const bootREyelet3R = new THREE.Mesh(octahedronGeo, brassMat);
bootREyelet3R.name = 'bootREyelet3R';
bootREyelet3R.position.set(0.023, 0.154, 0.0426);
bootR.add(bootREyelet3R);
const bootREyelet3L = new THREE.Mesh(octahedronGeo, brassMat);
bootREyelet3L.name = 'bootREyelet3L';
bootREyelet3L.position.set(-0.023, 0.154, 0.0426);
bootR.add(bootREyelet3L);
const bootRLaceKnot = new THREE.Mesh(boxGeo3, laceMat);
bootRLaceKnot.name = 'bootRLaceKnot';
bootRLaceKnot.position.set(0, 0.158, 0.0486);
bootR.add(bootRLaceKnot);
const bootRLaceEnd = new THREE.Mesh(tube([[0, 0.156, 0.0506], [0.012, 0.139, 0.0566], [0.016, 0.119, 0.0526]], 0.0025, 6, 3), laceMat);
bootRLaceEnd.name = 'bootRLaceEnd';
bootR.add(bootRLaceEnd);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createBoots;
Valoraciones y comentarios
0 comentarios
Aún no hay comentarios. Cuenta cómo usaste este modelo o qué se podría mejorar.
Modelos relacionados
Misma categoría o etiquetas similares









