Codels
300 треуг.0,44 × 0,96 × 0,41 m

Использовать в коде

Ремикс в редакторе
Самодостаточный 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;

Оценки и комментарии

—
Оценок пока нет — будьте первым.
5
0
4
0
3
0
2
0
1
0

Войдите, чтобы ставить оценки и оставлять комментарии.

0 комментариев

Комментариев пока нет. Расскажите, как вы использовали эту модель или что можно улучшить.

Похожие модели

Та же категория или похожие теги