300 треуг.0,44 × 0,96 × 0,41 m
Использовать в коде
Ремикс в редактореwooden-chair.js · 152 строки
Самодостаточный ES-модуль — зависит только от three. Вызовите фабрику и добавьте группу в сцену.
/**
* Wooden Chair — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 300 · Size (W × H × D): 0.44 × 0.95 × 0.41 m
*
* Usage:
* import { createWoodenChair } from './wooden-chair.js';
*
* const model = createWoodenChair();
* 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 createWoodenChair() {
const root = new THREE.Group();
root.name = 'WoodenChair';
// Materials
const plankMat = new THREE.MeshStandardMaterial({ name: 'plank', color: 0xa5693a, roughness: 0.85, flatShading: true });
const plankAltMat = new THREE.MeshStandardMaterial({ name: 'plankAlt', color: 0xb97641, roughness: 0.85, flatShading: true });
const frameMat = new THREE.MeshStandardMaterial({ name: 'frame', color: 0x774c2a, roughness: 0.9, flatShading: true });
const trimMat = new THREE.MeshStandardMaterial({ name: 'trim', color: 0x915c33, roughness: 0.85, flatShading: true });
const underMat = new THREE.MeshStandardMaterial({ name: 'under', color: 0x422a17, roughness: 1, flatShading: true });
// Shared geometries
const boxGeo = new THREE.BoxGeometry(0.44, 0.04, 0.133);
const cylinderGeo = new THREE.CylinderGeometry(0.0318, 0.0255, 0.394, 4);
const boxGeo2 = new THREE.BoxGeometry(0.045, 0.92, 0.045);
const cylinderGeo2 = new THREE.CylinderGeometry(0.012, 0.0225, 0.035, 4);
const boxGeo3 = new THREE.BoxGeometry(0.371, 0.06, 0.02);
const boxGeo4 = new THREE.BoxGeometry(0.02, 0.06, 0.35);
const boxGeo5 = new THREE.BoxGeometry(0.024, 0.024, 0.35);
const boxGeo6 = new THREE.BoxGeometry(0.055, 0.235, 0.016);
// Parts
const seatPlank = new THREE.Mesh(boxGeo, plankMat);
seatPlank.name = 'seatPlank';
seatPlank.position.set(0, 0.43, -0.14);
root.add(seatPlank);
const seatPlank2 = new THREE.Mesh(boxGeo, plankAltMat);
seatPlank2.name = 'seatPlank';
seatPlank2.position.set(0, 0.43, 0);
root.add(seatPlank2);
const seatPlank3 = new THREE.Mesh(boxGeo, plankMat);
seatPlank3.name = 'seatPlank';
seatPlank3.position.set(0, 0.43, 0.14);
root.add(seatPlank3);
const seatBoard = new THREE.Mesh(new THREE.BoxGeometry(0.41, 0.016, 0.39), underMat);
seatBoard.name = 'seatBoard';
seatBoard.position.set(0, 0.402, 0);
root.add(seatBoard);
const legFront = new THREE.Mesh(cylinderGeo, frameMat);
legFront.name = 'legFront';
legFront.position.set(-0.1855, 0.197, 0.1675);
legFront.rotation.set(0, deg(45), 0);
root.add(legFront);
const legBack = new THREE.Mesh(boxGeo2, frameMat);
legBack.name = 'legBack';
legBack.position.set(-0.1855, 0.46, -0.1825);
root.add(legBack);
const finial = new THREE.Mesh(cylinderGeo2, frameMat);
finial.name = 'finial';
finial.position.set(-0.1855, 0.9375, -0.1825);
finial.rotation.set(0, deg(45), 0);
root.add(finial);
const legFront2 = new THREE.Mesh(cylinderGeo, frameMat);
legFront2.name = 'legFront';
legFront2.position.set(0.1855, 0.197, 0.1675);
legFront2.rotation.set(0, deg(45), 0);
root.add(legFront2);
const legBack2 = new THREE.Mesh(boxGeo2, frameMat);
legBack2.name = 'legBack';
legBack2.position.set(0.1855, 0.46, -0.1825);
root.add(legBack2);
const finial2 = new THREE.Mesh(cylinderGeo2, frameMat);
finial2.name = 'finial';
finial2.position.set(0.1855, 0.9375, -0.1825);
finial2.rotation.set(0, deg(45), 0);
root.add(finial2);
const apronFront = new THREE.Mesh(boxGeo3, trimMat);
apronFront.name = 'apronFront';
apronFront.position.set(0, 0.364, 0.174);
root.add(apronFront);
const apronBack = new THREE.Mesh(boxGeo3, trimMat);
apronBack.name = 'apronBack';
apronBack.position.set(0, 0.364, -0.1825);
root.add(apronBack);
const apronSide = new THREE.Mesh(boxGeo4, trimMat);
apronSide.name = 'apronSide';
apronSide.position.set(-0.192, 0.364, -0.0075);
root.add(apronSide);
const stretcherSide = new THREE.Mesh(boxGeo5, frameMat);
stretcherSide.name = 'stretcherSide';
stretcherSide.position.set(-0.1855, 0.13, -0.0075);
root.add(stretcherSide);
const apronSide2 = new THREE.Mesh(boxGeo4, trimMat);
apronSide2.name = 'apronSide';
apronSide2.position.set(0.192, 0.364, -0.0075);
root.add(apronSide2);
const stretcherSide2 = new THREE.Mesh(boxGeo5, frameMat);
stretcherSide2.name = 'stretcherSide';
stretcherSide2.position.set(0.1855, 0.13, -0.0075);
root.add(stretcherSide2);
const stretcherFront = new THREE.Mesh(new THREE.BoxGeometry(0.371, 0.024, 0.024), frameMat);
stretcherFront.name = 'stretcherFront';
stretcherFront.position.set(0, 0.19, 0.1675);
root.add(stretcherFront);
const crestRail = new THREE.Mesh(extrude([[-0.1855, 0], [-0.1855, 0.075], [-0.1237, 0.09], [-0.0618, 0.101], [0, 0.105], [0.0618, 0.101], [0.1237, 0.09], [0.1855, 0.075], [0.1855, 0]], 0.028), plankMat);
crestRail.name = 'crestRail';
crestRail.position.set(0, 0.81, -0.1825);
root.add(crestRail);
const lowerRail = new THREE.Mesh(new THREE.BoxGeometry(0.371, 0.045, 0.024), trimMat);
lowerRail.name = 'lowerRail';
lowerRail.position.set(0, 0.5725, -0.1825);
root.add(lowerRail);
const slat = new THREE.Mesh(boxGeo6, plankMat);
slat.name = 'slat';
slat.position.set(-0.11, 0.7025, -0.1825);
root.add(slat);
const slat2 = new THREE.Mesh(boxGeo6, plankAltMat);
slat2.name = 'slat';
slat2.position.set(0, 0.7025, -0.1825);
root.add(slat2);
const slat3 = new THREE.Mesh(boxGeo6, plankMat);
slat3.name = 'slat';
slat3.position.set(0.11, 0.7025, -0.1825);
root.add(slat3);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createWoodenChair;
Оценки и комментарии
0 комментариев
Комментариев пока нет. Расскажите, как вы использовали эту модель или что можно улучшить.
Похожие модели
Та же категория или похожие теги









