Codels
844 tris2,12 × 0,87 × 0,92 m
Módulo ES autocontido — depende apenas do three. Chame a factory e adicione o grupo à sua cena.
/**
 * Sofa — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 844 · Size (W × H × D): 2.12 × 0.87 × 0.92 m
 *
 * Usage:
 *   import { createSofa } from './sofa.js';
 *   
 *   const model = createSofa();
 *   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 createSofa() {
  const root = new THREE.Group();
  root.name = 'Sofa';

  // Materials
  const fabricMat = new THREE.MeshStandardMaterial({ name: 'fabric', color: 0x4d7085, roughness: 1, flatShading: true });
  const cushionMat = new THREE.MeshStandardMaterial({ name: 'cushion', color: 0x597a8e, roughness: 1, flatShading: true });
  const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x375160, roughness: 1, flatShading: true });
  const woodMat = new THREE.MeshStandardMaterial({ name: 'wood', color: 0x5c3d24, roughness: 0.75, flatShading: true });
  const pillowMat = new THREE.MeshStandardMaterial({ name: 'pillow', color: 0xd9a441, roughness: 1, flatShading: true });
  const pillowAltMat = new THREE.MeshStandardMaterial({ name: 'pillowAlt', color: 0xe8e1d3, roughness: 1, flatShading: true });

  // Shared geometries
  const extrudeGeo = extrude([[0.264, 0.2879], [0.2244, 0.3275], [-0.2244, 0.3275], [-0.264, 0.2879], [-0.264, -0.2879], [-0.2244, -0.3275], [0.2244, -0.3275], [0.264, -0.2879]], 0.08, [], [0.03, 0.03, 1]);
  const extrudeGeo2 = extrude([[0.055, 0.2017], [0.0468, 0.21], [-0.0467, 0.21], [-0.055, 0.2017], [-0.055, -0.2017], [-0.0467, -0.21], [0.0468, -0.21], [0.055, -0.2017]], 0.85, [], [0.025, 0.025, 1]);
  const extrudeGeo3 = extrude([[0.252, 0.136], [0.228, 0.16], [-0.228, 0.16], [-0.252, 0.136], [-0.252, -0.136], [-0.228, -0.16], [0.228, -0.16], [0.252, -0.136]], 0.09, [], [0.04, 0.04, 1]);
  const cylinderGeo = new THREE.CylinderGeometry(0.012, 0.022, 0.1347, 6);
  const cylinderGeo2 = new THREE.CylinderGeometry(0.012, 0.022, 0.1324, 6);
  const extrudeGeo4 = extrude([[0.155, 0.1008], [0.1391, 0.1391], [0.1008, 0.155], [-0.1008, 0.155], [-0.1391, 0.1391], [-0.155, 0.1008], [-0.155, -0.1008], [-0.1391, -0.1391], [-0.1008, -0.155], [0.1007, -0.155], [0.1391, -0.1391], [0.155, -0.1008]], 0.026, [], [0.052, 0.055, 1]);

  // Parts
  const base = new THREE.Mesh(new THREE.BoxGeometry(1.83, 0.18, 0.89), fabricMat);
  base.name = 'base';
  base.position.set(0, 0.22, 0.005);
  root.add(base);
  const deck = new THREE.Mesh(new THREE.BoxGeometry(1.8, 0.012, 0.68), darkMat);
  deck.name = 'deck';
  deck.position.set(0, 0.306, 0.1);
  root.add(deck);
  const seatCushion = new THREE.Mesh(extrudeGeo, cushionMat);
  seatCushion.name = 'seatCushion';
  seatCushion.position.set(-0.6, 0.38, 0.1075);
  seatCushion.rotation.set(deg(-90), 0, 0);
  root.add(seatCushion);
  const seatCushion2 = new THREE.Mesh(extrudeGeo, cushionMat);
  seatCushion2.name = 'seatCushion';
  seatCushion2.position.set(0, 0.38, 0.1075);
  seatCushion2.rotation.set(deg(-90), 0, 0);
  root.add(seatCushion2);
  const seatCushion3 = new THREE.Mesh(extrudeGeo, cushionMat);
  seatCushion3.name = 'seatCushion';
  seatCushion3.position.set(0.6, 0.38, 0.1075);
  seatCushion3.rotation.set(deg(-90), 0, 0);
  root.add(seatCushion3);
  const back = new THREE.Mesh(new THREE.BoxGeometry(2.1, 0.585, 0.175), fabricMat);
  back.name = 'back';
  back.position.set(0, 0.4475, -0.3375);
  root.add(back);
  const arm = new THREE.Mesh(extrudeGeo2, fabricMat);
  arm.name = 'arm';
  arm.position.set(-0.98, 0.365, 0);
  root.add(arm);
  const arm2 = new THREE.Mesh(extrudeGeo2, fabricMat);
  arm2.name = 'arm';
  arm2.position.set(0.98, 0.365, 0);
  root.add(arm2);
  const backCushion = new THREE.Mesh(extrudeGeo3, cushionMat);
  backCushion.name = 'backCushion';
  backCushion.position.set(-0.6, 0.64, -0.185);
  backCushion.rotation.set(deg(-12), 0, 0);
  root.add(backCushion);
  const backCushion2 = new THREE.Mesh(extrudeGeo3, cushionMat);
  backCushion2.name = 'backCushion';
  backCushion2.position.set(0, 0.64, -0.185);
  backCushion2.rotation.set(deg(-12), 0, 0);
  root.add(backCushion2);
  const backCushion3 = new THREE.Mesh(extrudeGeo3, cushionMat);
  backCushion3.name = 'backCushion';
  backCushion3.position.set(0.6, 0.64, -0.185);
  backCushion3.rotation.set(deg(-12), 0, 0);
  root.add(backCushion3);
  const leg = new THREE.Mesh(cylinderGeo, woodMat);
  leg.name = 'leg';
  leg.position.set(-1.0025, 0.069, -0.3825);
  leg.rotation.set(deg(-84.6051), deg(-79.2576), deg(84.6051));
  root.add(leg);
  const leg2 = new THREE.Mesh(cylinderGeo, woodMat);
  leg2.name = 'leg';
  leg2.position.set(-1.0025, 0.069, 0.3825);
  leg2.rotation.set(deg(84.6051), deg(79.2576), deg(84.6051));
  root.add(leg2);
  const leg3 = new THREE.Mesh(cylinderGeo2, woodMat);
  leg3.name = 'leg';
  leg3.position.set(0, 0.069, -0.3825);
  leg3.rotation.set(deg(-169.1145), 0, 0);
  root.add(leg3);
  const leg4 = new THREE.Mesh(cylinderGeo2, woodMat);
  leg4.name = 'leg';
  leg4.position.set(0, 0.069, 0.3825);
  leg4.rotation.set(deg(169.1145), 0, 0);
  root.add(leg4);
  const leg5 = new THREE.Mesh(cylinderGeo, woodMat);
  leg5.name = 'leg';
  leg5.position.set(1.0025, 0.069, -0.3825);
  leg5.rotation.set(deg(-84.6051), deg(79.2576), deg(-84.6051));
  root.add(leg5);
  const leg6 = new THREE.Mesh(cylinderGeo, woodMat);
  leg6.name = 'leg';
  leg6.position.set(1.0025, 0.069, 0.3825);
  leg6.rotation.set(deg(84.6051), deg(-79.2576), deg(-84.6051));
  root.add(leg6);
  const throwPillow = new THREE.Mesh(extrudeGeo4, pillowMat);
  throwPillow.name = 'throwPillow';
  throwPillow.position.set(-0.65, 0.65, -0.04);
  throwPillow.rotation.set(deg(-16.6099), deg(15.3646), deg(-3.4809));
  root.add(throwPillow);
  const throwPillow2 = new THREE.Mesh(extrudeGeo4, pillowAltMat);
  throwPillow2.name = 'throwPillow';
  throwPillow2.position.set(0.65, 0.65, -0.04);
  throwPillow2.rotation.set(deg(-16.6099), deg(-15.3646), deg(3.4809));
  root.add(throwPillow2);

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

export default createSofa;

Avaliações e comentários

—
Nenhuma avaliação ainda — seja o primeiro.
5
0
4
0
3
0
2
0
1
0

Entre para avaliar e comentar.

0 comentário

Nenhum comentário ainda. Conte como você usou este modelo ou o que poderia melhorar.

Modelos relacionados

Mesma categoria ou tags parecidas