Codels
1,4 тыс. треуг.1,17 × 2,02 × 1,14 m

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

Ремикс в редакторе
Самодостаточный ES-модуль — зависит только от three. Вызовите фабрику и добавьте группу в сцену.
/**
 * Wardrobe — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,392 · Size (W × H × D): 1.17 × 2.02 × 1.14 m
 *
 * Usage:
 *   import { createWardrobe } from './wardrobe.js';
 *   
 *   const model = createWardrobe();
 *   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 createWardrobe() {
  const root = new THREE.Group();
  root.name = 'Wardrobe';

  // Materials
  const woodMat = new THREE.MeshStandardMaterial({ name: 'wood', color: 0x8f5a32, roughness: 0.85, flatShading: true });
  const panelMat = new THREE.MeshStandardMaterial({ name: 'panel', color: 0x9a6b47, roughness: 0.8, flatShading: true });
  const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x59381f, roughness: 0.95, flatShading: true });
  const brassMat = new THREE.MeshStandardMaterial({ name: 'brass', color: 0xd6aa4f, roughness: 0.35, metalness: 0.5, flatShading: true });
  const redMat = new THREE.MeshStandardMaterial({ name: 'red', color: 0xb4483e, roughness: 1, flatShading: true });
  const creamMat = new THREE.MeshStandardMaterial({ name: 'cream', color: 0xe8dfcb, roughness: 1, flatShading: true });
  const blueMat = new THREE.MeshStandardMaterial({ name: 'blue', color: 0x3f5f86, roughness: 1, flatShading: true });
  const greenMat = new THREE.MeshStandardMaterial({ name: 'green', color: 0x5d7a4c, roughness: 1, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.03, 1.84, 0.6);
  const boxGeo2 = new THREE.BoxGeometry(1.04, 0.025, 0.585);
  const extrudeGeo = extrude([[0.261, 0.1156], [0.2406, 0.136], [-0.2406, 0.136], [-0.261, 0.1156], [-0.261, -0.1156], [-0.2406, -0.136], [0.2406, -0.136], [0.261, -0.1156]], 0.008, [], [0.008, 0.008, 1]);
  const extrudeGeo2 = extrude([[0.214, 0.0782], [0.2002, 0.092], [-0.2002, 0.092], [-0.214, 0.0782], [-0.214, -0.0782], [-0.2002, -0.092], [0.2002, -0.092], [0.214, -0.0782]], 0.0024, [], [0.0048, 0.008, 1]);
  const cylinderGeo = new THREE.CylinderGeometry(0.0081, 0.0108, 0.0162, 6);
  const sphereGeo = new THREE.SphereGeometry(0.018, 6, 4);
  const boxGeo3 = new THREE.BoxGeometry(0.544, 1.528, 0.024);
  const extrudeGeo3 = extrude([[0.19, 0.1845], [0.1615, 0.213], [-0.1615, 0.213], [-0.19, 0.1845], [-0.19, -0.1845], [-0.1615, -0.213], [0.1615, -0.213], [0.19, -0.1845]], 0.0028, [], [0.0056, 0.012, 1]);
  const extrudeGeo4 = extrude([[0.19, 0.3985], [0.1615, 0.427], [-0.1615, 0.427], [-0.19, 0.3985], [-0.19, -0.3985], [-0.1615, -0.427], [0.1615, -0.427], [0.19, -0.3985]], 0.0028, [], [0.0056, 0.012, 1]);
  const torusGeo = new THREE.TorusGeometry(0.016, 0.003, 3, 8, 4.3982);
  const extrudeGeo5 = extrude([[-0.1979, -0.105], [0.1979, -0.105], [0, -0.025]], 0.012);

  // Parts
  const plinth = new THREE.Mesh(new THREE.BoxGeometry(1.06, 0.08, 0.56), darkMat);
  plinth.name = 'plinth';
  plinth.position.set(0, 0.04, -0.01);
  root.add(plinth);
  const side = new THREE.Mesh(boxGeo, woodMat);
  side.name = 'side';
  side.position.set(-0.535, 1, 0);
  root.add(side);
  const side2 = new THREE.Mesh(boxGeo, woodMat);
  side2.name = 'side';
  side2.position.set(0.535, 1, 0);
  root.add(side2);
  const bottom = new THREE.Mesh(boxGeo2, woodMat);
  bottom.name = 'bottom';
  bottom.position.set(0, 0.0925, 0.0075);
  root.add(bottom);
  const divider = new THREE.Mesh(boxGeo2, woodMat);
  divider.name = 'divider';
  divider.position.set(0, 0.3675, 0.0075);
  root.add(divider);
  const top = new THREE.Mesh(boxGeo2, woodMat);
  top.name = 'top';
  top.position.set(0, 1.9075, 0.0075);
  root.add(top);
  const backPanel = new THREE.Mesh(new THREE.BoxGeometry(1.04, 1.84, 0.015), darkMat);
  backPanel.name = 'backPanel';
  backPanel.position.set(0, 1, -0.2925);
  root.add(backPanel);
  const corniceStep = new THREE.Mesh(new THREE.BoxGeometry(1.13, 0.035, 0.62), panelMat);
  corniceStep.name = 'corniceStep';
  corniceStep.position.set(0, 1.9375, 0.01);
  root.add(corniceStep);
  const cornice = new THREE.Mesh(new THREE.BoxGeometry(1.17, 0.065, 0.645), woodMat);
  cornice.name = 'cornice';
  cornice.position.set(0, 1.9875, 0.0175);
  root.add(cornice);
  const drawerFront = new THREE.Mesh(extrudeGeo, woodMat);
  drawerFront.name = 'drawerFront';
  drawerFront.position.set(-0.275, 0.23, 0.312);
  root.add(drawerFront);
  const drawerPanel = new THREE.Mesh(extrudeGeo2, panelMat);
  drawerPanel.name = 'drawerPanel';
  drawerPanel.position.set(-0.275, 0.23, 0.328);
  root.add(drawerPanel);
  const knob = new THREE.Group();
  knob.name = 'knob';
  knob.position.set(-0.275, 0.23, 0.33);
  root.add(knob);
  const knobStem = new THREE.Mesh(cylinderGeo, brassMat);
  knobStem.name = 'knobStem';
  knobStem.position.set(0, 0, 0.0081);
  knobStem.rotation.set(deg(90), 0, 0);
  knob.add(knobStem);
  const knobHead = new THREE.Mesh(sphereGeo, brassMat);
  knobHead.name = 'knobHead';
  knobHead.position.set(0, 0, 0.0225);
  knobHead.scale.set(1, 1, 0.7);
  knob.add(knobHead);
  const drawerFront2 = new THREE.Mesh(extrudeGeo, woodMat);
  drawerFront2.name = 'drawerFront';
  drawerFront2.position.set(0.275, 0.23, 0.312);
  root.add(drawerFront2);
  const drawerPanel2 = new THREE.Mesh(extrudeGeo2, panelMat);
  drawerPanel2.name = 'drawerPanel';
  drawerPanel2.position.set(0.275, 0.23, 0.328);
  root.add(drawerPanel2);
  const knob2 = new THREE.Group();
  knob2.name = 'knob';
  knob2.position.set(0.275, 0.23, 0.33);
  root.add(knob2);
  const knobStem2 = new THREE.Mesh(cylinderGeo, brassMat);
  knobStem2.name = 'knobStem';
  knobStem2.position.set(0, 0, 0.0081);
  knobStem2.rotation.set(deg(90), 0, 0);
  knob2.add(knobStem2);
  const knobHead2 = new THREE.Mesh(sphereGeo, brassMat);
  knobHead2.name = 'knobHead';
  knobHead2.position.set(0, 0, 0.0225);
  knobHead2.scale.set(1, 1, 0.7);
  knob2.add(knobHead2);
  const doorLeft = new THREE.Group();
  doorLeft.name = 'doorLeft';
  doorLeft.position.set(-0.55, 0.386, 0.3);
  doorLeft.rotation.set(0, deg(-75), 0);
  root.add(doorLeft);
  const doorSlab = new THREE.Mesh(boxGeo3, woodMat);
  doorSlab.name = 'doorSlab';
  doorSlab.position.set(0.272, 0.764, 0.012);
  doorLeft.add(doorSlab);
  const doorPanel = new THREE.Mesh(extrudeGeo3, panelMat);
  doorPanel.name = 'doorPanel';
  doorPanel.position.set(0.272, 0.295, 0.028);
  doorLeft.add(doorPanel);
  const doorPanel2 = new THREE.Mesh(extrudeGeo4, panelMat);
  doorPanel2.name = 'doorPanel';
  doorPanel2.position.set(0.272, 1.019, 0.028);
  doorLeft.add(doorPanel2);
  const knob3 = new THREE.Group();
  knob3.name = 'knob';
  knob3.position.set(0.494, 0.5501, 0.024);
  doorLeft.add(knob3);
  const knobStem3 = new THREE.Mesh(cylinderGeo, brassMat);
  knobStem3.name = 'knobStem';
  knobStem3.position.set(0, 0, 0.0081);
  knobStem3.rotation.set(deg(90), 0, 0);
  knob3.add(knobStem3);
  const knobHead3 = new THREE.Mesh(sphereGeo, brassMat);
  knobHead3.name = 'knobHead';
  knobHead3.position.set(0, 0, 0.0225);
  knobHead3.scale.set(1, 1, 0.7);
  knob3.add(knobHead3);
  const doorRight = new THREE.Group();
  doorRight.name = 'doorRight';
  doorRight.position.set(0.55, 0.386, 0.3);
  doorRight.rotation.set(0, deg(75), 0);
  root.add(doorRight);
  const doorSlab2 = new THREE.Mesh(boxGeo3, woodMat);
  doorSlab2.name = 'doorSlab';
  doorSlab2.position.set(-0.272, 0.764, 0.012);
  doorRight.add(doorSlab2);
  const doorPanel3 = new THREE.Mesh(extrudeGeo3, panelMat);
  doorPanel3.name = 'doorPanel';
  doorPanel3.position.set(-0.272, 0.295, 0.028);
  doorRight.add(doorPanel3);
  const doorPanel4 = new THREE.Mesh(extrudeGeo4, panelMat);
  doorPanel4.name = 'doorPanel';
  doorPanel4.position.set(-0.272, 1.019, 0.028);
  doorRight.add(doorPanel4);
  const knob4 = new THREE.Group();
  knob4.name = 'knob';
  knob4.position.set(-0.494, 0.5501, 0.024);
  doorRight.add(knob4);
  const knobStem4 = new THREE.Mesh(cylinderGeo, brassMat);
  knobStem4.name = 'knobStem';
  knobStem4.position.set(0, 0, 0.0081);
  knobStem4.rotation.set(deg(90), 0, 0);
  knob4.add(knobStem4);
  const knobHead4 = new THREE.Mesh(sphereGeo, brassMat);
  knobHead4.name = 'knobHead';
  knobHead4.position.set(0, 0, 0.0225);
  knobHead4.scale.set(1, 1, 0.7);
  knob4.add(knobHead4);
  const shelf = new THREE.Mesh(new THREE.BoxGeometry(1.04, 0.02, 0.57), woodMat);
  shelf.name = 'shelf';
  shelf.position.set(0, 1.66, 0);
  root.add(shelf);
  const rail = new THREE.Mesh(new THREE.CylinderGeometry(0.012, 0.012, 1.04, 6), brassMat);
  rail.name = 'rail';
  rail.position.set(0, 1.56, 0);
  rail.rotation.set(0, 0, deg(90));
  root.add(rail);
  const hanger = new THREE.Group();
  hanger.name = 'hanger';
  hanger.position.set(-0.4346, 1.56, 0);
  hanger.rotation.set(0, deg(73.7427), 0);
  root.add(hanger);
  const garment = new THREE.Mesh(extrude([[-0.1893, -0.62], [0.1893, -0.62], [0.1993, -0.1], [0.05, -0.035], [-0.05, -0.035], [-0.1993, -0.1]], 0.0525), redMat);
  garment.name = 'garment';
  hanger.add(garment);
  const coatHanger = new THREE.Mesh(extrude([[-0.2043, -0.105], [0.2043, -0.105], [0, -0.025]], 0.012), darkMat);
  coatHanger.name = 'coatHanger';
  hanger.add(coatHanger);
  const hook = new THREE.Mesh(torusGeo, brassMat);
  hook.name = 'hook';
  hook.position.set(0, -0.004, 0);
  hook.rotation.set(0, 0, deg(-20));
  hanger.add(hook);
  const hanger2 = new THREE.Group();
  hanger2.name = 'hanger';
  hanger2.position.set(-0.2548, 1.56, 0);
  hanger2.rotation.set(0, deg(108.7579), 0);
  root.add(hanger2);
  const garment2 = new THREE.Mesh(extrude([[-0.1672, -0.75], [0.1672, -0.75], [0.1772, -0.1], [0.05, -0.035], [-0.05, -0.035], [-0.1772, -0.1]], 0.0488), creamMat);
  garment2.name = 'garment';
  hanger2.add(garment2);
  const coatHanger2 = new THREE.Mesh(extrude([[-0.1822, -0.105], [0.1822, -0.105], [0, -0.025]], 0.012), darkMat);
  coatHanger2.name = 'coatHanger';
  hanger2.add(coatHanger2);
  const hook2 = new THREE.Mesh(torusGeo, brassMat);
  hook2.name = 'hook';
  hook2.position.set(0, -0.004, 0);
  hook2.rotation.set(0, 0, deg(-20));
  hanger2.add(hook2);
  const hanger3 = new THREE.Group();
  hanger3.name = 'hanger';
  hanger3.position.set(-0.0913, 1.56, 0);
  hanger3.rotation.set(0, deg(77.6344), 0);
  root.add(hanger3);
  const garment3 = new THREE.Mesh(extrude([[-0.1829, -0.62], [0.1829, -0.62], [0.1929, -0.1], [0.05, -0.035], [-0.05, -0.035], [-0.1929, -0.1]], 0.048), blueMat);
  garment3.name = 'garment';
  hanger3.add(garment3);
  const coatHanger3 = new THREE.Mesh(extrudeGeo5, darkMat);
  coatHanger3.name = 'coatHanger';
  hanger3.add(coatHanger3);
  const hook3 = new THREE.Mesh(torusGeo, brassMat);
  hook3.name = 'hook';
  hook3.position.set(0, -0.004, 0);
  hook3.rotation.set(0, 0, deg(-20));
  hanger3.add(hook3);
  const hanger4 = new THREE.Group();
  hanger4.name = 'hanger';
  hanger4.position.set(0.08, 1.56, 0);
  hanger4.rotation.set(0, deg(111.7354), 0);
  root.add(hanger4);
  const garment4 = new THREE.Mesh(extrude([[-0.176, -0.75], [0.176, -0.75], [0.186, -0.1], [0.05, -0.035], [-0.05, -0.035], [-0.186, -0.1]], 0.0424), greenMat);
  garment4.name = 'garment';
  hanger4.add(garment4);
  const coatHanger4 = new THREE.Mesh(extrude([[-0.191, -0.105], [0.191, -0.105], [0, -0.025]], 0.012), darkMat);
  coatHanger4.name = 'coatHanger';
  hanger4.add(coatHanger4);
  const hook4 = new THREE.Mesh(torusGeo, brassMat);
  hook4.name = 'hook';
  hook4.position.set(0, -0.004, 0);
  hook4.rotation.set(0, 0, deg(-20));
  hanger4.add(hook4);
  const hanger5 = new THREE.Group();
  hanger5.name = 'hanger';
  hanger5.position.set(0.2444, 1.56, 0);
  hanger5.rotation.set(0, deg(78.1443), 0);
  root.add(hanger5);
  const garment5 = new THREE.Mesh(extrude([[-0.1657, -1.05], [0.1657, -1.05], [0.1757, -0.1], [0.05, -0.035], [-0.05, -0.035], [-0.1757, -0.1]], 0.0386), creamMat);
  garment5.name = 'garment';
  hanger5.add(garment5);
  const coatHanger5 = new THREE.Mesh(extrude([[-0.1807, -0.105], [0.1807, -0.105], [0, -0.025]], 0.012), darkMat);
  coatHanger5.name = 'coatHanger';
  hanger5.add(coatHanger5);
  const hook5 = new THREE.Mesh(torusGeo, brassMat);
  hook5.name = 'hook';
  hook5.position.set(0, -0.004, 0);
  hook5.rotation.set(0, 0, deg(-20));
  hanger5.add(hook5);
  const hanger6 = new THREE.Group();
  hanger6.name = 'hanger';
  hanger6.position.set(0.4137, 1.56, 0);
  hanger6.rotation.set(0, deg(110.9553), 0);
  root.add(hanger6);
  const garment6 = new THREE.Mesh(extrude([[-0.1829, -0.95], [0.1829, -0.95], [0.1929, -0.1], [0.05, -0.035], [-0.05, -0.035], [-0.1929, -0.1]], 0.0369), redMat);
  garment6.name = 'garment';
  hanger6.add(garment6);
  const coatHanger6 = new THREE.Mesh(extrudeGeo5, darkMat);
  coatHanger6.name = 'coatHanger';
  hanger6.add(coatHanger6);
  const hook6 = new THREE.Mesh(torusGeo, brassMat);
  hook6.name = 'hook';
  hook6.position.set(0, -0.004, 0);
  hook6.rotation.set(0, 0, deg(-20));
  hanger6.add(hook6);
  const linen = new THREE.Mesh(new THREE.BoxGeometry(0.32, 0.045, 0.3), creamMat);
  linen.name = 'linen';
  linen.position.set(-0.2189, 1.6925, 0.02);
  linen.rotation.set(0, deg(0.973), 0);
  root.add(linen);
  const linen2 = new THREE.Mesh(new THREE.BoxGeometry(0.31, 0.045, 0.3), blueMat);
  linen2.name = 'linen';
  linen2.position.set(-0.2164, 1.7375, 0.02);
  linen2.rotation.set(0, deg(3.7279), 0);
  root.add(linen2);
  const linen3 = new THREE.Mesh(new THREE.BoxGeometry(0.3, 0.045, 0.3), creamMat);
  linen3.name = 'linen';
  linen3.position.set(-0.2175, 1.7825, 0.02);
  linen3.rotation.set(0, deg(3.3696), 0);
  root.add(linen3);
  const hatBox = new THREE.Mesh(new THREE.BoxGeometry(0.26, 0.14, 0.26), redMat);
  hatBox.name = 'hatBox';
  hatBox.position.set(0.24, 1.74, 0);
  hatBox.rotation.set(0, deg(12), 0);
  root.add(hatBox);

  root.traverse((o) => {
    if (o.isMesh) {
      o.castShadow = true;
      o.receiveShadow = true;
    }
  });
  return root;
}

export default createWardrobe;

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

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

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

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

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

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

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