1,1 B üçgen7,50 × 2,02 × 2,32 m
Kodda kullan
Editörde remix’lewooden-bridge.js · 426 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.
/**
* Wooden Bridge — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 1,092 · Size (W × H × D): 7.50 × 2.02 × 2.32 m
*
* Usage:
* import { createWoodenBridge } from './wooden-bridge.js';
*
* const model = createWoodenBridge();
* model.position.set(0, 0, 0);
* scene.add(model);
*/
import * as THREE from 'three';
const deg = THREE.MathUtils.degToRad;
// Deterministic vertex displacement (organic low-poly look).
function jitter(geometry, amount, seed) {
const pos = geometry.attributes.position;
const h = (a, b, c, s) => {
let x = Math.imul(a, 73856093) ^ Math.imul(b, 19349663) ^ Math.imul(c, 83492791) ^ Math.imul(s, 2654435761);
x = Math.imul(x ^ (x >>> 16), 2246822507);
x = Math.imul(x ^ (x >>> 13), 3266489909);
return ((x ^ (x >>> 16)) >>> 0) / 4294967295 - 0.5;
};
for (let i = 0; i < pos.count; i++) {
const x = pos.getX(i), y = pos.getY(i), z = pos.getZ(i);
const qx = Math.round(x * 1000), qy = Math.round(y * 1000), qz = Math.round(z * 1000);
pos.setXYZ(i, x + h(qx, qy, qz, seed) * 2 * amount, y + h(qx, qy, qz, seed + 1) * 2 * amount, z + h(qx, qy, qz, seed + 2) * 2 * amount);
}
pos.needsUpdate = true;
geometry.computeVertexNormals();
return geometry;
}
// Tube along a smooth curve through the given points.
function tube(path, radius, tubularSegments, radialSegments, closed = false) {
const curve = new THREE.CatmullRomCurve3(path.map(([x, y, z]) => new THREE.Vector3(x, y, z)), closed);
return new THREE.TubeGeometry(curve, tubularSegments, radius, radialSegments, closed);
}
export function createWoodenBridge() {
const root = new THREE.Group();
root.name = 'WoodenBridge';
// Materials
const plankMat = new THREE.MeshStandardMaterial({ name: 'plank', color: 0xa5743f, roughness: 0.9, flatShading: true });
const plank2Mat = new THREE.MeshStandardMaterial({ name: 'plank2', color: 0x8c6033, roughness: 0.9, flatShading: true });
const beamMat = new THREE.MeshStandardMaterial({ name: 'beam', color: 0x6a4528, roughness: 0.95, flatShading: true });
const stoneMat = new THREE.MeshStandardMaterial({ name: 'stone', color: 0x75706a, roughness: 0.95, flatShading: true });
// Shared geometries
const boxGeo = new THREE.BoxGeometry(0.12, 1.2583, 0.12);
const boxGeo2 = new THREE.BoxGeometry(0.215, 0.07, 1.7838);
const boxGeo3 = new THREE.BoxGeometry(0.15, 1.32, 0.15);
const cylinderGeo = new THREE.CylinderGeometry(0, 0.1125, 0.12, 4);
const boxGeo4 = new THREE.BoxGeometry(0.1, 1.2, 0.1);
const boxGeo5 = new THREE.BoxGeometry(0.07, 1.4817, 0.1);
const boxGeo6 = new THREE.BoxGeometry(0.05, 1.4817, 0.05);
const boxGeo7 = new THREE.BoxGeometry(0.04, 1.6323, 0.04);
const boxGeo8 = new THREE.BoxGeometry(0.07, 1.4314, 0.1);
const boxGeo9 = new THREE.BoxGeometry(0.05, 1.4314, 0.05);
const boxGeo10 = new THREE.BoxGeometry(0.04, 1.5188, 0.04);
const boxGeo11 = new THREE.BoxGeometry(0.04, 1.4476, 0.04);
const boxGeo12 = new THREE.BoxGeometry(0.04, 1.4251, 0.04);
// Parts
const abutment = new THREE.Mesh(jitter(new THREE.BoxGeometry(1, 0.32, 2.3), 0.015, 3), stoneMat);
abutment.name = 'abutment';
abutment.position.set(-2.75, 0.172, 0);
root.add(abutment);
const abutmentStep = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.6, 0.17, 2.1), 0.015, 5), stoneMat);
abutmentStep.name = 'abutmentStep';
abutmentStep.position.set(-3.45, 0.097, 0);
root.add(abutmentStep);
const abutment2 = new THREE.Mesh(jitter(new THREE.BoxGeometry(1, 0.32, 2.3), 0.015, 2), stoneMat);
abutment2.name = 'abutment';
abutment2.position.set(2.75, 0.172, 0);
root.add(abutment2);
const abutmentStep2 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.6, 0.17, 2.1), 0.015, 4), stoneMat);
abutmentStep2.name = 'abutmentStep';
abutmentStep2.position.set(3.45, 0.097, 0);
root.add(abutmentStep2);
const stringer = new THREE.Mesh(tube([[-2.95, 0.2698, -0.72], [-2.2125, 0.5237, -0.72], [-1.475, 0.705, -0.72], [-0.7375, 0.8137, -0.72], [0, 0.85, -0.72], [0.7375, 0.8137, -0.72], [1.475, 0.705, -0.72], [2.2125, 0.5237, -0.72], [2.95, 0.2698, -0.72]], 0.1, 16, 4), beamMat);
stringer.name = 'stringer';
root.add(stringer);
const stringer2 = new THREE.Mesh(tube([[-2.95, 0.2698, 0.72], [-2.2125, 0.5237, 0.72], [-1.475, 0.705, 0.72], [-0.7375, 0.8137, 0.72], [0, 0.85, 0.72], [0.7375, 0.8137, 0.72], [1.475, 0.705, 0.72], [2.2125, 0.5237, 0.72], [2.95, 0.2698, 0.72]], 0.1, 16, 4), beamMat);
stringer2.name = 'stringer';
root.add(stringer2);
const strut = new THREE.Mesh(boxGeo, beamMat);
strut.name = 'strut';
strut.position.set(-1.95, 0.4893, -0.72);
strut.rotation.set(0, deg(180), deg(72.4939));
root.add(strut);
const strut2 = new THREE.Mesh(boxGeo, beamMat);
strut2.name = 'strut';
strut2.position.set(-1.95, 0.4893, 0.72);
strut2.rotation.set(0, deg(180), deg(72.4939));
root.add(strut2);
const strut3 = new THREE.Mesh(boxGeo, beamMat);
strut3.name = 'strut';
strut3.position.set(1.95, 0.4893, -0.72);
strut3.rotation.set(0, 0, deg(72.4939));
root.add(strut3);
const strut4 = new THREE.Mesh(boxGeo, beamMat);
strut4.name = 'strut';
strut4.position.set(1.95, 0.4893, 0.72);
strut4.rotation.set(0, 0, deg(72.4939));
root.add(strut4);
const plank = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.808), plankMat);
plank.name = 'plank';
plank.position.set(-2.88, 0.4269, -0.0271);
plank.rotation.set(0, deg(-1.1117), deg(21.0068));
root.add(plank);
const plank2 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7408), plank2Mat);
plank2.name = 'plank';
plank2.position.set(-2.64, 0.5186, 0.0035);
plank2.rotation.set(0, deg(0.8894), deg(19.3921));
root.add(plank2);
const plank3 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8187), plankMat);
plank3.name = 'plank';
plank3.position.set(-2.4, 0.5985, -0.02);
plank3.rotation.set(0, deg(0.1457), deg(17.7447));
root.add(plank3);
const plank4 = new THREE.Mesh(boxGeo2, plankMat);
plank4.name = 'plank';
plank4.position.set(-2.16, 0.6753, -0.0226);
plank4.rotation.set(0, deg(0.3515), deg(16.0664));
root.add(plank4);
const plank5 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7921), plankMat);
plank5.name = 'plank';
plank5.position.set(-1.92, 0.7373, -0.0238);
plank5.rotation.set(0, deg(0.59), deg(14.3593));
root.add(plank5);
const plank6 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7884), plank2Mat);
plank6.name = 'plank';
plank6.position.set(-1.68, 0.7946, -0.0276);
plank6.rotation.set(0, deg(-1.0527), deg(12.6258));
root.add(plank6);
const plank7 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7747), plankMat);
plank7.name = 'plank';
plank7.position.set(-1.44, 0.8451, 0.0135);
plank7.rotation.set(0, deg(-0.671), deg(10.8685));
root.add(plank7);
const plank8 = new THREE.Mesh(boxGeo2, plank2Mat);
plank8.name = 'plank';
plank8.position.set(-1.2, 0.8914, -0.0289);
plank8.rotation.set(0, deg(0.0716), deg(9.0903));
root.add(plank8);
const plank9 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7499), plank2Mat);
plank9.name = 'plank';
plank9.position.set(-0.96, 0.9225, -0.0229);
plank9.rotation.set(0, deg(-0.7878), deg(7.2942));
root.add(plank9);
const plank10 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7715), plankMat);
plank10.name = 'plank';
plank10.position.set(-0.72, 0.9458, -0.0198);
plank10.rotation.set(0, deg(0.6217), deg(5.4836));
root.add(plank10);
const plank11 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7592), plank2Mat);
plank11.name = 'plank';
plank11.position.set(-0.48, 0.9668, 0.024);
plank11.rotation.set(0, deg(1.1897), deg(3.6619));
root.add(plank11);
const plank12 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8319), plank2Mat);
plank12.name = 'plank';
plank12.position.set(-0.24, 0.9797, -0.0272);
plank12.rotation.set(0, deg(0.6687), deg(1.8328));
root.add(plank12);
const plank13 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7579), plank2Mat);
plank13.name = 'plank';
plank13.position.set(0, 0.9807, 0.0118);
plank13.rotation.set(0, deg(0.7961), 0);
root.add(plank13);
const plank14 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8561), plankMat);
plank14.name = 'plank';
plank14.position.set(0.24, 0.98, 0.0118);
plank14.rotation.set(0, deg(0.9706), deg(-1.8328));
root.add(plank14);
const plank15 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8171), plankMat);
plank15.name = 'plank';
plank15.position.set(0.48, 0.9722, 0.0254);
plank15.rotation.set(0, deg(0.0885), deg(-3.6619));
root.add(plank15);
const plank16 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8331), plankMat);
plank16.name = 'plank';
plank16.position.set(0.72, 0.9546, -0.0138);
plank16.rotation.set(0, deg(0.352), deg(-5.4836));
root.add(plank16);
const plank17 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.765), plankMat);
plank17.name = 'plank';
plank17.position.set(0.96, 0.9251, -0.0058);
plank17.rotation.set(0, deg(-0.9303), deg(-7.2942));
root.add(plank17);
const plank18 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7487), plankMat);
plank18.name = 'plank';
plank18.position.set(1.2, 0.8844, 0.0256);
plank18.rotation.set(0, deg(0.6926), deg(-9.0903));
root.add(plank18);
const plank19 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7831), plankMat);
plank19.name = 'plank';
plank19.position.set(1.44, 0.8516, -0.0212);
plank19.rotation.set(0, deg(-0.3655), deg(-10.8685));
root.add(plank19);
const plank20 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.7563), plankMat);
plank20.name = 'plank';
plank20.position.set(1.68, 0.7948, -0.0075);
plank20.rotation.set(0, deg(-0.7818), deg(-12.6258));
root.add(plank20);
const plank21 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8151), plankMat);
plank21.name = 'plank';
plank21.position.set(1.92, 0.7371, 0.0206);
plank21.rotation.set(0, deg(1.103), deg(-14.3593));
root.add(plank21);
const plank22 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8089), plank2Mat);
plank22.name = 'plank';
plank22.position.set(2.16, 0.6691, 0.0004);
plank22.rotation.set(0, deg(-0.7146), deg(-16.0664));
root.add(plank22);
const plank23 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8411), plankMat);
plank23.name = 'plank';
plank23.position.set(2.4, 0.6054, 0.0152);
plank23.rotation.set(0, deg(0.9122), deg(-17.7447));
root.add(plank23);
const plank24 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.8455), plank2Mat);
plank24.name = 'plank';
plank24.position.set(2.64, 0.5249, 0.0147);
plank24.rotation.set(0, deg(-1.0455), deg(-19.3921));
root.add(plank24);
const plank25 = new THREE.Mesh(new THREE.BoxGeometry(0.215, 0.07, 1.754), plank2Mat);
plank25.name = 'plank';
plank25.position.set(2.88, 0.4358, -0.021);
plank25.rotation.set(0, deg(-0.3847), deg(-21.0068));
root.add(plank25);
const endPost = new THREE.Mesh(boxGeo3, beamMat);
endPost.name = 'endPost';
endPost.position.set(-2.85, 0.9385, -0.88);
root.add(endPost);
const postCap = new THREE.Mesh(cylinderGeo, beamMat);
postCap.name = 'postCap';
postCap.position.set(-2.85, 1.6585, -0.88);
postCap.rotation.set(0, deg(45), 0);
root.add(postCap);
const post = new THREE.Mesh(boxGeo4, beamMat);
post.name = 'post';
post.position.set(-1.425, 1.2846, -0.88);
root.add(post);
const post2 = new THREE.Mesh(boxGeo4, beamMat);
post2.name = 'post';
post2.position.set(0, 1.42, -0.88);
root.add(post2);
const post3 = new THREE.Mesh(boxGeo4, beamMat);
post3.name = 'post';
post3.position.set(1.425, 1.2846, -0.88);
root.add(post3);
const endPost2 = new THREE.Mesh(boxGeo3, beamMat);
endPost2.name = 'endPost';
endPost2.position.set(2.85, 0.9385, -0.88);
root.add(endPost2);
const postCap2 = new THREE.Mesh(cylinderGeo, beamMat);
postCap2.name = 'postCap';
postCap2.position.set(2.85, 1.6585, -0.88);
postCap2.rotation.set(0, deg(45), 0);
root.add(postCap2);
const handrail = new THREE.Mesh(boxGeo5, plankMat);
handrail.name = 'handrail';
handrail.position.set(-2.1375, 1.6316, -0.88);
handrail.rotation.set(0, deg(180), deg(74.0924));
root.add(handrail);
const midRail = new THREE.Mesh(boxGeo6, plank2Mat);
midRail.name = 'midRail';
midRail.position.set(-2.1375, 1.1816, -0.88);
midRail.rotation.set(0, deg(180), deg(74.0924));
root.add(midRail);
const infill = new THREE.Mesh(boxGeo7, beamMat);
infill.name = 'infill';
infill.position.set(-2.1375, 0.9566, -0.88);
infill.rotation.set(0, deg(180), deg(60.8086));
root.add(infill);
const handrail2 = new THREE.Mesh(boxGeo8, plankMat);
handrail2.name = 'handrail';
handrail2.position.set(-0.7125, 1.9023, -0.88);
handrail2.rotation.set(0, deg(180), deg(84.5732));
root.add(handrail2);
const midRail2 = new THREE.Mesh(boxGeo9, plank2Mat);
midRail2.name = 'midRail';
midRail2.position.set(-0.7125, 1.4523, -0.88);
midRail2.rotation.set(0, deg(180), deg(84.5732));
root.add(midRail2);
const infill2 = new THREE.Mesh(boxGeo10, beamMat);
infill2.name = 'infill';
infill2.position.set(-0.7125, 1.2273, -0.88);
infill2.rotation.set(0, deg(180), deg(69.7619));
root.add(infill2);
const handrail3 = new THREE.Mesh(boxGeo8, plankMat);
handrail3.name = 'handrail';
handrail3.position.set(0.7125, 1.9023, -0.88);
handrail3.rotation.set(0, deg(180), deg(95.4268));
root.add(handrail3);
const midRail3 = new THREE.Mesh(boxGeo9, plank2Mat);
midRail3.name = 'midRail';
midRail3.position.set(0.7125, 1.4523, -0.88);
midRail3.rotation.set(0, deg(180), deg(95.4268));
root.add(midRail3);
const infill3 = new THREE.Mesh(boxGeo11, beamMat);
infill3.name = 'infill';
infill3.position.set(0.7125, 1.2273, -0.88);
infill3.rotation.set(0, deg(180), deg(79.8691));
root.add(infill3);
const handrail4 = new THREE.Mesh(boxGeo5, plankMat);
handrail4.name = 'handrail';
handrail4.position.set(2.1375, 1.6316, -0.88);
handrail4.rotation.set(0, deg(180), deg(105.9076));
root.add(handrail4);
const midRail4 = new THREE.Mesh(boxGeo6, plank2Mat);
midRail4.name = 'midRail';
midRail4.position.set(2.1375, 1.1816, -0.88);
midRail4.rotation.set(0, deg(180), deg(105.9076));
root.add(midRail4);
const infill4 = new THREE.Mesh(boxGeo12, beamMat);
infill4.name = 'infill';
infill4.position.set(2.1375, 0.9566, -0.88);
infill4.rotation.set(0, deg(180), deg(90.6483));
root.add(infill4);
const endPost3 = new THREE.Mesh(boxGeo3, beamMat);
endPost3.name = 'endPost';
endPost3.position.set(-2.85, 0.9385, 0.88);
root.add(endPost3);
const postCap3 = new THREE.Mesh(cylinderGeo, beamMat);
postCap3.name = 'postCap';
postCap3.position.set(-2.85, 1.6585, 0.88);
postCap3.rotation.set(0, deg(45), 0);
root.add(postCap3);
const post4 = new THREE.Mesh(boxGeo4, beamMat);
post4.name = 'post';
post4.position.set(-1.425, 1.2846, 0.88);
root.add(post4);
const post5 = new THREE.Mesh(boxGeo4, beamMat);
post5.name = 'post';
post5.position.set(0, 1.42, 0.88);
root.add(post5);
const post6 = new THREE.Mesh(boxGeo4, beamMat);
post6.name = 'post';
post6.position.set(1.425, 1.2846, 0.88);
root.add(post6);
const endPost4 = new THREE.Mesh(boxGeo3, beamMat);
endPost4.name = 'endPost';
endPost4.position.set(2.85, 0.9385, 0.88);
root.add(endPost4);
const postCap4 = new THREE.Mesh(cylinderGeo, beamMat);
postCap4.name = 'postCap';
postCap4.position.set(2.85, 1.6585, 0.88);
postCap4.rotation.set(0, deg(45), 0);
root.add(postCap4);
const handrail5 = new THREE.Mesh(boxGeo5, plankMat);
handrail5.name = 'handrail';
handrail5.position.set(-2.1375, 1.6316, 0.88);
handrail5.rotation.set(0, deg(180), deg(74.0924));
root.add(handrail5);
const midRail5 = new THREE.Mesh(boxGeo6, plank2Mat);
midRail5.name = 'midRail';
midRail5.position.set(-2.1375, 1.1816, 0.88);
midRail5.rotation.set(0, deg(180), deg(74.0924));
root.add(midRail5);
const infill5 = new THREE.Mesh(boxGeo7, beamMat);
infill5.name = 'infill';
infill5.position.set(-2.1375, 0.9566, 0.88);
infill5.rotation.set(0, deg(180), deg(60.8086));
root.add(infill5);
const handrail6 = new THREE.Mesh(boxGeo8, plankMat);
handrail6.name = 'handrail';
handrail6.position.set(-0.7125, 1.9023, 0.88);
handrail6.rotation.set(0, deg(180), deg(84.5732));
root.add(handrail6);
const midRail6 = new THREE.Mesh(boxGeo9, plank2Mat);
midRail6.name = 'midRail';
midRail6.position.set(-0.7125, 1.4523, 0.88);
midRail6.rotation.set(0, deg(180), deg(84.5732));
root.add(midRail6);
const infill6 = new THREE.Mesh(boxGeo10, beamMat);
infill6.name = 'infill';
infill6.position.set(-0.7125, 1.2273, 0.88);
infill6.rotation.set(0, deg(180), deg(69.7619));
root.add(infill6);
const handrail7 = new THREE.Mesh(boxGeo8, plankMat);
handrail7.name = 'handrail';
handrail7.position.set(0.7125, 1.9023, 0.88);
handrail7.rotation.set(0, deg(180), deg(95.4268));
root.add(handrail7);
const midRail7 = new THREE.Mesh(boxGeo9, plank2Mat);
midRail7.name = 'midRail';
midRail7.position.set(0.7125, 1.4523, 0.88);
midRail7.rotation.set(0, deg(180), deg(95.4268));
root.add(midRail7);
const infill7 = new THREE.Mesh(boxGeo11, beamMat);
infill7.name = 'infill';
infill7.position.set(0.7125, 1.2273, 0.88);
infill7.rotation.set(0, deg(180), deg(79.8691));
root.add(infill7);
const handrail8 = new THREE.Mesh(boxGeo5, plankMat);
handrail8.name = 'handrail';
handrail8.position.set(2.1375, 1.6316, 0.88);
handrail8.rotation.set(0, deg(180), deg(105.9076));
root.add(handrail8);
const midRail8 = new THREE.Mesh(boxGeo6, plank2Mat);
midRail8.name = 'midRail';
midRail8.position.set(2.1375, 1.1816, 0.88);
midRail8.rotation.set(0, deg(180), deg(105.9076));
root.add(midRail8);
const infill8 = new THREE.Mesh(boxGeo12, beamMat);
infill8.name = 'infill';
infill8.position.set(2.1375, 0.9566, 0.88);
infill8.rotation.set(0, deg(180), deg(90.6483));
root.add(infill8);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createWoodenBridge;
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









