Codels
1,2 B üçgen1,42 × 1,61 × 2,09 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.
/**
 * Laser Turret — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,168 · Size (W × H × D): 1.42 × 1.60 × 2.09 m
 *
 * Usage:
 *   import { createLaserTurret } from './laser-turret.js';
 *   
 *   const model = createLaserTurret();
 *   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 createLaserTurret() {
  const root = new THREE.Group();
  root.name = 'LaserTurret';

  // Materials
  const armorMat = new THREE.MeshStandardMaterial({ name: 'armor', color: 0xd0d6de, roughness: 0.45, metalness: 0.3, flatShading: true });
  const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x2f343c, roughness: 0.6, metalness: 0.35, flatShading: true });
  const metalMat = new THREE.MeshStandardMaterial({ name: 'metal', color: 0x7d858f, roughness: 0.4, metalness: 0.6, flatShading: true });
  const hazardMat = new THREE.MeshStandardMaterial({ name: 'hazard', color: 0xf2b630, roughness: 0.55, metalness: 0.2, flatShading: true });
  const glowMat = new THREE.MeshStandardMaterial({ name: 'glow', color: 0xff4436, roughness: 0.4, emissive: 0xff4436, emissiveIntensity: 1.3, flatShading: true });
  const tipMat = new THREE.MeshStandardMaterial({ name: 'tip', color: 0xff9890, roughness: 0.3, emissive: 0xff695e, emissiveIntensity: 1.4, flatShading: true });

  // Shared geometries
  const cylinderGeo = new THREE.CylinderGeometry(0.04, 0.05, 0.05, 6);
  const extrudeGeo = extrude([[-0.3444, 0.05], [0.2132, 0.05], [0.328, 0.1514], [0.246, 0.3932], [-0.1476, 0.4556], [-0.3772, 0.2996]], 0.06);
  const boxGeo = new THREE.BoxGeometry(0.02, 0.04, 0.34);
  const boxGeo2 = new THREE.BoxGeometry(0.44, 0.02, 0.2);
  const cylinderGeo2 = new THREE.CylinderGeometry(0.06, 0.07, 0.24, 8);
  const cylinderGeo3 = new THREE.CylinderGeometry(0.04, 0.045, 0.8, 8);
  const cylinderGeo4 = new THREE.CylinderGeometry(0.062, 0.062, 0.04, 8);
  const boxGeo3 = new THREE.BoxGeometry(0.018, 0.012, 0.36);
  const cylinderGeo5 = new THREE.CylinderGeometry(0.07, 0.06, 0.14, 8);
  const cylinderGeo6 = new THREE.CylinderGeometry(0.045, 0.045, 0.06, 8);
  const coneGeo = new THREE.ConeGeometry(0.03, 0.08, 6);

  // Parts
  const plinth = new THREE.Mesh(new THREE.CylinderGeometry(0.62, 0.68, 0.16, 8), darkMat);
  plinth.name = 'plinth';
  plinth.position.set(0, 0.08, 0);
  plinth.rotation.set(0, deg(22.5), 0);
  root.add(plinth);
  const plinthCap = new THREE.Mesh(new THREE.CylinderGeometry(0.5, 0.6, 0.1, 8), armorMat);
  plinthCap.name = 'plinthCap';
  plinthCap.position.set(0, 0.21, 0);
  plinthCap.rotation.set(0, deg(22.5), 0);
  root.add(plinthCap);
  const bolt1 = new THREE.Mesh(cylinderGeo, metalMat);
  bolt1.name = 'bolt1';
  bolt1.position.set(0.396, 0.185, 0.396);
  root.add(bolt1);
  const bolt2 = new THREE.Mesh(cylinderGeo, metalMat);
  bolt2.name = 'bolt2';
  bolt2.position.set(0.396, 0.185, -0.396);
  root.add(bolt2);
  const bolt3 = new THREE.Mesh(cylinderGeo, metalMat);
  bolt3.name = 'bolt3';
  bolt3.position.set(-0.396, 0.185, -0.396);
  root.add(bolt3);
  const bolt4 = new THREE.Mesh(cylinderGeo, metalMat);
  bolt4.name = 'bolt4';
  bolt4.position.set(-0.396, 0.185, 0.396);
  root.add(bolt4);
  const column = new THREE.Mesh(new THREE.CylinderGeometry(0.34, 0.42, 0.42, 8), armorMat);
  column.name = 'column';
  column.position.set(0, 0.47, 0);
  column.rotation.set(0, deg(22.5), 0);
  root.add(column);
  const hazardRing = new THREE.Mesh(new THREE.CylinderGeometry(0.385, 0.395, 0.1, 16), darkMat);
  hazardRing.name = 'hazardRing';
  hazardRing.position.set(0, 0.41, 0);
  root.add(hazardRing);
  const hazard1 = new THREE.Mesh(new THREE.CylinderGeometry(0.392, 0.402, 0.1, 1, 1, false, 0, 0.3927), hazardMat);
  hazard1.name = 'hazard1';
  hazard1.position.set(0, 0.41, 0);
  root.add(hazard1);
  const hazard2 = new THREE.Mesh(new THREE.CylinderGeometry(0.392, 0.402, 0.1, 1, 1, false, Math.PI / 4, 0.3927), hazardMat);
  hazard2.name = 'hazard2';
  hazard2.position.set(0, 0.41, 0);
  root.add(hazard2);
  const hazard3 = new THREE.Mesh(new THREE.CylinderGeometry(0.392, 0.402, 0.1, 1, 1, false, Math.PI / 2, 0.3927), hazardMat);
  hazard3.name = 'hazard3';
  hazard3.position.set(0, 0.41, 0);
  root.add(hazard3);
  const hazard4 = new THREE.Mesh(new THREE.CylinderGeometry(0.392, 0.402, 0.1, 1, 1, false, Math.PI * 0.75, 0.3927), hazardMat);
  hazard4.name = 'hazard4';
  hazard4.position.set(0, 0.41, 0);
  root.add(hazard4);
  const hazard5 = new THREE.Mesh(new THREE.CylinderGeometry(0.392, 0.402, 0.1, 1, 1, false, Math.PI, 0.3927), hazardMat);
  hazard5.name = 'hazard5';
  hazard5.position.set(0, 0.41, 0);
  root.add(hazard5);
  const hazard6 = new THREE.Mesh(new THREE.CylinderGeometry(0.392, 0.402, 0.1, 1, 1, false, Math.PI * 1.25, 0.3927), hazardMat);
  hazard6.name = 'hazard6';
  hazard6.position.set(0, 0.41, 0);
  root.add(hazard6);
  const hazard7 = new THREE.Mesh(new THREE.CylinderGeometry(0.392, 0.402, 0.1, 1, 1, false, Math.PI * 1.5, 0.3927), hazardMat);
  hazard7.name = 'hazard7';
  hazard7.position.set(0, 0.41, 0);
  root.add(hazard7);
  const hazard8 = new THREE.Mesh(new THREE.CylinderGeometry(0.392, 0.402, 0.1, 1, 1, false, Math.PI * 1.75, 0.3927), hazardMat);
  hazard8.name = 'hazard8';
  hazard8.position.set(0, 0.41, 0);
  root.add(hazard8);
  const baseLight = new THREE.Mesh(new THREE.BoxGeometry(0.16, 0.08, 0.02), glowMat);
  baseLight.name = 'baseLight';
  baseLight.position.set(0, 0.58, 0.338);
  baseLight.rotation.set(deg(-11), 0, 0);
  root.add(baseLight);
  const turntable = new THREE.Mesh(new THREE.CylinderGeometry(0.44, 0.44, 0.08, 12), darkMat);
  turntable.name = 'turntable';
  turntable.position.set(0, 0.72, 0);
  root.add(turntable);
  const head = new THREE.Group();
  head.name = 'head';
  head.position.set(0, 0.76, 0);
  head.rotation.set(0, deg(25), 0);
  root.add(head);
  const housing = new THREE.Mesh(extrude([[-0.42, 0], [0.26, 0], [0.4, 0.13], [0.3, 0.44], [-0.18, 0.52], [-0.46, 0.32]], 0.62), armorMat);
  housing.name = 'housing';
  housing.rotation.set(0, deg(-90), 0);
  head.add(housing);
  const sidePlateL = new THREE.Mesh(extrudeGeo, darkMat);
  sidePlateL.name = 'sidePlateL';
  sidePlateL.position.set(-0.33, 0, -0.02);
  sidePlateL.rotation.set(0, deg(-90), 0);
  head.add(sidePlateL);
  const sideGlowL = new THREE.Mesh(boxGeo, glowMat);
  sideGlowL.name = 'sideGlowL';
  sideGlowL.position.set(-0.365, 0.24, -0.06);
  head.add(sideGlowL);
  const sidePlateR = new THREE.Mesh(extrudeGeo, darkMat);
  sidePlateR.name = 'sidePlateR';
  sidePlateR.position.set(0.33, 0, -0.02);
  sidePlateR.rotation.set(0, deg(-90), 0);
  head.add(sidePlateR);
  const sideGlowR = new THREE.Mesh(boxGeo, glowMat);
  sideGlowR.name = 'sideGlowR';
  sideGlowR.position.set(0.365, 0.24, -0.06);
  head.add(sideGlowR);
  const visor = new THREE.Mesh(new THREE.BoxGeometry(0.3, 0.1, 0.06), darkMat);
  visor.name = 'visor';
  visor.position.set(0, 0.39, 0.33);
  visor.rotation.set(deg(-18), 0, 0);
  head.add(visor);
  const eye = new THREE.Mesh(new THREE.CylinderGeometry(0.035, 0.035, 0.04, 8), glowMat);
  eye.name = 'eye';
  eye.position.set(-0.07, 0.395, 0.36);
  eye.rotation.set(deg(72), 0, 0);
  head.add(eye);
  const eyeSmall = new THREE.Mesh(new THREE.CylinderGeometry(0.022, 0.022, 0.04, 6), glowMat);
  eyeSmall.name = 'eyeSmall';
  eyeSmall.position.set(0.06, 0.395, 0.36);
  eyeSmall.rotation.set(deg(72), 0, 0);
  head.add(eyeSmall);
  const powerPack = new THREE.Mesh(new THREE.BoxGeometry(0.4, 0.3, 0.16), metalMat);
  powerPack.name = 'powerPack';
  powerPack.position.set(0, 0.22, -0.5);
  head.add(powerPack);
  const fin1 = new THREE.Mesh(boxGeo2, darkMat);
  fin1.name = 'fin1';
  fin1.position.set(0, 0.11, -0.52);
  head.add(fin1);
  const fin2 = new THREE.Mesh(boxGeo2, darkMat);
  fin2.name = 'fin2';
  fin2.position.set(0, 0.18, -0.52);
  head.add(fin2);
  const fin3 = new THREE.Mesh(boxGeo2, darkMat);
  fin3.name = 'fin3';
  fin3.position.set(0, 0.25, -0.52);
  head.add(fin3);
  const fin4 = new THREE.Mesh(boxGeo2, darkMat);
  fin4.name = 'fin4';
  fin4.position.set(0, 0.32, -0.52);
  head.add(fin4);
  const packLight = new THREE.Mesh(new THREE.BoxGeometry(0.16, 0.05, 0.02), glowMat);
  packLight.name = 'packLight';
  packLight.position.set(0, 0.27, -0.585);
  head.add(packLight);
  const antenna = new THREE.Mesh(new THREE.CylinderGeometry(0.012, 0.016, 0.34, 5), metalMat);
  antenna.name = 'antenna';
  antenna.position.set(0.2, 0.64, -0.22);
  head.add(antenna);
  const antennaTip = new THREE.Mesh(new THREE.SphereGeometry(0.025, 6, 4), glowMat);
  antennaTip.name = 'antennaTip';
  antennaTip.position.set(0.2, 0.82, -0.22);
  head.add(antennaTip);
  const barrels = new THREE.Group();
  barrels.name = 'barrels';
  barrels.position.set(0, 0.22, 0.3);
  barrels.rotation.set(deg(-12), 0, 0);
  head.add(barrels);
  const mantlet = new THREE.Mesh(new THREE.BoxGeometry(0.5, 0.2, 0.14), darkMat);
  mantlet.name = 'mantlet';
  mantlet.position.set(0, 0, 0.02);
  barrels.add(mantlet);
  const trunnion = new THREE.Mesh(new THREE.CylinderGeometry(0.07, 0.07, 0.72, 8), metalMat);
  trunnion.name = 'trunnion';
  trunnion.rotation.set(0, 0, deg(90));
  barrels.add(trunnion);
  const sleeveL = new THREE.Mesh(cylinderGeo2, armorMat);
  sleeveL.name = 'sleeveL';
  sleeveL.position.set(-0.15, 0, 0.2);
  sleeveL.rotation.set(deg(90), 0, 0);
  barrels.add(sleeveL);
  const barrelL = new THREE.Mesh(cylinderGeo3, metalMat);
  barrelL.name = 'barrelL';
  barrelL.position.set(-0.15, 0, 0.66);
  barrelL.rotation.set(deg(90), 0, 0);
  barrels.add(barrelL);
  const cylinder41 = new THREE.Mesh(cylinderGeo4, darkMat);
  cylinder41.position.set(-0.15, 0, 0.42);
  cylinder41.rotation.set(deg(90), 0, 0);
  barrels.add(cylinder41);
  const cylinder42 = new THREE.Mesh(cylinderGeo4, darkMat);
  cylinder42.position.set(-0.15, 0, 0.52);
  cylinder42.rotation.set(deg(90), 0, 0);
  barrels.add(cylinder42);
  const cylinder43 = new THREE.Mesh(cylinderGeo4, darkMat);
  cylinder43.position.set(-0.15, 0, 0.62);
  cylinder43.rotation.set(deg(90), 0, 0);
  barrels.add(cylinder43);
  const coilL = new THREE.Mesh(boxGeo3, glowMat);
  coilL.name = 'coilL';
  coilL.position.set(-0.15, 0.045, 0.82);
  barrels.add(coilL);
  const muzzleL = new THREE.Mesh(cylinderGeo5, darkMat);
  muzzleL.name = 'muzzleL';
  muzzleL.position.set(-0.15, 0, 1.06);
  muzzleL.rotation.set(deg(90), 0, 0);
  barrels.add(muzzleL);
  const emitterL = new THREE.Mesh(cylinderGeo6, glowMat);
  emitterL.name = 'emitterL';
  emitterL.position.set(-0.15, 0, 1.13);
  emitterL.rotation.set(deg(90), 0, 0);
  barrels.add(emitterL);
  const tipL = new THREE.Mesh(coneGeo, tipMat);
  tipL.name = 'tipL';
  tipL.position.set(-0.15, 0, 1.2);
  tipL.rotation.set(deg(90), 0, 0);
  barrels.add(tipL);
  const sleeveR = new THREE.Mesh(cylinderGeo2, armorMat);
  sleeveR.name = 'sleeveR';
  sleeveR.position.set(0.15, 0, 0.2);
  sleeveR.rotation.set(deg(90), 0, 0);
  barrels.add(sleeveR);
  const barrelR = new THREE.Mesh(cylinderGeo3, metalMat);
  barrelR.name = 'barrelR';
  barrelR.position.set(0.15, 0, 0.66);
  barrelR.rotation.set(deg(90), 0, 0);
  barrels.add(barrelR);
  const cylinder50 = new THREE.Mesh(cylinderGeo4, darkMat);
  cylinder50.position.set(0.15, 0, 0.42);
  cylinder50.rotation.set(deg(90), 0, 0);
  barrels.add(cylinder50);
  const cylinder51 = new THREE.Mesh(cylinderGeo4, darkMat);
  cylinder51.position.set(0.15, 0, 0.52);
  cylinder51.rotation.set(deg(90), 0, 0);
  barrels.add(cylinder51);
  const cylinder52 = new THREE.Mesh(cylinderGeo4, darkMat);
  cylinder52.position.set(0.15, 0, 0.62);
  cylinder52.rotation.set(deg(90), 0, 0);
  barrels.add(cylinder52);
  const coilR = new THREE.Mesh(boxGeo3, glowMat);
  coilR.name = 'coilR';
  coilR.position.set(0.15, 0.045, 0.82);
  barrels.add(coilR);
  const muzzleR = new THREE.Mesh(cylinderGeo5, darkMat);
  muzzleR.name = 'muzzleR';
  muzzleR.position.set(0.15, 0, 1.06);
  muzzleR.rotation.set(deg(90), 0, 0);
  barrels.add(muzzleR);
  const emitterR = new THREE.Mesh(cylinderGeo6, glowMat);
  emitterR.name = 'emitterR';
  emitterR.position.set(0.15, 0, 1.13);
  emitterR.rotation.set(deg(90), 0, 0);
  barrels.add(emitterR);
  const tipR = new THREE.Mesh(coneGeo, tipMat);
  tipR.name = 'tipR';
  tipR.position.set(0.15, 0, 1.2);
  tipR.rotation.set(deg(90), 0, 0);
  barrels.add(tipR);

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

export default createLaserTurret;

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