Codels
250 üçgen0,75 × 2,64 × 0,20 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.
/**
 * Stop Sign — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 250 · Size (W × H × D): 0.75 × 2.63 × 0.20 m
 *
 * Usage:
 *   import { createStopSign } from './stop-sign.js';
 *   
 *   const model = createStopSign();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 */
import * as THREE from 'three';

// 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 createStopSign() {
  const root = new THREE.Group();
  root.name = 'StopSign';

  // Materials
  const postMat = new THREE.MeshStandardMaterial({ name: 'post', color: 0x9aa1a6, roughness: 0.45, metalness: 0.6, flatShading: true });
  const concreteMat = new THREE.MeshStandardMaterial({ name: 'concrete', color: 0x9c998f, roughness: 0.95, flatShading: true });
  const backMat = new THREE.MeshStandardMaterial({ name: 'back', color: 0x8e949a, roughness: 0.5, metalness: 0.5, flatShading: true });
  const whiteMat = new THREE.MeshStandardMaterial({ name: 'white', color: 0xf3f3ee, roughness: 0.45, flatShading: true });
  const redMat = new THREE.MeshStandardMaterial({ name: 'red', color: 0xc3161c, roughness: 0.45, flatShading: true });
  const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x3a3f44, roughness: 0.6, metalness: 0.4, flatShading: true });

  // Shared geometries
  const planeGeo = new THREE.PlaneGeometry(0.1188, 0.033);
  const planeGeo2 = new THREE.PlaneGeometry(0.033, 0.066);
  const planeGeo3 = new THREE.PlaneGeometry(0.033, 0.099);
  const planeGeo4 = new THREE.PlaneGeometry(0.0858, 0.033);
  const boxGeo = new THREE.BoxGeometry(0.1, 0.035, 0.03);
  const boxGeo2 = new THREE.BoxGeometry(0.075, 0.03, 0.016);

  // Parts
  const footing = new THREE.Mesh(new THREE.CylinderGeometry(0.09, 0.1, 0.06, 8), concreteMat);
  footing.name = 'footing';
  footing.position.set(0, 0.03, 0);
  root.add(footing);
  const post = new THREE.Mesh(new THREE.CylinderGeometry(0.03, 0.03, 2.4625, 8), postMat);
  post.name = 'post';
  post.position.set(0, 1.2913, 0);
  root.add(post);
  const postCap = new THREE.Mesh(new THREE.SphereGeometry(0.033, 8, 2, 0, Math.PI * 2, 0, Math.PI / 2), postMat);
  postCap.name = 'postCap';
  postCap.position.set(0, 2.5225, 0);
  root.add(postCap);
  const sign = new THREE.Group();
  sign.name = 'sign';
  sign.position.set(0, 2.26, 0.045);
  root.add(sign);
  const signBack = new THREE.Mesh(extrude([[0.375, 0.1553], [0.1553, 0.375], [-0.1553, 0.375], [-0.375, 0.1553], [-0.375, -0.1553], [-0.1553, -0.375], [0.1553, -0.375], [0.375, -0.1553]], 0.01), backMat);
  signBack.name = 'signBack';
  signBack.position.set(0, 0, 0.005);
  sign.add(signBack);
  const signBorder = new THREE.Mesh(extrude([[0.3732, 0.1546], [0.1546, 0.3732], [-0.1546, 0.3732], [-0.3732, 0.1546], [-0.3732, -0.1546], [-0.1546, -0.3732], [0.1546, -0.3732], [0.3732, -0.1546]], 0.003), whiteMat);
  signBorder.name = 'signBorder';
  signBorder.position.set(0, 0, 0.0115);
  sign.add(signBorder);
  const signFace = new THREE.Mesh(extrude([[0.3375, 0.1398], [0.1398, 0.3375], [-0.1398, 0.3375], [-0.3375, 0.1398], [-0.3375, -0.1398], [-0.1398, -0.3375], [0.1398, -0.3375], [0.3375, -0.1398]], 0.003), redMat);
  signFace.name = 'signFace';
  signFace.position.set(0, 0, 0.0135);
  sign.add(signFace);
  const letter = new THREE.Mesh(planeGeo, whiteMat);
  letter.name = 'letter';
  letter.position.set(-0.2128, 0.066, 0.0165);
  sign.add(letter);
  const letter2 = new THREE.Mesh(planeGeo2, whiteMat);
  letter2.name = 'letter';
  letter2.position.set(-0.2557, 0.033, 0.0165);
  sign.add(letter2);
  const letter3 = new THREE.Mesh(planeGeo, whiteMat);
  letter3.name = 'letter';
  letter3.position.set(-0.2128, 0, 0.0165);
  sign.add(letter3);
  const letter4 = new THREE.Mesh(planeGeo2, whiteMat);
  letter4.name = 'letter';
  letter4.position.set(-0.1699, -0.033, 0.0165);
  sign.add(letter4);
  const letter5 = new THREE.Mesh(planeGeo, whiteMat);
  letter5.name = 'letter';
  letter5.position.set(-0.2128, -0.066, 0.0165);
  sign.add(letter5);
  const letter6 = new THREE.Mesh(planeGeo, whiteMat);
  letter6.name = 'letter';
  letter6.position.set(-0.0709, 0.066, 0.0165);
  sign.add(letter6);
  const letter7 = new THREE.Mesh(new THREE.PlaneGeometry(0.038, 0.132), whiteMat);
  letter7.name = 'letter';
  letter7.position.set(-0.0709, -0.0165, 0.0165);
  sign.add(letter7);
  const letter8 = new THREE.Mesh(planeGeo, whiteMat);
  letter8.name = 'letter';
  letter8.position.set(0.071, 0.066, 0.0165);
  sign.add(letter8);
  const letter9 = new THREE.Mesh(planeGeo, whiteMat);
  letter9.name = 'letter';
  letter9.position.set(0.071, -0.066, 0.0165);
  sign.add(letter9);
  const letter10 = new THREE.Mesh(planeGeo3, whiteMat);
  letter10.name = 'letter';
  letter10.position.set(0.0281, 0, 0.0165);
  sign.add(letter10);
  const letter11 = new THREE.Mesh(planeGeo3, whiteMat);
  letter11.name = 'letter';
  letter11.position.set(0.1139, 0, 0.0165);
  sign.add(letter11);
  const letter12 = new THREE.Mesh(new THREE.PlaneGeometry(0.033, 0.165), whiteMat);
  letter12.name = 'letter';
  letter12.position.set(0.17, 0, 0.0165);
  sign.add(letter12);
  const letter13 = new THREE.Mesh(planeGeo4, whiteMat);
  letter13.name = 'letter';
  letter13.position.set(0.2294, 0.066, 0.0165);
  sign.add(letter13);
  const letter14 = new THREE.Mesh(planeGeo4, whiteMat);
  letter14.name = 'letter';
  letter14.position.set(0.2294, -0.0066, 0.0165);
  sign.add(letter14);
  const letter15 = new THREE.Mesh(new THREE.PlaneGeometry(0.033, 0.0561), whiteMat);
  letter15.name = 'letter';
  letter15.position.set(0.2558, 0.038, 0.0165);
  sign.add(letter15);
  const bracket = new THREE.Mesh(boxGeo, darkMat);
  bracket.name = 'bracket';
  bracket.position.set(0, 2.035, 0.03);
  root.add(bracket);
  const clamp = new THREE.Mesh(boxGeo2, darkMat);
  clamp.name = 'clamp';
  clamp.position.set(0, 2.035, -0.035);
  root.add(clamp);
  const bracket2 = new THREE.Mesh(boxGeo, darkMat);
  bracket2.name = 'bracket';
  bracket2.position.set(0, 2.485, 0.03);
  root.add(bracket2);
  const clamp2 = new THREE.Mesh(boxGeo2, darkMat);
  clamp2.name = 'clamp';
  clamp2.position.set(0, 2.485, -0.035);
  root.add(clamp2);

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

export default createStopSign;

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