Codels
1,3 mil tris0,27 × 0,22 × 0,28 m

Úsalo en código

Hacer remix en el editor
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

—
Aún no hay valoraciones — sé el primero.
5
0
4
0
3
0
2
0
1
0

Inicia sesión para valorar y comentar.

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