Codels
1,3 mil tris2,70 × 4,00 × 3,77 m
Módulo ES autocontido — depende apenas do three. Chame a factory e adicione o grupo à sua cena.
/**
 * Swinging Axe — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,296 · Size (W × H × D): 2.70 × 4.00 × 3.77 m
 *
 * Usage:
 *   import { createSwingingAxe } from './swinging-axe.js';
 *   
 *   const model = createSwingingAxe();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 *   
 *   // Animations: swing
 *   const mixer = new THREE.AnimationMixer(model);
 *   const swing = mixer.clipAction(THREE.AnimationClip.findByName(model.animations, 'swing'));
 *   swing.setLoop(THREE.LoopOnce, 1);
 *   swing.clampWhenFinished = true;
 *   swing.play(); // back: swing.timeScale = -1; swing.paused = false;
 *   // in your render loop: mixer.update(clock.getDelta());
 */
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);
}

// Build animation clips from simple descriptions (Codels). Play them with THREE.AnimationMixer.
function codelsClips(THREE, entries) {
  var TAU = Math.PI * 2;
  var DEG = Math.PI / 180;
  var AX = { x: new THREE.Vector3(1, 0, 0), y: new THREE.Vector3(0, 1, 0), z: new THREE.Vector3(0, 0, 1) };
  var periodOf = function (a) { return a.type === 'spin' ? 360 / Math.abs(a.speed) : a.period; };
  var clips = [];

  // loops → 'idle'
  var loops = [];
  entries.forEach(function (e) {
    var l = e.anim.filter(function (a) { return a.type !== 'hinge'; });
    if (l.length) loops.push({ target: e.target, anim: l });
  });
  if (loops.length) {
    var periods = [];
    loops.forEach(function (e) { e.anim.forEach(function (a) { periods.push(periodOf(a)); }); });
    var longest = Math.max.apply(null, periods);
    var D = longest;
    var bestErr = Infinity;
    for (var m = 1; m <= 6 && bestErr > 0.01; m++) {
      var err = 0;
      periods.forEach(function (p) {
        var n = Math.max(1, Math.round((longest * m) / p));
        err = Math.max(err, Math.abs((longest * m) / n - p) / p);
      });
      if (err < bestErr - 1e-9) { bestErr = err; D = longest * m; }
    }
    var cycles = function (a) { return Math.max(1, Math.round(D / periodOf(a))); };
    var steps = 24;
    loops.forEach(function (e) { e.anim.forEach(function (a) { steps = Math.max(steps, cycles(a) * 24); }); });
    steps = Math.min(steps, 720);
    var tracks = [];
    loops.forEach(function (e) {
      var o = e.target;
      var q0 = o.quaternion.clone(), p0 = o.position.clone(), s0 = o.scale.clone();
      var q = new THREE.Quaternion(), turn = new THREE.Quaternion(), p = new THREE.Vector3(), s = new THREE.Vector3();
      var has = function (type) { return e.anim.some(function (a) { return a.type === type; }); };
      var turns = has('spin') || has('swing'), moves = has('bob'), grows = has('pulse');
      var times = [], qv = [], pv = [], sv = [];
      for (var k = 0; k <= steps; k++) {
        var t = (D * k) / steps;
        q.copy(q0); p.copy(p0); s.copy(s0);
        e.anim.forEach(function (a) {
          var n = cycles(a);
          var w = Math.sin(TAU * ((n * t) / D + (a.phase || 0)));
          if (a.type === 'spin') q.multiply(turn.setFromAxisAngle(AX[a.axis], (a.speed < 0 ? -TAU : TAU) * ((n * t) / D)));
          else if (a.type === 'swing') q.multiply(turn.setFromAxisAngle(AX[a.axis], a.angle * DEG * w));
          else if (a.type === 'bob') p.addScaledVector(AX[a.axis], a.distance * w);
          else if (a.type === 'pulse') s.multiplyScalar(1 + a.amount * w);
        });
        times.push(t);
        if (turns) qv.push(q.x, q.y, q.z, q.w);
        if (moves) pv.push(p.x, p.y, p.z);
        if (grows) sv.push(s.x, s.y, s.z);
      }
      if (turns) tracks.push(new THREE.QuaternionKeyframeTrack(o.uuid + '.quaternion', times, qv));
      if (moves) tracks.push(new THREE.VectorKeyframeTrack(o.uuid + '.position', times, pv));
      if (grows) tracks.push(new THREE.VectorKeyframeTrack(o.uuid + '.scale', times, sv));
    });
    clips.push(new THREE.AnimationClip('idle', D, tracks));
  }

  // hinge moves → one-shot clips ('open' …)
  var shots = {};
  entries.forEach(function (e) {
    e.anim.forEach(function (a) {
      if (a.type !== 'hinge') return;
      var name = a.clip || 'open';
      (shots[name] = shots[name] || []).push({ target: e.target, a: a });
    });
  });
  Object.keys(shots).forEach(function (name) {
    var tracks = [];
    var length = 0;
    shots[name].forEach(function (h) {
      var o = h.target, q0 = o.quaternion.clone(), q = new THREE.Quaternion(), turn = new THREE.Quaternion();
      var n = Math.max(4, Math.ceil(Math.abs(h.a.angle) / 10));
      var times = [], qv = [];
      for (var k = 0; k <= n; k++) {
        var f = k / n;
        var eased = f * f * (3 - 2 * f);
        q.copy(q0).multiply(turn.setFromAxisAngle(AX[h.a.axis], h.a.angle * DEG * eased));
        times.push(h.a.duration * f);
        qv.push(q.x, q.y, q.z, q.w);
      }
      length = Math.max(length, h.a.duration);
      tracks.push(new THREE.QuaternionKeyframeTrack(o.uuid + '.quaternion', times, qv));
    });
    clips.push(new THREE.AnimationClip(name, length, tracks));
  });
  return clips;
}

