Codels
1,4 B üçgen0,83 × 0,79 × 0,60 m
Bağımsız bir ES modülü — yalnızca three paketine bağımlıdır. Fabrika fonksiyonunu çağırıp dönen grubu sahnene ekle.
/**
 * Treasure Chest — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,350 · Size (W × H × D): 0.83 × 0.79 × 0.60 m
 *
 * Usage:
 *   import { createTreasureChest } from './treasure-chest.js';
 *   
 *   const model = createTreasureChest();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 *   
 *   // Animations: open
 *   const mixer = new THREE.AnimationMixer(model);
 *   const open = mixer.clipAction(THREE.AnimationClip.findByName(model.animations, 'open'));
 *   open.setLoop(THREE.LoopOnce, 1);
 *   open.clampWhenFinished = true;
 *   open.play(); // back: open.timeScale = -1; open.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 createTreasureChest() {
  const root = new THREE.Group();
  root.name = 'TreasureChest';

  // Materials
  const woodMat = new THREE.MeshStandardMaterial({ name: 'wood', color: 0x7d4a25, roughness: 0.88, flatShading: true });
  const woodDarkMat = new THREE.MeshStandardMaterial({ name: 'woodDark', color: 0x4e2e17, roughness: 0.92, flatShading: true });
  const trimMat = new THREE.MeshStandardMaterial({ name: 'trim', color: 0xd6a23a, roughness: 0.38, metalness: 0.45, flatShading: true });
  const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x1d1714, roughness: 0.9, flatShading: true });
  const liningMat = new THREE.MeshStandardMaterial({ name: 'lining', color: 0x9b2335, roughness: 1, flatShading: true });
  const goldMat = new THREE.MeshStandardMaterial({ name: 'gold', color: 0xe0a52c, roughness: 0.4, metalness: 0.5, emissive: 0x3d2400, emissiveIntensity: 0.3, flatShading: true });
  const coinMat = new THREE.MeshStandardMaterial({ name: 'coin', color: 0xffd65a, roughness: 0.25, metalness: 0.3, emissive: 0x6b4a00, emissiveIntensity: 0.35, flatShading: true });
  const rubyMat = new THREE.MeshStandardMaterial({ name: 'ruby', color: 0xe0304a, roughness: 0.2, emissive: 0x7a0d1c, emissiveIntensity: 0.5, flatShading: true });
  const emeraldMat = new THREE.MeshStandardMaterial({ name: 'emerald', color: 0x2fd08a, roughness: 0.2, emissive: 0x0a5c37, emissiveIntensity: 0.5, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.8, 0.36, 0.04);
  const boxGeo2 = new THREE.BoxGeometry(0.04, 0.36, 0.42);
  const boxGeo3 = new THREE.BoxGeometry(0.82, 0.045, 0.046);
  const boxGeo4 = new THREE.BoxGeometry(0.046, 0.045, 0.42);
  const boxGeo5 = new THREE.BoxGeometry(0.05, 0.356, 0.022);
  const boxGeo6 = new THREE.BoxGeometry(0.048, 0.356, 0.048);
  const boxGeo7 = new THREE.BoxGeometry(0.08, 0.05, 0.02);
  const cylinderGeo = new THREE.CylinderGeometry(0.034, 0.034, 0.009, 6);
  const extrudeGeo = extrude([[0.264, -0.004], [0.264, 0], [0.2511, 0.0816], [0.2136, 0.1552], [0.1552, 0.2136], [0.0816, 0.2511], [0, 0.264], [-0.0816, 0.2511], [-0.1552, 0.2136], [-0.2136, 0.1552], [-0.2511, 0.0816], [-0.264, 0], [-0.264, -0.004], [-0.246, -0.004], [-0.246, 0], [-0.234, 0.076], [-0.199, 0.1446], [-0.1446, 0.199], [-0.076, 0.234], [0, 0.246], [0.076, 0.234], [0.1446, 0.199], [0.199, 0.1446], [0.234, 0.076], [0.246, 0], [0.246, -0.004]], 0.05);
  const extrudeGeo2 = extrude([[0.26, -0.004], [0.26, 0], [0.2473, 0.0803], [0.2103, 0.1528], [0.1528, 0.2103], [0.0803, 0.2473], [0, 0.26], [-0.0803, 0.2473], [-0.1528, 0.2103], [-0.2103, 0.1528], [-0.2473, 0.0803], [-0.26, 0], [-0.26, -0.004], [-0.215, -0.004], [-0.215, 0], [-0.2045, 0.0664], [-0.1739, 0.1264], [-0.1264, 0.1739], [-0.0664, 0.2045], [0, 0.215], [0.0664, 0.2045], [0.1264, 0.1739], [0.1739, 0.1264], [0.2045, 0.0664], [0.215, 0], [0.215, -0.004]], 0.022);

  // Parts
  const floor = new THREE.Mesh(new THREE.BoxGeometry(0.8, 0.056, 0.5), woodMat);
  floor.name = 'floor';
  floor.position.set(0, 0.028, 0);
  root.add(floor);
  const wallFront = new THREE.Mesh(boxGeo, woodMat);
  wallFront.name = 'wallFront';
  wallFront.position.set(0, 0.18, 0.23);
  root.add(wallFront);
  const wallBack = new THREE.Mesh(boxGeo, woodMat);
  wallBack.name = 'wallBack';
  wallBack.position.set(0, 0.18, -0.23);
  root.add(wallBack);
  const wallSide = new THREE.Mesh(boxGeo2, woodMat);
  wallSide.name = 'wallSide';
  wallSide.position.set(-0.38, 0.18, 0);
  root.add(wallSide);
  const wallSide2 = new THREE.Mesh(boxGeo2, woodMat);
  wallSide2.name = 'wallSide';
  wallSide2.position.set(0.38, 0.18, 0);
  root.add(wallSide2);
  const plinth = new THREE.Mesh(new THREE.BoxGeometry(0.82, 0.05, 0.52), woodDarkMat);
  plinth.name = 'plinth';
  plinth.position.set(0, 0.025, 0);
  root.add(plinth);
  const rim = new THREE.Mesh(boxGeo3, woodDarkMat);
  rim.name = 'rim';
  rim.position.set(0, 0.3355, -0.237);
  root.add(rim);
  const rim2 = new THREE.Mesh(boxGeo4, woodDarkMat);
  rim2.name = 'rim';
  rim2.position.set(-0.387, 0.3355, 0);
  root.add(rim2);
  const rim3 = new THREE.Mesh(boxGeo3, woodDarkMat);
  rim3.name = 'rim';
  rim3.position.set(0, 0.3355, 0.237);
  root.add(rim3);
  const rim4 = new THREE.Mesh(boxGeo4, woodDarkMat);
  rim4.name = 'rim';
  rim4.position.set(0.387, 0.3355, 0);
  root.add(rim4);
  const band = new THREE.Mesh(boxGeo5, trimMat);
  band.name = 'band';
  band.position.set(-0.27, 0.178, -0.254);
  root.add(band);
  const band2 = new THREE.Mesh(boxGeo5, trimMat);
  band2.name = 'band';
  band2.position.set(-0.27, 0.178, 0.254);
  root.add(band2);
  const band3 = new THREE.Mesh(boxGeo5, trimMat);
  band3.name = 'band';
  band3.position.set(0.27, 0.178, -0.254);
  root.add(band3);
  const band4 = new THREE.Mesh(boxGeo5, trimMat);
  band4.name = 'band';
  band4.position.set(0.27, 0.178, 0.254);
  root.add(band4);
  const corner = new THREE.Mesh(boxGeo6, trimMat);
  corner.name = 'corner';
  corner.position.set(-0.389, 0.178, -0.239);
  root.add(corner);
  const corner2 = new THREE.Mesh(boxGeo6, trimMat);
  corner2.name = 'corner';
  corner2.position.set(0.389, 0.178, -0.239);
  root.add(corner2);
  const corner3 = new THREE.Mesh(boxGeo6, trimMat);
  corner3.name = 'corner';
  corner3.position.set(0.389, 0.178, 0.239);
  root.add(corner3);
  const corner4 = new THREE.Mesh(boxGeo6, trimMat);
  corner4.name = 'corner';
  corner4.position.set(-0.389, 0.178, 0.239);
  root.add(corner4);
  const lockPlate = new THREE.Mesh(new THREE.BoxGeometry(0.13, 0.13, 0.016), trimMat);
  lockPlate.name = 'lockPlate';
  lockPlate.position.set(0, 0.25, 0.262);
  root.add(lockPlate);
  const keyhole = new THREE.Mesh(new THREE.BoxGeometry(0.016, 0.036, 0.006), darkMat);
  keyhole.name = 'keyhole';
  keyhole.position.set(0, 0.23, 0.272);
  root.add(keyhole);
  const keyholeTop = new THREE.Mesh(new THREE.CylinderGeometry(0.012, 0.012, 0.006, 8), darkMat);
  keyholeTop.name = 'keyholeTop';
  keyholeTop.position.set(0, 0.255, 0.272);
  keyholeTop.rotation.set(deg(90), 0, 0);
  root.add(keyholeTop);
  const hinge = new THREE.Mesh(boxGeo7, trimMat);
  hinge.name = 'hinge';
  hinge.position.set(-0.2, 0.348, -0.262);
  root.add(hinge);
  const hinge2 = new THREE.Mesh(boxGeo7, trimMat);
  hinge2.name = 'hinge';
  hinge2.position.set(0.2, 0.348, -0.262);
  root.add(hinge2);
  const goldFill = new THREE.Mesh(new THREE.BoxGeometry(0.716, 0.234, 0.416), goldMat);
  goldFill.name = 'goldFill';
  goldFill.position.set(0, 0.173, 0);
  root.add(goldFill);
  const goldHeap = new THREE.Mesh(new THREE.SphereGeometry(1, 10, 4, 0, Math.PI * 2, 0, Math.PI / 2), goldMat);
  goldHeap.name = 'goldHeap';
  goldHeap.position.set(0, 0.29, 0);
  goldHeap.scale.set(0.356, 0.11, 0.206);
  root.add(goldHeap);
  const coin = new THREE.Mesh(cylinderGeo, coinMat);
  coin.name = 'coin';
  coin.position.set(0.0576, 0.3942, -0.016);
  coin.rotation.set(deg(19.7381), deg(120.5521), deg(-18.2104));
  root.add(coin);
  const coin2 = new THREE.Mesh(cylinderGeo, coinMat);
  coin2.name = 'coin';
  coin2.position.set(0.0151, 0.3893, -0.0701);
  coin2.rotation.set(deg(6.9857), deg(155.7854), deg(-1.5502));
  root.add(coin2);
  const coin3 = new THREE.Mesh(cylinderGeo, coinMat);
  coin3.name = 'coin';
  coin3.position.set(-0.1424, 0.3647, 0.1181);
  coin3.rotation.set(deg(13.7613), deg(55.2603), deg(-16.9538));
  root.add(coin3);
  const coin4 = new THREE.Mesh(cylinderGeo, coinMat);
  coin4.name = 'coin';
  coin4.position.set(0.0004, 0.3916, 0.0577);
  coin4.rotation.set(deg(6.1948), deg(0.6917), deg(-1.6362));
  root.add(coin4);
  const coin5 = new THREE.Mesh(cylinderGeo, coinMat);
  coin5.name = 'coin';
  coin5.position.set(0.1921, 0.3416, -0.1387);
  coin5.rotation.set(deg(5.1701), deg(5.6768), deg(-13.0505));
  root.add(coin5);
  const coin6 = new THREE.Mesh(cylinderGeo, coinMat);
  coin6.name = 'coin';
  coin6.position.set(-0.2496, 0.3448, -0.0971);
  coin6.rotation.set(deg(15.8786), deg(95.4604), deg(-26.4811));
  root.add(coin6);
  const coin7 = new THREE.Mesh(cylinderGeo, coinMat);
  coin7.name = 'coin';
  coin7.position.set(-0.1863, 0.3608, 0.1059);
  coin7.rotation.set(deg(-0.6866), deg(145.6241), deg(-10.1101));
  root.add(coin7);
  const coin8 = new THREE.Mesh(cylinderGeo, coinMat);
  coin8.name = 'coin';
  coin8.position.set(-0.0285, 0.3647, -0.1429);
  coin8.rotation.set(deg(-25.122), deg(100.188), deg(5.4169));
  root.add(coin8);
  const coin9 = new THREE.Mesh(cylinderGeo, coinMat);
  coin9.name = 'coin';
  coin9.position.set(-0.1451, 0.3835, 0.045);
  coin9.rotation.set(deg(-16.2674), deg(54.6533), deg(13.3628));
  root.add(coin9);
  const coin10 = new THREE.Mesh(cylinderGeo, coinMat);
  coin10.name = 'coin';
  coin10.position.set(0.2043, 0.3761, 0.0025);
  coin10.rotation.set(deg(-16.5654), deg(51.1573), deg(-11.5925));
  root.add(coin10);
  const coin11 = new THREE.Mesh(cylinderGeo, coinMat);
  coin11.name = 'coin';
  coin11.position.set(-0.2423, 0.3622, 0.0494);
  coin11.rotation.set(deg(10.1231), deg(124.7559), deg(23.959));
  root.add(coin11);
  const coin12 = new THREE.Mesh(cylinderGeo, coinMat);
  coin12.name = 'coin';
  coin12.position.set(-0.2347, 0.3245, 0.1371);
  coin12.rotation.set(deg(-3.8563), deg(169.613), deg(-20.3113));
  root.add(coin12);
  const coin13 = new THREE.Mesh(cylinderGeo, coinMat);
  coin13.name = 'coin';
  coin13.position.set(-0.2216, 0.3181, -0.1496);
  coin13.rotation.set(deg(-7.815), deg(86.7101), deg(6.2676));
  root.add(coin13);
  const coin14 = new THREE.Mesh(cylinderGeo, coinMat);
  coin14.name = 'coin';
  coin14.position.set(0.2276, 0.3339, -0.1305);
  coin14.rotation.set(deg(12.2975), deg(168.2762), deg(-12.4179));
  root.add(coin14);
  const coin15 = new THREE.Mesh(cylinderGeo, coinMat);
  coin15.name = 'coin';
  coin15.position.set(0.1177, 0.3754, -0.099);
  coin15.rotation.set(deg(1.1377), deg(147.9405), deg(-21.2468));
  root.add(coin15);
  const coin16 = new THREE.Mesh(cylinderGeo, coinMat);
  coin16.name = 'coin';
  coin16.position.set(0.2823, 0.3522, 0.0194);
  coin16.rotation.set(deg(23.3027), deg(78.1183), deg(4.3934));
  root.add(coin16);
  const coin17 = new THREE.Mesh(cylinderGeo, coinMat);
  coin17.name = 'coin';
  coin17.position.set(-0.0929, 0.391, 0.0297);
  coin17.rotation.set(deg(-9.9144), deg(131.2945), deg(-11.4683));
  root.add(coin17);
  const coin18 = new THREE.Mesh(cylinderGeo, coinMat);
  coin18.name = 'coin';
  coin18.position.set(-0.0286, 0.3799, 0.106);
  coin18.rotation.set(deg(10.9237), deg(178.9221), deg(21.8511));
  root.add(coin18);
  const coin19 = new THREE.Mesh(cylinderGeo, coinMat);
  coin19.name = 'coin';
  coin19.position.set(-0.0388, 0.3951, 0.014);
  coin19.rotation.set(deg(-11.4279), deg(18.1579), deg(11.0164));
  root.add(coin19);
  const coin20 = new THREE.Mesh(cylinderGeo, coinMat);
  coin20.name = 'coin';
  coin20.position.set(-0.1063, 0.3798, 0.0884);
  coin20.rotation.set(deg(22.6674), deg(16.8554), deg(-1.3781));
  root.add(coin20);
  const ruby = new THREE.Mesh(new THREE.OctahedronGeometry(0.045, 0), rubyMat);
  ruby.name = 'ruby';
  ruby.position.set(-0.12, 0.4021, 0.05);
  ruby.rotation.set(deg(20), deg(30), deg(10));
  ruby.scale.set(1, 1.25, 1);
  root.add(ruby);
  const emerald = new THREE.Mesh(new THREE.OctahedronGeometry(0.04, 0), emeraldMat);
  emerald.name = 'emerald';
  emerald.position.set(0.15, 0.3974, -0.04);
  emerald.rotation.set(deg(-15), deg(10), deg(25));
  emerald.scale.set(1, 1.25, 1);
  root.add(emerald);
  const lid = new THREE.Group();
  lid.name = 'lid';
  lid.position.set(0, 0.36, -0.25);
  lid.rotation.set(deg(-42), 0, 0);
  root.add(lid);
  const lidBody = new THREE.Mesh(extrude([[0.25, 0], [0.2378, 0.0773], [0.2023, 0.1469], [0.1469, 0.2023], [0.0773, 0.2378], [0, 0.25], [-0.0773, 0.2378], [-0.1469, 0.2023], [-0.2023, 0.1469], [-0.2378, 0.0773], [-0.25, 0]], 0.8), woodMat);
  lidBody.name = 'lidBody';
  lidBody.position.set(0, 0, 0.25);
  lidBody.rotation.set(0, deg(90), 0);
  lid.add(lidBody);
  const lidLining = new THREE.Mesh(new THREE.BoxGeometry(0.74, 0.004, 0.44), liningMat);
  lidLining.name = 'lidLining';
  lidLining.position.set(0, -0.003, 0.25);
  lid.add(lidLining);
  const lidBand = new THREE.Mesh(extrudeGeo, trimMat);
  lidBand.name = 'lidBand';
  lidBand.position.set(-0.27, 0, 0.25);
  lidBand.rotation.set(0, deg(90), 0);
  lid.add(lidBand);
  const lidEnd = new THREE.Mesh(extrudeGeo2, woodDarkMat);
  lidEnd.name = 'lidEnd';
  lidEnd.position.set(-0.391, 0, 0.25);
  lidEnd.rotation.set(0, deg(90), 0);
  lid.add(lidEnd);
  const lidBand2 = new THREE.Mesh(extrudeGeo, trimMat);
  lidBand2.name = 'lidBand';
  lidBand2.position.set(0.27, 0, 0.25);
  lidBand2.rotation.set(0, deg(90), 0);
  lid.add(lidBand2);
  const lidEnd2 = new THREE.Mesh(extrudeGeo2, woodDarkMat);
  lidEnd2.name = 'lidEnd';
  lidEnd2.position.set(0.391, 0, 0.25);
  lidEnd2.rotation.set(0, deg(90), 0);
  lid.add(lidEnd2);
  const lidRimFront = new THREE.Mesh(new THREE.BoxGeometry(0.78, 0.03, 0.018), woodDarkMat);
  lidRimFront.name = 'lidRimFront';
  lidRimFront.position.set(0, 0.015, 0.495);
  lid.add(lidRimFront);
  const hasp = new THREE.Mesh(new THREE.BoxGeometry(0.08, 0.11, 0.014), trimMat);
  hasp.name = 'hasp';
  hasp.position.set(0, -0.012, 0.513);
  lid.add(hasp);

  // Animations ('open') — play them with THREE.AnimationMixer
  root.animations = codelsClips(THREE, [
    { target: lid, anim: [{ type: 'hinge', axis: 'x', angle: -68, duration: 0.8533 }] },
  ]);

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

export default createTreasureChest;

Puanlar ve yorumlar

—
Henüz puan yok — ilk puanı sen ver.
5
0
4
0
3
0
2
0
1
0

Puan vermek ve yorum yapmak için giriş yap.

0 yorum

Henüz yorum yok. Bu modeli nasıl kullandığını ya da neyin daha iyi olabileceğini paylaş.

Benzer modeller

Aynı kategori ya da benzer etiketler