Codels
1,1 тыс. треуг.0,75 × 1,48 × 0,89 m

Использовать в коде

Ремикс в редакторе
Самодостаточный ES-модуль — зависит только от three. Вызовите фабрику и добавьте группу в сцену.
/**
 * Wheel Crank — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,064 · Size (W × H × D): 0.75 × 1.48 × 0.89 m
 *
 * Usage:
 *   import { createCrank } from './crank.js';
 *   
 *   const model = createCrank();
 *   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 createCrank() {
  const root = new THREE.Group();
  root.name = 'Crank';

  // Materials
  const frameMat = new THREE.MeshStandardMaterial({ name: 'frame', color: 0x3a4252, roughness: 0.6, metalness: 0.35, flatShading: true });
  const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x232831, roughness: 0.7, metalness: 0.3, flatShading: true });
  const steelMat = new THREE.MeshStandardMaterial({ name: 'steel', color: 0xc3cad4, roughness: 0.3, metalness: 0.75, flatShading: true });
  const hazardMat = new THREE.MeshStandardMaterial({ name: 'hazard', color: 0xf5c02a, roughness: 0.55, flatShading: true });
  const wheelMat = new THREE.MeshStandardMaterial({ name: 'wheel', color: 0xe8392f, roughness: 0.4, metalness: 0.2, flatShading: true });
  const gripMat = new THREE.MeshStandardMaterial({ name: 'grip', color: 0x2a2d33, roughness: 0.8, flatShading: true });
  const lampMat = new THREE.MeshStandardMaterial({ name: 'lamp', color: 0xc9ffd9, roughness: 0.3, emissive: 0x3dff7a, emissiveIntensity: 1.1, flatShading: true });

  // Shared geometries
  const cylinderGeo = new THREE.CylinderGeometry(0.028, 0.028, 0.03, 6);
  const boxGeo = new THREE.BoxGeometry(0.04, 0.28, 0.03);

  // Parts
  const base = new THREE.Mesh(new THREE.BoxGeometry(0.64, 0.08, 0.64), darkMat);
  base.name = 'base';
  base.position.set(0, 0.04, 0);
  root.add(base);
  const baseTrim = new THREE.Mesh(new THREE.BoxGeometry(0.56, 0.05, 0.56), hazardMat);
  baseTrim.name = 'baseTrim';
  baseTrim.position.set(0, 0.105, 0);
  root.add(baseTrim);
  const cylinder3 = new THREE.Mesh(cylinderGeo, steelMat);
  cylinder3.position.set(-0.23, 0.145, -0.23);
  root.add(cylinder3);
  const cylinder4 = new THREE.Mesh(cylinderGeo, steelMat);
  cylinder4.position.set(0.23, 0.145, -0.23);
  root.add(cylinder4);
  const cylinder5 = new THREE.Mesh(cylinderGeo, steelMat);
  cylinder5.position.set(0.23, 0.145, 0.23);
  root.add(cylinder5);
  const cylinder6 = new THREE.Mesh(cylinderGeo, steelMat);
  cylinder6.position.set(-0.23, 0.145, 0.23);
  root.add(cylinder6);
  const post = new THREE.Mesh(new THREE.BoxGeometry(0.22, 0.82, 0.22), frameMat);
  post.name = 'post';
  post.position.set(0, 0.54, 0);
  root.add(post);
  const postCollar = new THREE.Mesh(new THREE.BoxGeometry(0.26, 0.06, 0.26), darkMat);
  postCollar.name = 'postCollar';
  postCollar.position.set(0, 0.16, 0);
  root.add(postCollar);
  const housing = new THREE.Mesh(new THREE.BoxGeometry(0.42, 0.36, 0.32), frameMat);
  housing.name = 'housing';
  housing.position.set(0, 1.1, 0);
  root.add(housing);
  const housingBand = new THREE.Mesh(new THREE.BoxGeometry(0.44, 0.06, 0.34), hazardMat);
  housingBand.name = 'housingBand';
  housingBand.position.set(0, 0.98, 0);
  root.add(housingBand);
  const housingLid = new THREE.Mesh(new THREE.BoxGeometry(0.36, 0.04, 0.26), darkMat);
  housingLid.name = 'housingLid';
  housingLid.position.set(0, 1.3, 0);
  root.add(housingLid);
  const lampBase = new THREE.Mesh(new THREE.CylinderGeometry(0.05, 0.06, 0.04, 8), darkMat);
  lampBase.name = 'lampBase';
  lampBase.position.set(0.1, 1.34, 0);
  root.add(lampBase);
  const lamp = new THREE.Mesh(new THREE.SphereGeometry(0.045, 8, 6), lampMat);
  lamp.name = 'lamp';
  lamp.position.set(0.1, 1.38, 0);
  root.add(lamp);
  const cog = new THREE.Mesh(extrude([[0.13, 0], [0.1692, 0.016], [0.1617, 0.0525], [0.1193, 0.0516], [0.1052, 0.0764], [0.1275, 0.1124], [0.0999, 0.1375], [0.0662, 0.1119], [0.0402, 0.1236], [0.0371, 0.1659], [0, 0.17], [-0.0122, 0.1294], [-0.0402, 0.1236], [-0.0675, 0.156], [-0.0999, 0.1375], [-0.086, 0.0975], [-0.1052, 0.0764], [-0.1463, 0.0865], [-0.1617, 0.0525], [-0.1269, 0.0284], [-0.13, 0], [-0.1692, -0.016], [-0.1617, -0.0525], [-0.1193, -0.0516], [-0.1052, -0.0764], [-0.1275, -0.1124], [-0.0999, -0.1375], [-0.0662, -0.1119], [-0.0402, -0.1236], [-0.0371, -0.1659], [0, -0.17], [0.0122, -0.1294], [0.0402, -0.1236], [0.0675, -0.156], [0.0999, -0.1375], [0.086, -0.0975], [0.1052, -0.0764], [0.1463, -0.0865], [0.1617, -0.0525], [0.1269, -0.0284]], 0.04), steelMat);
  cog.name = 'cog';
  cog.position.set(0.23, 1.12, 0);
  cog.rotation.set(0, deg(90), 0);
  root.add(cog);
  const cylinder15 = new THREE.Mesh(new THREE.CylinderGeometry(0.05, 0.05, 0.06, 8), darkMat);
  cylinder15.position.set(0.25, 1.12, 0);
  cylinder15.rotation.set(0, 0, deg(90));
  root.add(cylinder15);
  const bearing = new THREE.Mesh(new THREE.CylinderGeometry(0.08, 0.09, 0.06, 10), darkMat);
  bearing.name = 'bearing';
  bearing.position.set(0, 1.1, 0.19);
  bearing.rotation.set(deg(90), 0, 0);
  root.add(bearing);
  const axle = new THREE.Mesh(new THREE.CylinderGeometry(0.04, 0.04, 0.16, 8), steelMat);
  axle.name = 'axle';
  axle.position.set(0, 1.1, 0.26);
  axle.rotation.set(deg(90), 0, 0);
  root.add(axle);
  const wheel = new THREE.Group();
  wheel.name = 'wheel';
  wheel.position.set(0, 1.1, 0.33);
  wheel.rotation.set(0, 0, deg(-30));
  root.add(wheel);
  const rim = new THREE.Mesh(new THREE.TorusGeometry(0.34, 0.035, 6, 24), wheelMat);
  rim.name = 'rim';
  wheel.add(rim);
  const hub = new THREE.Mesh(new THREE.CylinderGeometry(0.075, 0.075, 0.09, 10), wheelMat);
  hub.name = 'hub';
  hub.rotation.set(deg(90), 0, 0);
  wheel.add(hub);
  const hubCap = new THREE.Mesh(new THREE.CylinderGeometry(0.045, 0.045, 0.1, 8), steelMat);
  hubCap.name = 'hubCap';
  hubCap.position.set(0, 0, 0.02);
  hubCap.rotation.set(deg(90), 0, 0);
  wheel.add(hubCap);
  const spoke1 = new THREE.Group();
  spoke1.name = 'spoke1';
  wheel.add(spoke1);
  const box23 = new THREE.Mesh(boxGeo, wheelMat);
  box23.position.set(0, 0.2, 0);
  spoke1.add(box23);
  const spoke2 = new THREE.Group();
  spoke2.name = 'spoke2';
  spoke2.rotation.set(0, 0, deg(90));
  wheel.add(spoke2);
  const box25 = new THREE.Mesh(boxGeo, wheelMat);
  box25.position.set(0, 0.2, 0);
  spoke2.add(box25);
  const spoke3 = new THREE.Group();
  spoke3.name = 'spoke3';
  spoke3.rotation.set(0, 0, deg(180));
  wheel.add(spoke3);
  const box27 = new THREE.Mesh(boxGeo, wheelMat);
  box27.position.set(0, 0.2, 0);
  spoke3.add(box27);
  const spoke4 = new THREE.Group();
  spoke4.name = 'spoke4';
  spoke4.rotation.set(0, 0, deg(270));
  wheel.add(spoke4);
  const box29 = new THREE.Mesh(boxGeo, wheelMat);
  box29.position.set(0, 0.2, 0);
  spoke4.add(box29);
  const cylinder30 = new THREE.Mesh(new THREE.CylinderGeometry(0.02, 0.02, 0.1, 6), steelMat);
  cylinder30.position.set(-0.2404, 0.2404, 0.06);
  cylinder30.rotation.set(deg(90), 0, 0);
  wheel.add(cylinder30);
  const knob = new THREE.Mesh(new THREE.CapsuleGeometry(0.032, 0.09, 2, 8), gripMat);
  knob.name = 'knob';
  knob.position.set(-0.2404, 0.2404, 0.16);
  knob.rotation.set(deg(90), 0, 0);
  wheel.add(knob);

  root.traverse((o) => {
    if (o.isMesh) {
      o.castShadow = true;
      o.receiveShadow = true;
    }
  });
  return root;
}

export default createCrank;

Оценки и комментарии

—
Оценок пока нет — будьте первым.
5
0
4
0
3
0
2
0
1
0

Войдите, чтобы ставить оценки и оставлять комментарии.

0 комментариев

Комментариев пока нет. Расскажите, как вы использовали эту модель или что можно улучшить.

Похожие модели

Та же категория или похожие теги