1,2 mil tris2,13 × 1,18 × 1,27 m
Úsalo en código
Hacer remix en el editorbridge-plank.js · 235 líneas
Módulo ES autónomo — solo depende de three. Llama a la función factory y añade el grupo a tu escena.
/**
* Bridge Plank Segment — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 1,168 · Size (W × H × D): 2.13 × 1.18 × 1.27 m
*
* Usage:
* import { createBridgePlank } from './bridge-plank.js';
*
* const model = createBridgePlank();
* model.position.set(0, 0, 0);
* scene.add(model);
*/
import * as THREE from 'three';
const deg = THREE.MathUtils.degToRad;
// 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 createBridgePlank() {
const root = new THREE.Group();
root.name = 'BridgePlank';
// Materials
const plankMat = new THREE.MeshStandardMaterial({ name: 'plank', color: 0xa8743f, roughness: 0.9, flatShading: true });
const plankAltMat = new THREE.MeshStandardMaterial({ name: 'plankAlt', color: 0x906436, roughness: 0.9, flatShading: true });
const ropeMat = new THREE.MeshStandardMaterial({ name: 'rope', color: 0xd2b07a, roughness: 1, flatShading: true });
const knotMat = new THREE.MeshStandardMaterial({ name: 'knot', color: 0x9c7a46, roughness: 1, flatShading: true });
const postMat = new THREE.MeshStandardMaterial({ name: 'post', color: 0x76512c, roughness: 0.9, flatShading: true });
// Shared geometries
const cylinderGeo = new THREE.CylinderGeometry(0.028, 0.028, 2, 6);
const boxGeo = new THREE.BoxGeometry(0.22, 0.02, 0.07);
const cylinderGeo2 = new THREE.CylinderGeometry(0.013, 0.013, 0.8309, 5);
const sphereGeo = new THREE.SphereGeometry(0.03, 6, 4);
const cylinderGeo3 = new THREE.CylinderGeometry(0.013, 0.013, 0.7915, 5);
const cylinderGeo4 = new THREE.CylinderGeometry(0.06, 0.07, 1.1, 6);
const coneGeo = new THREE.ConeGeometry(0.07, 0.08, 6);
const cylinderGeo5 = new THREE.CylinderGeometry(0.075, 0.075, 0.07, 6);
// Parts
const deckRopeBack = new THREE.Mesh(cylinderGeo, ropeMat);
deckRopeBack.name = 'deckRopeBack';
deckRopeBack.position.set(0, 0.028, -0.4);
deckRopeBack.rotation.set(0, 0, deg(90));
root.add(deckRopeBack);
const deckRopeFront = new THREE.Mesh(cylinderGeo, ropeMat);
deckRopeFront.name = 'deckRopeFront';
deckRopeFront.position.set(0, 0.028, 0.4);
deckRopeFront.rotation.set(0, 0, deg(90));
root.add(deckRopeFront);
const planks = new THREE.Group();
planks.name = 'planks';
root.add(planks);
const plank1 = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.06, 1.0024), plankMat);
plank1.name = 'plank1';
plank1.position.set(-0.8747, 0.086, 0.0036);
plank1.rotation.set(0, deg(0.6487), deg(1.0523));
planks.add(plank1);
const plank2 = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.06, 0.9664), plankAltMat);
plank2.name = 'plank2';
plank2.position.set(-0.6241, 0.086, 0.0043);
plank2.rotation.set(0, deg(0.183), deg(-0.149));
planks.add(plank2);
const plank3 = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.06, 1.0275), plankMat);
plank3.name = 'plank3';
plank3.position.set(-0.3755, 0.086, 0.0068);
plank3.rotation.set(0, deg(-0.4801), deg(0.5446));
planks.add(plank3);
const plank4 = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.06, 0.9743), plankMat);
plank4.name = 'plank4';
plank4.position.set(-0.1331, 0.086, -0.0042);
plank4.rotation.set(0, deg(-1.3434), deg(-0.3691));
planks.add(plank4);
const plank5 = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.06, 0.9702), plankAltMat);
plank5.name = 'plank5';
plank5.position.set(0.127, 0.086, 0.0031);
plank5.rotation.set(0, deg(0.5825), deg(-0.2447));
planks.add(plank5);
const plank6 = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.06, 1.0244), plankMat);
plank6.name = 'plank6';
plank6.position.set(0.3833, 0.086, -0.0073);
plank6.rotation.set(0, deg(1.6128), deg(0.3693));
planks.add(plank6);
const plank7 = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.06, 0.9645), plankMat);
plank7.name = 'plank7';
plank7.position.set(0.619, 0.086, 0.0191);
plank7.rotation.set(0, deg(1.4455), deg(-0.6095));
planks.add(plank7);
const plank8 = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.06, 1.0195), plankAltMat);
plank8.name = 'plank8';
plank8.position.set(0.8665, 0.086, 0.0021);
plank8.rotation.set(0, deg(-0.9167), deg(0.23));
planks.add(plank8);
const box12 = new THREE.Mesh(boxGeo, knotMat);
box12.position.set(-0.875, 0.126, -0.4);
root.add(box12);
const box13 = new THREE.Mesh(boxGeo, knotMat);
box13.position.set(-0.875, 0.126, 0.4);
root.add(box13);
const box14 = new THREE.Mesh(boxGeo, knotMat);
box14.position.set(-0.375, 0.126, -0.4);
root.add(box14);
const box15 = new THREE.Mesh(boxGeo, knotMat);
box15.position.set(-0.375, 0.126, 0.4);
root.add(box15);
const box16 = new THREE.Mesh(boxGeo, knotMat);
box16.position.set(0.125, 0.126, -0.4);
root.add(box16);
const box17 = new THREE.Mesh(boxGeo, knotMat);
box17.position.set(0.125, 0.126, 0.4);
root.add(box17);
const box18 = new THREE.Mesh(boxGeo, knotMat);
box18.position.set(0.625, 0.126, -0.4);
root.add(box18);
const box19 = new THREE.Mesh(boxGeo, knotMat);
box19.position.set(0.625, 0.126, 0.4);
root.add(box19);
const handRopeBack = new THREE.Mesh(tube([[-1, 0.92, -0.56], [-0.5, 0.86, -0.56], [0, 0.84, -0.56], [0.5, 0.86, -0.56], [1, 0.92, -0.56]], 0.022, 12, 5), ropeMat);
handRopeBack.name = 'handRopeBack';
root.add(handRopeBack);
const cylinder21 = new THREE.Mesh(cylinderGeo2, ropeMat);
cylinder21.position.set(-0.75, 0.4755, -0.49);
cylinder21.rotation.set(deg(-9.7004), 0, 0);
root.add(cylinder21);
const sphere22 = new THREE.Mesh(sphereGeo, knotMat);
sphere22.position.set(-0.75, 0.885, -0.56);
root.add(sphere22);
const cylinder23 = new THREE.Mesh(cylinderGeo3, ropeMat);
cylinder23.position.set(-0.25, 0.4555, -0.49);
cylinder23.rotation.set(deg(-10.1883), 0, 0);
root.add(cylinder23);
const sphere24 = new THREE.Mesh(sphereGeo, knotMat);
sphere24.position.set(-0.25, 0.845, -0.56);
root.add(sphere24);
const cylinder25 = new THREE.Mesh(cylinderGeo3, ropeMat);
cylinder25.position.set(0.25, 0.4555, -0.49);
cylinder25.rotation.set(deg(-10.1883), 0, 0);
root.add(cylinder25);
const sphere26 = new THREE.Mesh(sphereGeo, knotMat);
sphere26.position.set(0.25, 0.845, -0.56);
root.add(sphere26);
const cylinder27 = new THREE.Mesh(cylinderGeo2, ropeMat);
cylinder27.position.set(0.75, 0.4755, -0.49);
cylinder27.rotation.set(deg(-9.7004), 0, 0);
root.add(cylinder27);
const sphere28 = new THREE.Mesh(sphereGeo, knotMat);
sphere28.position.set(0.75, 0.885, -0.56);
root.add(sphere28);
const handRopeFront = new THREE.Mesh(tube([[-1, 0.92, 0.56], [-0.5, 0.86, 0.56], [0, 0.84, 0.56], [0.5, 0.86, 0.56], [1, 0.92, 0.56]], 0.022, 12, 5), ropeMat);
handRopeFront.name = 'handRopeFront';
root.add(handRopeFront);
const cylinder30 = new THREE.Mesh(cylinderGeo2, ropeMat);
cylinder30.position.set(-0.75, 0.4755, 0.49);
cylinder30.rotation.set(deg(9.7004), 0, 0);
root.add(cylinder30);
const sphere31 = new THREE.Mesh(sphereGeo, knotMat);
sphere31.position.set(-0.75, 0.885, 0.56);
root.add(sphere31);
const cylinder32 = new THREE.Mesh(cylinderGeo3, ropeMat);
cylinder32.position.set(-0.25, 0.4555, 0.49);
cylinder32.rotation.set(deg(10.1883), 0, 0);
root.add(cylinder32);
const sphere33 = new THREE.Mesh(sphereGeo, knotMat);
sphere33.position.set(-0.25, 0.845, 0.56);
root.add(sphere33);
const cylinder34 = new THREE.Mesh(cylinderGeo3, ropeMat);
cylinder34.position.set(0.25, 0.4555, 0.49);
cylinder34.rotation.set(deg(10.1883), 0, 0);
root.add(cylinder34);
const sphere35 = new THREE.Mesh(sphereGeo, knotMat);
sphere35.position.set(0.25, 0.845, 0.56);
root.add(sphere35);
const cylinder36 = new THREE.Mesh(cylinderGeo2, ropeMat);
cylinder36.position.set(0.75, 0.4755, 0.49);
cylinder36.rotation.set(deg(9.7004), 0, 0);
root.add(cylinder36);
const sphere37 = new THREE.Mesh(sphereGeo, knotMat);
sphere37.position.set(0.75, 0.885, 0.56);
root.add(sphere37);
const postLBack = new THREE.Mesh(cylinderGeo4, postMat);
postLBack.name = 'postLBack';
postLBack.position.set(-1, 0.55, -0.56);
root.add(postLBack);
const cone39 = new THREE.Mesh(coneGeo, postMat);
cone39.position.set(-1, 1.14, -0.56);
root.add(cone39);
const cylinder40 = new THREE.Mesh(cylinderGeo5, ropeMat);
cylinder40.position.set(-1, 0.92, -0.56);
root.add(cylinder40);
const postLFront = new THREE.Mesh(cylinderGeo4, postMat);
postLFront.name = 'postLFront';
postLFront.position.set(-1, 0.55, 0.56);
root.add(postLFront);
const cone42 = new THREE.Mesh(coneGeo, postMat);
cone42.position.set(-1, 1.14, 0.56);
root.add(cone42);
const cylinder43 = new THREE.Mesh(cylinderGeo5, ropeMat);
cylinder43.position.set(-1, 0.92, 0.56);
root.add(cylinder43);
const postRBack = new THREE.Mesh(cylinderGeo4, postMat);
postRBack.name = 'postRBack';
postRBack.position.set(1, 0.55, -0.56);
root.add(postRBack);
const cone45 = new THREE.Mesh(coneGeo, postMat);
cone45.position.set(1, 1.14, -0.56);
root.add(cone45);
const cylinder46 = new THREE.Mesh(cylinderGeo5, ropeMat);
cylinder46.position.set(1, 0.92, -0.56);
root.add(cylinder46);
const postRFront = new THREE.Mesh(cylinderGeo4, postMat);
postRFront.name = 'postRFront';
postRFront.position.set(1, 0.55, 0.56);
root.add(postRFront);
const cone48 = new THREE.Mesh(coneGeo, postMat);
cone48.position.set(1, 1.14, 0.56);
root.add(cone48);
const cylinder49 = new THREE.Mesh(cylinderGeo5, ropeMat);
cylinder49.position.set(1, 0.92, 0.56);
root.add(cylinder49);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createBridgePlank;
Valoraciones y comentarios
0 comentarios
Aún no hay comentarios. Cuenta cómo usaste este modelo o qué se podría mejorar.
Modelos relacionados
Misma categoría o etiquetas similares









