Codels
304 треуг.1,71 × 0,88 × 0,66 m

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

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

  // Materials
  const woodMat = new THREE.MeshStandardMaterial({ name: 'wood', color: 0xb3773f, roughness: 0.85, flatShading: true });
  const ironMat = new THREE.MeshStandardMaterial({ name: 'iron', color: 0x2e3a34, roughness: 0.55, metalness: 0.5, flatShading: true });

  // Shared geometries
  const extrudeGeo = extrude([[0.27, 0], [0.17, 0], [0.15, 0.33], [-0.12, 0.33], [-0.18, 0], [-0.29, 0], [-0.25, 0.4], [-0.37, 0.86], [-0.29, 0.88], [-0.19, 0.43], [0.16, 0.455], [0.18, 0.58], [-0.1, 0.61], [-0.09, 0.67], [0.25, 0.66], [0.29, 0.6], [0.23, 0.43], [0.25, 0.3]], 0.05);
  const boxGeo = new THREE.BoxGeometry(0.08, 0.025, 0.14);
  const boxGeo2 = new THREE.BoxGeometry(0.07, 0.035, 0.38);

  // Parts
  const sideFrame = new THREE.Mesh(extrudeGeo, ironMat);
  sideFrame.name = 'sideFrame';
  sideFrame.position.set(-0.73, 0, 0);
  sideFrame.rotation.set(0, deg(-90), 0);
  root.add(sideFrame);
  const foot = new THREE.Mesh(boxGeo, ironMat);
  foot.name = 'foot';
  foot.position.set(-0.73, 0.0125, 0.22);
  root.add(foot);
  const foot2 = new THREE.Mesh(boxGeo, ironMat);
  foot2.name = 'foot';
  foot2.position.set(-0.73, 0.0125, -0.235);
  root.add(foot2);
  const sideFrame2 = new THREE.Mesh(extrudeGeo, ironMat);
  sideFrame2.name = 'sideFrame';
  sideFrame2.position.set(0.73, 0, 0);
  sideFrame2.rotation.set(0, deg(-90), 0);
  root.add(sideFrame2);
  const foot3 = new THREE.Mesh(boxGeo, ironMat);
  foot3.name = 'foot';
  foot3.position.set(0.73, 0.0125, 0.22);
  root.add(foot3);
  const foot4 = new THREE.Mesh(boxGeo, ironMat);
  foot4.name = 'foot';
  foot4.position.set(0.73, 0.0125, -0.235);
  root.add(foot4);
  const seatSlat = new THREE.Mesh(new THREE.BoxGeometry(1.6931, 0.04, 0.062), woodMat);
  seatSlat.name = 'seatSlat';
  seatSlat.position.set(0, 0.4545, -0.149);
  seatSlat.rotation.set(deg(-3.9725), 0, 0);
  root.add(seatSlat);
  const seatSlat2 = new THREE.Mesh(new THREE.BoxGeometry(1.7025, 0.04, 0.062), woodMat);
  seatSlat2.name = 'seatSlat';
  seatSlat2.position.set(0, 0.4595, -0.077);
  seatSlat2.rotation.set(deg(-3.9725), 0, 0);
  root.add(seatSlat2);
  const seatSlat3 = new THREE.Mesh(new THREE.BoxGeometry(1.696, 0.04, 0.062), woodMat);
  seatSlat3.name = 'seatSlat';
  seatSlat3.position.set(0, 0.4645, -0.005);
  seatSlat3.rotation.set(deg(-3.9725), 0, 0);
  root.add(seatSlat3);
  const seatSlat4 = new THREE.Mesh(new THREE.BoxGeometry(1.7039, 0.04, 0.062), woodMat);
  seatSlat4.name = 'seatSlat';
  seatSlat4.position.set(0, 0.4695, 0.067);
  seatSlat4.rotation.set(deg(-3.9725), 0, 0);
  root.add(seatSlat4);
  const seatSlat5 = new THREE.Mesh(new THREE.BoxGeometry(1.7017, 0.04, 0.062), woodMat);
  seatSlat5.name = 'seatSlat';
  seatSlat5.position.set(0, 0.4745, 0.139);
  seatSlat5.rotation.set(deg(-3.9725), 0, 0);
  root.add(seatSlat5);
  const backSlat = new THREE.Mesh(new THREE.BoxGeometry(1.699, 0.1, 0.035), woodMat);
  backSlat.name = 'backSlat';
  backSlat.position.set(0, 0.56, -0.1867);
  backSlat.rotation.set(deg(-15.5241), 0, 0);
  root.add(backSlat);
  const backSlat2 = new THREE.Mesh(new THREE.BoxGeometry(1.7064, 0.1, 0.035), woodMat);
  backSlat2.name = 'backSlat';
  backSlat2.position.set(0, 0.68, -0.22);
  backSlat2.rotation.set(deg(-15.5241), 0, 0);
  root.add(backSlat2);
  const backSlat3 = new THREE.Mesh(new THREE.BoxGeometry(1.6948, 0.1, 0.035), woodMat);
  backSlat3.name = 'backSlat';
  backSlat3.position.set(0, 0.8, -0.2533);
  backSlat3.rotation.set(deg(-15.5241), 0, 0);
  root.add(backSlat3);
  const armrest = new THREE.Mesh(boxGeo2, woodMat);
  armrest.name = 'armrest';
  armrest.position.set(-0.73, 0.685, 0.08);
  root.add(armrest);
  const armrest2 = new THREE.Mesh(boxGeo2, woodMat);
  armrest2.name = 'armrest';
  armrest2.position.set(0.73, 0.685, 0.08);
  root.add(armrest2);

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

export default createParkBench;

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

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

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

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

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

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

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