348 üçgen0,28 × 1,42 × 0,59 m
Kodda kullan
Editörde remix’lemailbox.js · 110 satır
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.
/**
* Mailbox — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 348 · Size (W × H × D): 0.28 × 1.42 × 0.58 m
*
* Usage:
* import { createMailbox } from './mailbox.js';
*
* const model = createMailbox();
* 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 createMailbox() {
const root = new THREE.Group();
root.name = 'Mailbox';
// Materials
const bodyMat = new THREE.MeshStandardMaterial({ name: 'body', color: 0xc23a2e, roughness: 0.5, metalness: 0.3, flatShading: true });
const woodMat = new THREE.MeshStandardMaterial({ name: 'wood', color: 0x8a6845, roughness: 0.9, flatShading: true });
const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x24282c, roughness: 0.6, metalness: 0.3, flatShading: true });
const flagMat = new THREE.MeshStandardMaterial({ name: 'flag', color: 0xf2c230, roughness: 0.6, flatShading: true });
// Shared geometries
const extrudeGeo = extrude([[-0.128, -0.008], [0.128, -0.008], [0.128, 0.13], [0.1217, 0.1696], [0.1036, 0.2052], [0.0752, 0.2336], [0.0396, 0.2517], [0, 0.258], [-0.0396, 0.2517], [-0.0752, 0.2336], [-0.1036, 0.2052], [-0.1217, 0.1696], [-0.128, 0.13]], 0.025);
// Parts
const post = new THREE.Mesh(new THREE.BoxGeometry(0.1, 1.02, 0.1), woodMat);
post.name = 'post';
post.position.set(0, 0.51, -0.02);
root.add(post);
const postCap = new THREE.Mesh(new THREE.BoxGeometry(0.16, 0.04, 0.16), woodMat);
postCap.name = 'postCap';
postCap.position.set(0, 1.03, -0.02);
root.add(postCap);
const board = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.04, 0.5), woodMat);
board.name = 'board';
board.position.set(0, 1.07, 0);
root.add(board);
const brace = new THREE.Mesh(new THREE.BoxGeometry(0.05, 0.3, 0.05), woodMat);
brace.name = 'brace';
brace.position.set(0, 0.885, 0.125);
brace.rotation.set(deg(40), 0, 0);
root.add(brace);
const body = new THREE.Mesh(extrude([[-0.12, 0], [0.12, 0], [0.12, 0.13], [0.1141, 0.1671], [0.0971, 0.2005], [0.0705, 0.2271], [0.0371, 0.2441], [0, 0.25], [-0.0371, 0.2441], [-0.0705, 0.2271], [-0.0971, 0.2005], [-0.1141, 0.1671], [-0.12, 0.13]], 0.48), bodyMat);
body.name = 'body';
body.position.set(0, 1.09, 0);
root.add(body);
const rib = new THREE.Mesh(extrudeGeo, bodyMat);
rib.name = 'rib';
rib.position.set(0, 1.09, -0.19);
root.add(rib);
const rib2 = new THREE.Mesh(extrudeGeo, bodyMat);
rib2.name = 'rib';
rib2.position.set(0, 1.09, 0.12);
root.add(rib2);
const door = new THREE.Mesh(extrude([[-0.132, -0.012], [0.132, -0.012], [0.132, 0.13], [0.1255, 0.1708], [0.1068, 0.2076], [0.0776, 0.2368], [0.0408, 0.2555], [0, 0.262], [-0.0408, 0.2555], [-0.0776, 0.2368], [-0.1068, 0.2076], [-0.1255, 0.1708], [-0.132, 0.13]], 0.025), bodyMat);
door.name = 'door';
door.position.set(0, 1.09, 0.25);
root.add(door);
const backCap = new THREE.Mesh(extrude([[-0.126, -0.006], [0.126, -0.006], [0.126, 0.13], [0.1198, 0.1689], [0.1019, 0.2041], [0.0741, 0.2319], [0.0389, 0.2498], [0, 0.256], [-0.0389, 0.2498], [-0.0741, 0.2319], [-0.1019, 0.2041], [-0.1198, 0.1689], [-0.126, 0.13]], 0.02), darkMat);
backCap.name = 'backCap';
backCap.position.set(0, 1.09, -0.245);
root.add(backCap);
const doorHandle = new THREE.Mesh(new THREE.BoxGeometry(0.05, 0.03, 0.05), darkMat);
doorHandle.name = 'doorHandle';
doorHandle.position.set(0, 1.32, 0.28);
root.add(doorHandle);
const flag = new THREE.Group();
flag.name = 'flag';
flag.position.set(0.14, 1.16, -0.14);
root.add(flag);
const flagArm = new THREE.Mesh(new THREE.BoxGeometry(0.018, 0.26, 0.03), flagMat);
flagArm.name = 'flagArm';
flagArm.position.set(0, 0.13, 0);
flag.add(flagArm);
const flagPlate = new THREE.Mesh(new THREE.BoxGeometry(0.018, 0.1, 0.14), flagMat);
flagPlate.name = 'flagPlate';
flagPlate.position.set(0, 0.21, -0.07);
flag.add(flagPlate);
const flagPivot = new THREE.Mesh(new THREE.CylinderGeometry(0.02, 0.02, 0.03, 6), darkMat);
flagPivot.name = 'flagPivot';
flagPivot.position.set(-0.012, 0, 0);
flagPivot.rotation.set(0, 0, deg(90));
flag.add(flagPivot);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createMailbox;
Puanlar ve yorumlar
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









