1116 Tris0,66 × 4,19 × 0,56 m
Im Code verwenden
Im Editor remixentraffic-light.js · 168 Zeilen
Eigenständiges ES-Modul — hängt nur von three ab. Ruf die Factory auf und füge die Gruppe deiner Szene hinzu.
/**
* Traffic Light — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 1,116 · Size (W × H × D): 0.66 × 4.19 × 0.56 m
*
* Usage:
* import { createTrafficLight } from './traffic-light.js';
*
* const model = createTrafficLight();
* 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 createTrafficLight() {
const root = new THREE.Group();
root.name = 'TrafficLight';
// Materials
const poleMat = new THREE.MeshStandardMaterial({ name: 'pole', color: 0x7d848b, roughness: 0.45, metalness: 0.6, flatShading: true });
const housingMat = new THREE.MeshStandardMaterial({ name: 'housing', color: 0x353b40, roughness: 0.6, metalness: 0.2, flatShading: true });
const plateMat = new THREE.MeshStandardMaterial({ name: 'plate', color: 0x1b1d1f, roughness: 0.7, flatShading: true });
const accentMat = new THREE.MeshStandardMaterial({ name: 'accent', color: 0xe3bd2c, roughness: 0.4, flatShading: true });
const redMat = new THREE.MeshStandardMaterial({ name: 'red', color: 0xff5a4a, roughness: 0.25, emissive: 0xff2a1a, emissiveIntensity: 1.3, flatShading: true });
const yellowMat = new THREE.MeshStandardMaterial({ name: 'yellow', color: 0x665219, roughness: 0.3, metalness: 0.1, flatShading: true });
const greenMat = new THREE.MeshStandardMaterial({ name: 'green', color: 0x1a5236, roughness: 0.3, metalness: 0.1, flatShading: true });
// Shared geometries
const cylinderGeo = new THREE.CylinderGeometry(0.018, 0.018, 0.035, 6);
const cylinderGeo2 = new THREE.CylinderGeometry(0.135, 0.135, 0.02, 12);
const sphereGeo = new THREE.SphereGeometry(0.115, 12, 6, 0, Math.PI * 2, 0, Math.PI / 2);
const extrudeGeo = extrude([[0.15, 0], [0.1386, 0.0574], [0.1061, 0.1061], [0.0574, 0.1386], [0, 0.15], [-0.0574, 0.1386], [-0.1061, 0.1061], [-0.1386, 0.0574], [-0.15, 0], [-0.128, 0], [-0.1183, 0.049], [-0.0905, 0.0905], [-0.049, 0.1183], [0, 0.128], [0.049, 0.1183], [0.0905, 0.0905], [0.1183, 0.049], [0.128, 0]], 0.2);
// Parts
const basePlate = new THREE.Mesh(new THREE.CylinderGeometry(0.2, 0.22, 0.04, 10), poleMat);
basePlate.name = 'basePlate';
basePlate.position.set(0, 0.02, 0);
root.add(basePlate);
const anchorBolt = new THREE.Mesh(cylinderGeo, plateMat);
anchorBolt.name = 'anchorBolt';
anchorBolt.position.set(0.1061, 0.0575, 0.1061);
root.add(anchorBolt);
const anchorBolt2 = new THREE.Mesh(cylinderGeo, plateMat);
anchorBolt2.name = 'anchorBolt';
anchorBolt2.position.set(0.1061, 0.0575, -0.1061);
root.add(anchorBolt2);
const anchorBolt3 = new THREE.Mesh(cylinderGeo, plateMat);
anchorBolt3.name = 'anchorBolt';
anchorBolt3.position.set(-0.1061, 0.0575, -0.1061);
root.add(anchorBolt3);
const anchorBolt4 = new THREE.Mesh(cylinderGeo, plateMat);
anchorBolt4.name = 'anchorBolt';
anchorBolt4.position.set(-0.1061, 0.0575, 0.1061);
root.add(anchorBolt4);
const poleBase = new THREE.Mesh(new THREE.CylinderGeometry(0.09, 0.1, 0.35, 10), poleMat);
poleBase.name = 'poleBase';
poleBase.position.set(0, 0.215, 0);
root.add(poleBase);
const pole = new THREE.Mesh(new THREE.CylinderGeometry(0.065, 0.08, 2.61, 10), poleMat);
pole.name = 'pole';
pole.position.set(0, 1.695, 0);
root.add(pole);
const poleCollar = new THREE.Mesh(new THREE.CylinderGeometry(0.085, 0.085, 0.06, 10), poleMat);
poleCollar.name = 'poleCollar';
poleCollar.position.set(0, 2.97, 0);
root.add(poleCollar);
const buttonBox = new THREE.Mesh(new THREE.BoxGeometry(0.12, 0.18, 0.08), housingMat);
buttonBox.name = 'buttonBox';
buttonBox.position.set(0, 1.1, 0.1);
root.add(buttonBox);
const pushButton = new THREE.Mesh(new THREE.CylinderGeometry(0.03, 0.03, 0.02, 8), accentMat);
pushButton.name = 'pushButton';
pushButton.position.set(0, 1.08, 0.145);
pushButton.rotation.set(deg(90), 0, 0);
root.add(pushButton);
const buttonSign = new THREE.Mesh(new THREE.BoxGeometry(0.08, 0.05, 0.012), plateMat);
buttonSign.name = 'buttonSign';
buttonSign.position.set(0, 1.15, 0.143);
root.add(buttonSign);
const mount = new THREE.Mesh(new THREE.BoxGeometry(0.14, 0.1, 0.14), housingMat);
mount.name = 'mount';
mount.position.set(0, 3.05, 0);
root.add(mount);
const signalHousing = new THREE.Mesh(new THREE.BoxGeometry(0.36, 1, 0.26), housingMat);
signalHousing.name = 'signalHousing';
signalHousing.position.set(0, 3.54, 0);
root.add(signalHousing);
const backplate = new THREE.Mesh(new THREE.BoxGeometry(0.62, 1.26, 0.025), plateMat);
backplate.name = 'backplate';
backplate.position.set(0, 3.54, -0.145);
root.add(backplate);
const backplateBorder = new THREE.Mesh(new THREE.BoxGeometry(0.66, 1.3, 0.012), accentMat);
backplateBorder.name = 'backplateBorder';
backplateBorder.position.set(0, 3.54, -0.161);
root.add(backplateBorder);
const housingCap = new THREE.Mesh(new THREE.BoxGeometry(0.4, 0.05, 0.3), housingMat);
housingCap.name = 'housingCap';
housingCap.position.set(0, 4.065, 0);
root.add(housingCap);
const lampRing = new THREE.Mesh(cylinderGeo2, plateMat);
lampRing.name = 'lampRing';
lampRing.position.set(0, 3.85, 0.138);
lampRing.rotation.set(deg(90), 0, 0);
root.add(lampRing);
const lens = new THREE.Mesh(sphereGeo, redMat);
lens.name = 'lens';
lens.position.set(0, 3.85, 0.142);
lens.rotation.set(deg(90), 0, 0);
lens.scale.set(1, 0.35, 1);
root.add(lens);
const visor = new THREE.Mesh(extrudeGeo, housingMat);
visor.name = 'visor';
visor.position.set(0, 3.85, 0.24);
root.add(visor);
const lampRing2 = new THREE.Mesh(cylinderGeo2, plateMat);
lampRing2.name = 'lampRing';
lampRing2.position.set(0, 3.54, 0.138);
lampRing2.rotation.set(deg(90), 0, 0);
root.add(lampRing2);
const lens2 = new THREE.Mesh(sphereGeo, yellowMat);
lens2.name = 'lens';
lens2.position.set(0, 3.54, 0.142);
lens2.rotation.set(deg(90), 0, 0);
lens2.scale.set(1, 0.35, 1);
root.add(lens2);
const visor2 = new THREE.Mesh(extrudeGeo, housingMat);
visor2.name = 'visor';
visor2.position.set(0, 3.54, 0.24);
root.add(visor2);
const lampRing3 = new THREE.Mesh(cylinderGeo2, plateMat);
lampRing3.name = 'lampRing';
lampRing3.position.set(0, 3.23, 0.138);
lampRing3.rotation.set(deg(90), 0, 0);
root.add(lampRing3);
const lens3 = new THREE.Mesh(sphereGeo, greenMat);
lens3.name = 'lens';
lens3.position.set(0, 3.23, 0.142);
lens3.rotation.set(deg(90), 0, 0);
lens3.scale.set(1, 0.35, 1);
root.add(lens3);
const visor3 = new THREE.Mesh(extrudeGeo, housingMat);
visor3.name = 'visor';
visor3.position.set(0, 3.23, 0.24);
root.add(visor3);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createTrafficLight;
Bewertungen & Kommentare
—
Noch keine Bewertungen — gib die erste ab.
5
0
4
0
3
0
2
0
1
0
Melde dich an, um zu bewerten und zu kommentieren.
0 Kommentare
Noch keine Kommentare. Erzähl, wie du dieses Modell genutzt hast oder was besser sein könnte.
Ähnliche Modelle
Gleiche Kategorie oder ähnliche Tags