export function createSwingingAxe() {
  const root = new THREE.Group();
  root.name = 'SwingingAxe';

  // 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 hazardMat = new THREE.MeshStandardMaterial({ name: 'hazard', color: 0xf5c02a, roughness: 0.55, flatShading: true });
  const stripeMat = new THREE.MeshStandardMaterial({ name: 'stripe', color: 0x1d1f25, roughness: 0.7, flatShading: true });
  const accentMat = new THREE.MeshStandardMaterial({ name: 'accent', color: 0xd63a2f, roughness: 0.45, metalness: 0.2, flatShading: true });
  const bladeBodyMat = new THREE.MeshStandardMaterial({ name: 'bladeBody', color: 0x7d8794, roughness: 0.35, metalness: 0.75, flatShading: true });
  const edgeMat = new THREE.MeshStandardMaterial({ name: 'edge', color: 0xeef2f6, roughness: 0.15, metalness: 0.9, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.24, 0.14, 3);
  const extrudeGeo = extrude([[-1.5, 0.07], [-1.5, -0.05], [-1.38, 0.07]], 0.008);
  const extrudeGeo2 = extrude([[-1.4, -0.07], [-1.28, -0.07], [-1.14, 0.07], [-1.26, 0.07]], 0.008);
  const extrudeGeo3 = extrude([[-1.16, -0.07], [-1.04, -0.07], [-0.9, 0.07], [-1.02, 0.07]], 0.008);
  const extrudeGeo4 = extrude([[-0.92, -0.07], [-0.8, -0.07], [-0.66, 0.07], [-0.78, 0.07]], 0.008);
  const extrudeGeo5 = extrude([[-0.68, -0.07], [-0.56, -0.07], [-0.42, 0.07], [-0.54, 0.07]], 0.008);
  const extrudeGeo6 = extrude([[-0.44, -0.07], [-0.32, -0.07], [-0.18, 0.07], [-0.3, 0.07]], 0.008);
  const extrudeGeo7 = extrude([[-0.2, -0.07], [-0.08, -0.07], [0.06, 0.07], [-0.06, 0.07]], 0.008);
  const extrudeGeo8 = extrude([[0.04, -0.07], [0.16, -0.07], [0.3, 0.07], [0.18, 0.07]], 0.008);
  const extrudeGeo9 = extrude([[0.28, -0.07], [0.4, -0.07], [0.54, 0.07], [0.42, 0.07]], 0.008);
  const extrudeGeo10 = extrude([[0.52, -0.07], [0.64, -0.07], [0.78, 0.07], [0.66, 0.07]], 0.008);
  const extrudeGeo11 = extrude([[0.76, -0.07], [0.88, -0.07], [1.02, 0.07], [0.9, 0.07]], 0.008);
  const extrudeGeo12 = extrude([[1, -0.07], [1.12, -0.07], [1.26, 0.07], [1.14, 0.07]], 0.008);
  const extrudeGeo13 = extrude([[1.24, -0.07], [1.36, -0.07], [1.5, 0.07], [1.38, 0.07]], 0.008);
  const extrudeGeo14 = extrude([[1.5, -0.05], [1.48, -0.07], [1.5, -0.07]], 0.008);
  const boxGeo2 = new THREE.BoxGeometry(0.2, 3.86, 0.2);
  const boxGeo3 = new THREE.BoxGeometry(0.14, 2.5096, 0.14);
  const boxGeo4 = new THREE.BoxGeometry(0.26, 0.05, 0.3);
  const boxGeo5 = new THREE.BoxGeometry(2.6, 0.16, 0.012);
  const extrudeGeo15 = extrude([[-1.3, 0.08], [-1.3, -0.05], [-1.17, 0.08]], 0.008);
  const extrudeGeo16 = extrude([[-1.2, -0.08], [-1.07, -0.08], [-0.91, 0.08], [-1.04, 0.08]], 0.008);
  const extrudeGeo17 = extrude([[-0.94, -0.08], [-0.81, -0.08], [-0.65, 0.08], [-0.78, 0.08]], 0.008);
  const extrudeGeo18 = extrude([[-0.68, -0.08], [-0.55, -0.08], [-0.39, 0.08], [-0.52, 0.08]], 0.008);
  const extrudeGeo19 = extrude([[-0.42, -0.08], [-0.29, -0.08], [-0.13, 0.08], [-0.26, 0.08]], 0.008);
  const extrudeGeo20 = extrude([[-0.16, -0.08], [-0.03, -0.08], [0.13, 0.08], [0, 0.08]], 0.008);
  const extrudeGeo21 = extrude([[0.1, -0.08], [0.23, -0.08], [0.39, 0.08], [0.26, 0.08]], 0.008);
  const extrudeGeo22 = extrude([[0.36, -0.08], [0.49, -0.08], [0.65, 0.08], [0.52, 0.08]], 0.008);
  const extrudeGeo23 = extrude([[0.62, -0.08], [0.75, -0.08], [0.91, 0.08], [0.78, 0.08]], 0.008);
  const extrudeGeo24 = extrude([[0.88, -0.08], [1.01, -0.08], [1.17, 0.08], [1.04, 0.08]], 0.008);
  const extrudeGeo25 = extrude([[1.3, 0.08], [1.14, -0.08], [1.27, -0.08], [1.3, -0.05]], 0.008);
  const boxGeo6 = new THREE.BoxGeometry(0.06, 0.34, 0.26);
  const cylinderGeo = new THREE.CylinderGeometry(0.075, 0.075, 0.08, 8);
  const cylinderGeo2 = new THREE.CylinderGeometry(0.035, 0.035, 0.1, 6);

  // Parts
  const skidLeft = new THREE.Mesh(boxGeo, hazardMat);
  skidLeft.name = 'skidLeft';
  skidLeft.position.set(-1.15, 0.07, 0);
  root.add(skidLeft);
  const skidStripesLeft = new THREE.Group();
  skidStripesLeft.name = 'skidStripesLeft';
  skidStripesLeft.position.set(-1.27, 0.07, 0);
  skidStripesLeft.rotation.set(0, deg(-90), 0);
  root.add(skidStripesLeft);
  const extrude3 = new THREE.Mesh(extrudeGeo, stripeMat);
  extrude3.position.set(0, 0, 0.004);
  skidStripesLeft.add(extrude3);
  const extrude4 = new THREE.Mesh(extrudeGeo2, stripeMat);
  extrude4.position.set(0, 0, 0.004);
  skidStripesLeft.add(extrude4);
  const extrude5 = new THREE.Mesh(extrudeGeo3, stripeMat);
  extrude5.position.set(0, 0, 0.004);
  skidStripesLeft.add(extrude5);
  const extrude6 = new THREE.Mesh(extrudeGeo4, stripeMat);
  extrude6.position.set(0, 0, 0.004);
  skidStripesLeft.add(extrude6);
  const extrude7 = new THREE.Mesh(extrudeGeo5, stripeMat);
  extrude7.position.set(0, 0, 0.004);
  skidStripesLeft.add(extrude7);
  const extrude8 = new THREE.Mesh(extrudeGeo6, stripeMat);
  extrude8.position.set(0, 0, 0.004);
  skidStripesLeft.add(extrude8);
  const extrude9 = new THREE.Mesh(extrudeGeo7, stripeMat);
  extrude9.position.set(0, 0, 0.004);
  skidStripesLeft.add(extrude9);
  const extrude10 = new THREE.Mesh(extrudeGeo8, stripeMat);
  extrude10.position.set(0, 0, 0.004);
  skidStripesLeft.add(extrude10);
  const extrude11 = new THREE.Mesh(extrudeGeo9, stripeMat);
  extrude11.position.set(0, 0, 0.004);
  skidStripesLeft.add(extrude11);
  const extrude12 = new THREE.Mesh(extrudeGeo10, stripeMat);
  extrude12.position.set(0, 0, 0.004);
  skidStripesLeft.add(extrude12);
  const extrude13 = new THREE.Mesh(extrudeGeo11, stripeMat);
  extrude13.position.set(0, 0, 0.004);
  skidStripesLeft.add(extrude13);
  const extrude14 = new THREE.Mesh(extrudeGeo12, stripeMat);
  extrude14.position.set(0, 0, 0.004);
  skidStripesLeft.add(extrude14);
  const extrude15 = new THREE.Mesh(extrudeGeo13, stripeMat);
  extrude15.position.set(0, 0, 0.004);
  skidStripesLeft.add(extrude15);
  const extrude16 = new THREE.Mesh(extrudeGeo14, stripeMat);
  extrude16.position.set(0, 0, 0.004);
  skidStripesLeft.add(extrude16);
  const postLeft = new THREE.Mesh(boxGeo2, frameMat);
  postLeft.name = 'postLeft';
  postLeft.position.set(-1.15, 2.07, 0);
  root.add(postLeft);
  const box18 = new THREE.Mesh(boxGeo3, frameMat);
  box18.position.set(-1.15, 1.17, -0.625);
  box18.rotation.set(deg(-148.7508), 0, 0);
  root.add(box18);
  const box19 = new THREE.Mesh(boxGeo4, darkMat);
  box19.position.set(-1.15, 0.165, -1.25);
  root.add(box19);
  const box20 = new THREE.Mesh(boxGeo3, frameMat);
  box20.position.set(-1.15, 1.17, 0.625);
  box20.rotation.set(deg(-31.2492), 0, deg(-180));
  root.add(box20);
  const box21 = new THREE.Mesh(boxGeo4, darkMat);
  box21.position.set(-1.15, 0.165, 1.25);
  root.add(box21);
  const skidRight = new THREE.Mesh(boxGeo, hazardMat);
  skidRight.name = 'skidRight';
  skidRight.position.set(1.15, 0.07, 0);
  root.add(skidRight);
  const skidStripesRight = new THREE.Group();
  skidStripesRight.name = 'skidStripesRight';
  skidStripesRight.position.set(1.27, 0.07, 0);
  skidStripesRight.rotation.set(0, deg(90), 0);
  root.add(skidStripesRight);
  const extrude24 = new THREE.Mesh(extrudeGeo, stripeMat);
  extrude24.position.set(0, 0, 0.004);
  skidStripesRight.add(extrude24);
  const extrude25 = new THREE.Mesh(extrudeGeo2, stripeMat);
  extrude25.position.set(0, 0, 0.004);
  skidStripesRight.add(extrude25);
  const extrude26 = new THREE.Mesh(extrudeGeo3, stripeMat);
  extrude26.position.set(0, 0, 0.004);
  skidStripesRight.add(extrude26);
  const extrude27 = new THREE.Mesh(extrudeGeo4, stripeMat);
  extrude27.position.set(0, 0, 0.004);
  skidStripesRight.add(extrude27);
  const extrude28 = new THREE.Mesh(extrudeGeo5, stripeMat);
  extrude28.position.set(0, 0, 0.004);
  skidStripesRight.add(extrude28);
  const extrude29 = new THREE.Mesh(extrudeGeo6, stripeMat);
  extrude29.position.set(0, 0, 0.004);
  skidStripesRight.add(extrude29);
  const extrude30 = new THREE.Mesh(extrudeGeo7, stripeMat);
  extrude30.position.set(0, 0, 0.004);
  skidStripesRight.add(extrude30);
  const extrude31 = new THREE.Mesh(extrudeGeo8, stripeMat);
  extrude31.position.set(0, 0, 0.004);
  skidStripesRight.add(extrude31);
  const extrude32 = new THREE.Mesh(extrudeGeo9, stripeMat);
  extrude32.position.set(0, 0, 0.004);
  skidStripesRight.add(extrude32);
  const extrude33 = new THREE.Mesh(extrudeGeo10, stripeMat);
  extrude33.position.set(0, 0, 0.004);
  skidStripesRight.add(extrude33);
  const extrude34 = new THREE.Mesh(extrudeGeo11, stripeMat);
  extrude34.position.set(0, 0, 0.004);
  skidStripesRight.add(extrude34);
  const extrude35 = new THREE.Mesh(extrudeGeo12, stripeMat);
  extrude35.position.set(0, 0, 0.004);
  skidStripesRight.add(extrude35);
  const extrude36 = new THREE.Mesh(extrudeGeo13, stripeMat);
  extrude36.position.set(0, 0, 0.004);
  skidStripesRight.add(extrude36);
  const extrude37 = new THREE.Mesh(extrudeGeo14, stripeMat);
  extrude37.position.set(0, 0, 0.004);
  skidStripesRight.add(extrude37);
  const postRight = new THREE.Mesh(boxGeo2, frameMat);
  postRight.name = 'postRight';
  postRight.position.set(1.15, 2.07, 0);
  root.add(postRight);
  const box39 = new THREE.Mesh(boxGeo3, frameMat);
  box39.position.set(1.15, 1.17, -0.625);
  box39.rotation.set(deg(-148.7508), 0, 0);
  root.add(box39);
  const box40 = new THREE.Mesh(boxGeo4, darkMat);
  box40.position.set(1.15, 0.165, -1.25);
  root.add(box40);
  const box41 = new THREE.Mesh(boxGeo3, frameMat);
  box41.position.set(1.15, 1.17, 0.625);
  box41.rotation.set(deg(-31.2492), 0, deg(-180));
  root.add(box41);
  const box42 = new THREE.Mesh(boxGeo4, darkMat);
  box42.position.set(1.15, 0.165, 1.25);
  root.add(box42);
  const topBeam = new THREE.Mesh(new THREE.BoxGeometry(2.7, 0.3, 0.3), frameMat);
  topBeam.name = 'topBeam';
  topBeam.position.set(0, 3.85, 0);
  root.add(topBeam);
  const box44 = new THREE.Mesh(boxGeo5, hazardMat);
  box44.position.set(0, 3.85, -0.152);
  root.add(box44);
  const beamStripesBack = new THREE.Group();
  beamStripesBack.name = 'beamStripesBack';
  beamStripesBack.position.set(0, 3.85, -0.158);
  beamStripesBack.rotation.set(0, deg(180), 0);
  root.add(beamStripesBack);
  const extrude46 = new THREE.Mesh(extrudeGeo15, stripeMat);
  extrude46.position.set(0, 0, 0.004);
  beamStripesBack.add(extrude46);
  const extrude47 = new THREE.Mesh(extrudeGeo16, stripeMat);
  extrude47.position.set(0, 0, 0.004);
  beamStripesBack.add(extrude47);
  const extrude48 = new THREE.Mesh(extrudeGeo17, stripeMat);
  extrude48.position.set(0, 0, 0.004);
  beamStripesBack.add(extrude48);
  const extrude49 = new THREE.Mesh(extrudeGeo18, stripeMat);
  extrude49.position.set(0, 0, 0.004);
  beamStripesBack.add(extrude49);
  const extrude50 = new THREE.Mesh(extrudeGeo19, stripeMat);
  extrude50.position.set(0, 0, 0.004);
  beamStripesBack.add(extrude50);
  const extrude51 = new THREE.Mesh(extrudeGeo20, stripeMat);
  extrude51.position.set(0, 0, 0.004);
  beamStripesBack.add(extrude51);
  const extrude52 = new THREE.Mesh(extrudeGeo21, stripeMat);
  extrude52.position.set(0, 0, 0.004);
  beamStripesBack.add(extrude52);
  const extrude53 = new THREE.Mesh(extrudeGeo22, stripeMat);
  extrude53.position.set(0, 0, 0.004);
  beamStripesBack.add(extrude53);
  const extrude54 = new THREE.Mesh(extrudeGeo23, stripeMat);
  extrude54.position.set(0, 0, 0.004);
  beamStripesBack.add(extrude54);
  const extrude55 = new THREE.Mesh(extrudeGeo24, stripeMat);
  extrude55.position.set(0, 0, 0.004);
  beamStripesBack.add(extrude55);
  const extrude56 = new THREE.Mesh(extrudeGeo25, stripeMat);
  extrude56.position.set(0, 0, 0.004);
  beamStripesBack.add(extrude56);
  const box57 = new THREE.Mesh(boxGeo5, hazardMat);
  box57.position.set(0, 3.85, 0.152);
  root.add(box57);
  const beamStripesFront = new THREE.Group();
  beamStripesFront.name = 'beamStripesFront';
  beamStripesFront.position.set(0, 3.85, 0.158);
  root.add(beamStripesFront);
  const extrude59 = new THREE.Mesh(extrudeGeo15, stripeMat);
  extrude59.position.set(0, 0, 0.004);
  beamStripesFront.add(extrude59);
  const extrude60 = new THREE.Mesh(extrudeGeo16, stripeMat);
  extrude60.position.set(0, 0, 0.004);
  beamStripesFront.add(extrude60);
  const extrude61 = new THREE.Mesh(extrudeGeo17, stripeMat);
  extrude61.position.set(0, 0, 0.004);
  beamStripesFront.add(extrude61);
  const extrude62 = new THREE.Mesh(extrudeGeo18, stripeMat);
  extrude62.position.set(0, 0, 0.004);
  beamStripesFront.add(extrude62);
  const extrude63 = new THREE.Mesh(extrudeGeo19, stripeMat);
  extrude63.position.set(0, 0, 0.004);
  beamStripesFront.add(extrude63);
  const extrude64 = new THREE.Mesh(extrudeGeo20, stripeMat);
  extrude64.position.set(0, 0, 0.004);
  beamStripesFront.add(extrude64);
  const extrude65 = new THREE.Mesh(extrudeGeo21, stripeMat);
  extrude65.position.set(0, 0, 0.004);
  beamStripesFront.add(extrude65);
  const extrude66 = new THREE.Mesh(extrudeGeo22, stripeMat);
  extrude66.position.set(0, 0, 0.004);
  beamStripesFront.add(extrude66);
  const extrude67 = new THREE.Mesh(extrudeGeo23, stripeMat);
  extrude67.position.set(0, 0, 0.004);
  beamStripesFront.add(extrude67);
  const extrude68 = new THREE.Mesh(extrudeGeo24, stripeMat);
  extrude68.position.set(0, 0, 0.004);
  beamStripesFront.add(extrude68);
  const extrude69 = new THREE.Mesh(extrudeGeo25, stripeMat);
  extrude69.position.set(0, 0, 0.004);
  beamStripesFront.add(extrude69);
  const bearingLeft = new THREE.Mesh(boxGeo6, darkMat);
  bearingLeft.name = 'bearingLeft';
  bearingLeft.position.set(-0.19, 3.62, 0);
  root.add(bearingLeft);
  const bearingRight = new THREE.Mesh(boxGeo6, darkMat);
  bearingRight.name = 'bearingRight';
  bearingRight.position.set(0.19, 3.62, 0);
  root.add(bearingRight);
  const axle = new THREE.Mesh(new THREE.CylinderGeometry(0.045, 0.045, 0.5, 8), frameMat);
  axle.name = 'axle';
  axle.position.set(0, 3.55, 0);
  axle.rotation.set(0, 0, deg(90));
  root.add(axle);
  const pendulum = new THREE.Group();
  pendulum.name = 'pendulum';
  pendulum.position.set(0, 3.55, 0);
  pendulum.rotation.set(deg(-30), 0, 0);
  root.add(pendulum);
  const hub = new THREE.Mesh(new THREE.CylinderGeometry(0.13, 0.13, 0.28, 10), accentMat);
  hub.name = 'hub';
  hub.rotation.set(0, 0, deg(90));
  pendulum.add(hub);
  const shaft = new THREE.Mesh(new THREE.CylinderGeometry(0.06, 0.06, 2.15, 8), frameMat);
  shaft.name = 'shaft';
  shaft.position.set(0, -1.075, 0);
  pendulum.add(shaft);
  const cylinder76 = new THREE.Mesh(cylinderGeo, accentMat);
  cylinder76.position.set(0, -0.4625, 0);
  pendulum.add(cylinder76);
  const cylinder77 = new THREE.Mesh(cylinderGeo, accentMat);
  cylinder77.position.set(0, -0.925, 0);
  pendulum.add(cylinder77);
  const cylinder78 = new THREE.Mesh(cylinderGeo, accentMat);
  cylinder78.position.set(0, -1.3875, 0);
  pendulum.add(cylinder78);
  const blade = new THREE.Group();
  blade.name = 'blade';
  blade.position.set(0, -1.85, 0);
  blade.rotation.set(0, deg(90), 0);
  blade.scale.setScalar(1.5);
  pendulum.add(blade);
  const bladeBody = new THREE.Mesh(extrude([[-0.7142, -0.2599], [-0.6582, -0.38], [-0.5822, -0.4885], [-0.4885, -0.5822], [-0.38, -0.6582], [-0.2599, -0.7142], [-0.132, -0.7485], [0, -0.76], [0.132, -0.7485], [0.2599, -0.7142], [0.38, -0.6582], [0.4885, -0.5822], [0.5822, -0.4885], [0.6582, -0.38], [0.7142, -0.2599], [0.5355, -0.3037], [0.357, -0.335], [0.1785, -0.3537], [0, -0.36], [-0.1785, -0.3537], [-0.357, -0.335], [-0.5355, -0.3037]], 0.08), bladeBodyMat);
  bladeBody.name = 'bladeBody';
  blade.add(bladeBody);
  const cuttingEdge = new THREE.Mesh(extrude([[-0.8607, -0.2631], [-0.8157, -0.3804], [-0.7548, -0.4902], [-0.6792, -0.5905], [-0.5905, -0.6792], [-0.4902, -0.7548], [-0.3804, -0.8157], [-0.2631, -0.8607], [-0.1408, -0.8889], [-0.0157, -0.8999], [0.1097, -0.8933], [0.2329, -0.8693], [0.3517, -0.8285], [0.4635, -0.7715], [0.5664, -0.6994], [0.6582, -0.6138], [0.7372, -0.5162], [0.8019, -0.4086], [0.851, -0.293], [0.6885, -0.2105], [0.6525, -0.3043], [0.6038, -0.3921], [0.5434, -0.4724], [0.4724, -0.5434], [0.3921, -0.6038], [0.3043, -0.6525], [0.2105, -0.6885], [0.1126, -0.7111], [0.0126, -0.7199], [-0.0877, -0.7146], [-0.1863, -0.6955], [-0.2813, -0.6628], [-0.3708, -0.6172], [-0.4531, -0.5595], [-0.5266, -0.491], [-0.5898, -0.413], [-0.6415, -0.3269], [-0.6808, -0.2344]], 0.035), edgeMat);
  cuttingEdge.name = 'cuttingEdge';
  blade.add(cuttingEdge);
  const collar = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.34, 0.14), accentMat);
  collar.name = 'collar';
  collar.position.set(0, -0.3, 0);
  blade.add(collar);
  const cylinder83 = new THREE.Mesh(cylinderGeo2, darkMat);
  cylinder83.position.set(-0.45, -0.48, 0);
  cylinder83.rotation.set(deg(90), 0, 0);
  blade.add(cylinder83);
  const cylinder84 = new THREE.Mesh(cylinderGeo2, darkMat);
  cylinder84.position.set(0, -0.5, 0);
  cylinder84.rotation.set(deg(90), 0, 0);
  blade.add(cylinder84);
  const cylinder85 = new THREE.Mesh(cylinderGeo2, darkMat);
  cylinder85.position.set(0.45, -0.48, 0);
  cylinder85.rotation.set(deg(90), 0, 0);
  blade.add(cylinder85);

  // Animations ('swing') — play them with THREE.AnimationMixer
  root.animations = codelsClips(THREE, [
    { target: pendulum, anim: [{ type: 'hinge', axis: 'x', angle: 60, duration: 1.2, clip: 'swing' }] },
  ]);

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

export default createSwingingAxe;

Avaliações e comentários

—
Nenhuma avaliação ainda — seja o primeiro.
5
0
4
0
3
0
2
0
1
0

Entre para avaliar e comentar.

0 comentário

Nenhum comentário ainda. Conte como você usou este modelo ou o que poderia melhorar.

Modelos relacionados

Mesma categoria ou tags parecidas