Codels
2,1 B üçgen1,86 × 1,44 × 4,46 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.
/**
 * Sedan — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 2,108 · Size (W × H × D): 1.86 × 1.44 × 4.46 m
 *
 * Usage:
 *   import { createSedan } from './sedan.js';
 *   
 *   const model = createSedan();
 *   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);
}

export function createSedan() {
  const root = new THREE.Group();
  root.name = 'Sedan';

  // Materials
  const paintMat = new THREE.MeshStandardMaterial({ name: 'paint', color: 0x3f78c0, roughness: 0.42, metalness: 0.15, flatShading: true });
  const glassMat = new THREE.MeshStandardMaterial({ name: 'glass', color: 0x2a3644, roughness: 0.2, metalness: 0.3, flatShading: true });
  const trimMat = new THREE.MeshStandardMaterial({ name: 'trim', color: 0x2a2c31, roughness: 0.8, flatShading: true });
  const chromeMat = new THREE.MeshStandardMaterial({ name: 'chrome', color: 0xc9cdd3, roughness: 0.3, metalness: 0.65, flatShading: true });
  const headlightMat = new THREE.MeshStandardMaterial({ name: 'headlight', color: 0xfff4d6, roughness: 0.3, emissive: 0xffe2a0, emissiveIntensity: 0.9, flatShading: true });
  const taillightMat = new THREE.MeshStandardMaterial({ name: 'taillight', color: 0xd81e28, roughness: 0.3, emissive: 0xff2020, emissiveIntensity: 0.7, flatShading: true });

  // Shared geometries
  const extrudeGeo = extrude([[0.8004, 0.99], [0.3225, 1.33], [-0.12, 1.33], [-0.12, 0.99]], 0.02);
  const extrudeGeo2 = extrude([[-0.22, 0.99], [-0.22, 1.33], [-0.6526, 1.33], [-0.9852, 0.99]], 0.02);
  const boxGeo = new THREE.BoxGeometry(0.36, 0.12, 0.06);
  const boxGeo2 = new THREE.BoxGeometry(0.34, 0.11, 0.06);
  const boxGeo3 = new THREE.BoxGeometry(0.13, 0.09, 0.13);
  const boxGeo4 = new THREE.BoxGeometry(0.006, 0.52, 0.014);
  const boxGeo5 = new THREE.BoxGeometry(0.02, 0.03, 0.13);
  const boxGeo6 = new THREE.BoxGeometry(0.05, 0.1, 1.7);
  const boxGeo7 = new THREE.BoxGeometry(1.86, 0.16, 0.24);
  const boxGeo8 = new THREE.BoxGeometry(0.36, 0.11, 0.02);
  const latheGeo = lathe([[0.2139, -0.095], [0.2139, -0.12], [0.3, -0.12], [0.345, -0.07], [0.345, 0.07], [0.3, 0.12], [0.2139, 0.12], [0.2139, 0.095]], 14);
  const cylinderGeo = new THREE.CylinderGeometry(0.2139, 0.2139, 0.19, 14);
  const cylinderGeo2 = new THREE.CylinderGeometry(0.1754, 0.2096, 0.03, 14);
  const cylinderGeo3 = new THREE.CylinderGeometry(0.0535, 0.0684, 0.03, 8);

  // Parts
  const body = new THREE.Group();
  body.name = 'body';
  root.add(body);
  const lowerBody = new THREE.Mesh(extrude([[2.02, 0.24], [2.11, 0.34], [2.12, 0.62], [2, 0.79], [1.5, 0.88], [1, 0.93], [-1.05, 0.935], [-1.88, 0.945], [-2.1, 0.88], [-2.12, 0.44], [-2.02, 0.24], [-1.7773, 0.24], [-1.7802, 0.4376], [-1.6963, 0.6165], [-1.5425, 0.7406], [-1.35, 0.785], [-1.1575, 0.7406], [-1.0037, 0.6165], [-0.9198, 0.4376], [-0.9227, 0.24], [0.9227, 0.24], [0.9198, 0.4376], [1.0037, 0.6165], [1.1575, 0.7406], [1.35, 0.785], [1.5425, 0.7406], [1.6963, 0.6165], [1.7802, 0.4376], [1.7773, 0.24]], 1.73, [], [0.035, 0.035, 2]), paintMat);
  lowerBody.name = 'lowerBody';
  lowerBody.rotation.set(0, deg(-90), 0);
  body.add(lowerBody);
  const chassis = new THREE.Mesh(new THREE.BoxGeometry(1.24, 0.5, 3.9), trimMat);
  chassis.name = 'chassis';
  chassis.position.set(0, 0.55, 0);
  body.add(chassis);
  const cabin = new THREE.Mesh(extrude([[1.12, 0.84], [0.3, 1.4], [-0.66, 1.4], [-1.22, 0.86]], 1.42, [], [0.05, 0.05, 2]), paintMat);
  cabin.name = 'cabin';
  cabin.rotation.set(0, deg(-90), 0);
  body.add(cabin);
  const windowFL = new THREE.Mesh(extrudeGeo, glassMat);
  windowFL.name = 'windowFL';
  windowFL.position.set(0.765, 0, 0);
  windowFL.rotation.set(0, deg(-90), 0);
  body.add(windowFL);
  const windowRL = new THREE.Mesh(extrudeGeo2, glassMat);
  windowRL.name = 'windowRL';
  windowRL.position.set(0.765, 0, 0);
  windowRL.rotation.set(0, deg(-90), 0);
  body.add(windowRL);
  const windowFR = new THREE.Mesh(extrudeGeo, glassMat);
  windowFR.name = 'windowFR';
  windowFR.position.set(-0.765, 0, 0);
  windowFR.rotation.set(0, deg(-90), 0);
  body.add(windowFR);
  const windowRR = new THREE.Mesh(extrudeGeo2, glassMat);
  windowRR.name = 'windowRR';
  windowRR.position.set(-0.765, 0, 0);
  windowRR.rotation.set(0, deg(-90), 0);
  body.add(windowRR);
  const windshield = new THREE.Mesh(new THREE.BoxGeometry(1.3, 0.02, 0.6206), glassMat);
  windshield.name = 'windshield';
  windshield.position.set(0, 1.2079, 0.6948);
  windshield.rotation.set(deg(-145.6698), 0, 0);
  body.add(windshield);
  const rearWindow = new THREE.Mesh(new THREE.BoxGeometry(1.3, 0.02, 0.4898), glassMat);
  rearWindow.name = 'rearWindow';
  rearWindow.position.set(0, 1.2161, -0.9429);
  rearWindow.rotation.set(deg(136.0416), 0, 0);
  body.add(rearWindow);
  const headlightL = new THREE.Mesh(boxGeo, headlightMat);
  headlightL.name = 'headlightL';
  headlightL.position.set(0.57, 0.6, 2.155);
  body.add(headlightL);
  const taillightL = new THREE.Mesh(boxGeo2, taillightMat);
  taillightL.name = 'taillightL';
  taillightL.position.set(0.58, 0.74, -2.155);
  body.add(taillightL);
  const mirrorL = new THREE.Mesh(boxGeo3, paintMat);
  mirrorL.name = 'mirrorL';
  mirrorL.position.set(0.83, 1.03, 0.76);
  body.add(mirrorL);
  const box14 = new THREE.Mesh(boxGeo4, trimMat);
  box14.position.set(0.903, 0.6, 0.86);
  body.add(box14);
  const box15 = new THREE.Mesh(boxGeo4, trimMat);
  box15.position.set(0.903, 0.6, -0.12);
  body.add(box15);
  const box16 = new THREE.Mesh(boxGeo4, trimMat);
  box16.position.set(0.903, 0.6, -0.88);
  body.add(box16);
  const box17 = new THREE.Mesh(boxGeo5, trimMat);
  box17.position.set(0.91, 0.8, 0.36);
  body.add(box17);
  const box18 = new THREE.Mesh(boxGeo5, trimMat);
  box18.position.set(0.91, 0.8, -0.56);
  body.add(box18);
  const skirtL = new THREE.Mesh(boxGeo6, trimMat);
  skirtL.name = 'skirtL';
  skirtL.position.set(0.89, 0.26, 0);
  body.add(skirtL);
  const headlightR = new THREE.Mesh(boxGeo, headlightMat);
  headlightR.name = 'headlightR';
  headlightR.position.set(-0.57, 0.6, 2.155);
  body.add(headlightR);
  const taillightR = new THREE.Mesh(boxGeo2, taillightMat);
  taillightR.name = 'taillightR';
  taillightR.position.set(-0.58, 0.74, -2.155);
  body.add(taillightR);
  const mirrorR = new THREE.Mesh(boxGeo3, paintMat);
  mirrorR.name = 'mirrorR';
  mirrorR.position.set(-0.83, 1.03, 0.76);
  body.add(mirrorR);
  const box23 = new THREE.Mesh(boxGeo4, trimMat);
  box23.position.set(-0.903, 0.6, 0.86);
  body.add(box23);
  const box24 = new THREE.Mesh(boxGeo4, trimMat);
  box24.position.set(-0.903, 0.6, -0.12);
  body.add(box24);
  const box25 = new THREE.Mesh(boxGeo4, trimMat);
  box25.position.set(-0.903, 0.6, -0.88);
  body.add(box25);
  const box26 = new THREE.Mesh(boxGeo5, trimMat);
  box26.position.set(-0.91, 0.8, 0.36);
  body.add(box26);
  const box27 = new THREE.Mesh(boxGeo5, trimMat);
  box27.position.set(-0.91, 0.8, -0.56);
  body.add(box27);
  const skirtR = new THREE.Mesh(boxGeo6, trimMat);
  skirtR.name = 'skirtR';
  skirtR.position.set(-0.89, 0.26, 0);
  body.add(skirtR);
  const grille = new THREE.Mesh(new THREE.BoxGeometry(0.72, 0.13, 0.04), trimMat);
  grille.name = 'grille';
  grille.position.set(0, 0.58, 2.16);
  body.add(grille);
  const bumperFront = new THREE.Mesh(boxGeo7, trimMat);
  bumperFront.name = 'bumperFront';
  bumperFront.position.set(0, 0.33, 2.1);
  body.add(bumperFront);
  const bumperRear = new THREE.Mesh(boxGeo7, trimMat);
  bumperRear.name = 'bumperRear';
  bumperRear.position.set(0, 0.34, -2.1);
  body.add(bumperRear);
  const plateFront = new THREE.Mesh(boxGeo8, chromeMat);
  plateFront.name = 'plateFront';
  plateFront.position.set(0, 0.34, 2.23);
  body.add(plateFront);
  const plateRear = new THREE.Mesh(boxGeo8, chromeMat);
  plateRear.name = 'plateRear';
  plateRear.position.set(0, 0.5, -2.167);
  body.add(plateRear);
  const wheels = new THREE.Group();
  wheels.name = 'wheels';
  root.add(wheels);
  const wheelFL = new THREE.Group();
  wheelFL.name = 'wheelFL';
  wheelFL.position.set(0.765, 0.345, 1.35);
  wheels.add(wheelFL);
  const tire = new THREE.Mesh(latheGeo, trimMat);
  tire.name = 'tire';
  tire.rotation.set(0, 0, deg(90));
  wheelFL.add(tire);
  const rim = new THREE.Mesh(cylinderGeo, chromeMat);
  rim.name = 'rim';
  rim.rotation.set(0, 0, deg(90));
  wheelFL.add(rim);
  const hubcap = new THREE.Mesh(cylinderGeo2, chromeMat);
  hubcap.name = 'hubcap';
  hubcap.position.set(0.11, 0, 0);
  hubcap.rotation.set(0, 0, deg(-90));
  wheelFL.add(hubcap);
  const centerCap = new THREE.Mesh(cylinderGeo3, trimMat);
  centerCap.name = 'centerCap';
  centerCap.position.set(0.135, 0, 0);
  centerCap.rotation.set(0, 0, deg(-90));
  wheelFL.add(centerCap);
  const wheelFR = new THREE.Group();
  wheelFR.name = 'wheelFR';
  wheelFR.position.set(-0.765, 0.345, 1.35);
  wheels.add(wheelFR);
  const tire2 = new THREE.Mesh(latheGeo, trimMat);
  tire2.name = 'tire';
  tire2.rotation.set(0, 0, deg(90));
  wheelFR.add(tire2);
  const rim2 = new THREE.Mesh(cylinderGeo, chromeMat);
  rim2.name = 'rim';
  rim2.rotation.set(0, 0, deg(90));
  wheelFR.add(rim2);
  const hubcap2 = new THREE.Mesh(cylinderGeo2, chromeMat);
  hubcap2.name = 'hubcap';
  hubcap2.position.set(-0.11, 0, 0);
  hubcap2.rotation.set(0, 0, deg(90));
  wheelFR.add(hubcap2);
  const centerCap2 = new THREE.Mesh(cylinderGeo3, trimMat);
  centerCap2.name = 'centerCap';
  centerCap2.position.set(-0.135, 0, 0);
  centerCap2.rotation.set(0, 0, deg(90));
  wheelFR.add(centerCap2);
  const wheelRL = new THREE.Group();
  wheelRL.name = 'wheelRL';
  wheelRL.position.set(0.765, 0.345, -1.35);
  wheels.add(wheelRL);
  const tire3 = new THREE.Mesh(latheGeo, trimMat);
  tire3.name = 'tire';
  tire3.rotation.set(0, 0, deg(90));
  wheelRL.add(tire3);
  const rim3 = new THREE.Mesh(cylinderGeo, chromeMat);
  rim3.name = 'rim';
  rim3.rotation.set(0, 0, deg(90));
  wheelRL.add(rim3);
  const hubcap3 = new THREE.Mesh(cylinderGeo2, chromeMat);
  hubcap3.name = 'hubcap';
  hubcap3.position.set(0.11, 0, 0);
  hubcap3.rotation.set(0, 0, deg(-90));
  wheelRL.add(hubcap3);
  const centerCap3 = new THREE.Mesh(cylinderGeo3, trimMat);
  centerCap3.name = 'centerCap';
  centerCap3.position.set(0.135, 0, 0);
  centerCap3.rotation.set(0, 0, deg(-90));
  wheelRL.add(centerCap3);
  const wheelRR = new THREE.Group();
  wheelRR.name = 'wheelRR';
  wheelRR.position.set(-0.765, 0.345, -1.35);
  wheels.add(wheelRR);
  const tire4 = new THREE.Mesh(latheGeo, trimMat);
  tire4.name = 'tire';
  tire4.rotation.set(0, 0, deg(90));
  wheelRR.add(tire4);
  const rim4 = new THREE.Mesh(cylinderGeo, chromeMat);
  rim4.name = 'rim';
  rim4.rotation.set(0, 0, deg(90));
  wheelRR.add(rim4);
  const hubcap4 = new THREE.Mesh(cylinderGeo2, chromeMat);
  hubcap4.name = 'hubcap';
  hubcap4.position.set(-0.11, 0, 0);
  hubcap4.rotation.set(0, 0, deg(90));
  wheelRR.add(hubcap4);
  const centerCap4 = new THREE.Mesh(cylinderGeo3, trimMat);
  centerCap4.name = 'centerCap';
  centerCap4.position.set(-0.135, 0, 0);
  centerCap4.rotation.set(0, 0, deg(90));
  wheelRR.add(centerCap4);

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

export default createSedan;

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