Codels
1596 ポリゴン7.40 × 6.23 × 7.42 m
自己完結型の ES モジュールで、依存先は three のみです。ファクトリー関数を呼び出し、返された group をシーンに追加してください。
/**
 * Thatched Hut — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,596 · Size (W × H × D): 7.40 × 6.23 × 7.42 m
 *
 * Usage:
 *   import { createHut } from './hut.js';
 *   
 *   const model = createHut();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 */
import * as THREE from 'three';

const deg = THREE.MathUtils.degToRad;

// Deterministic vertex displacement (organic low-poly look).
function jitter(geometry, amount, seed) {
  const pos = geometry.attributes.position;
  const h = (a, b, c, s) => {
    let x = Math.imul(a, 73856093) ^ Math.imul(b, 19349663) ^ Math.imul(c, 83492791) ^ Math.imul(s, 2654435761);
    x = Math.imul(x ^ (x >>> 16), 2246822507);
    x = Math.imul(x ^ (x >>> 13), 3266489909);
    return ((x ^ (x >>> 16)) >>> 0) / 4294967295 - 0.5;
  };
  for (let i = 0; i < pos.count; i++) {
    const x = pos.getX(i), y = pos.getY(i), z = pos.getZ(i);
    const qx = Math.round(x * 1000), qy = Math.round(y * 1000), qz = Math.round(z * 1000);
    pos.setXYZ(i, x + h(qx, qy, qz, seed) * 2 * amount, y + h(qx, qy, qz, seed + 1) * 2 * amount, z + h(qx, qy, qz, seed + 2) * 2 * amount);
  }
  pos.needsUpdate = true;
  geometry.computeVertexNormals();
  return geometry;
}

// Revolve a 2D profile [[radius, y], ...] around the Y axis.
function lathe(points, segments, phiStart = 0, phiLength = Math.PI * 2) {
  return new THREE.LatheGeometry(points.map(([x, y]) => new THREE.Vector2(x, y)), segments, phiStart, phiLength);
}

export function createHut() {
  const root = new THREE.Group();
  root.name = 'Hut';

  // Materials
  const mudMat = new THREE.MeshStandardMaterial({ name: 'mud', color: 0xb47d52, roughness: 1, flatShading: true });
  const mudDarkMat = new THREE.MeshStandardMaterial({ name: 'mudDark', color: 0x8c6240, roughness: 1, flatShading: true });
  const thatchMat = new THREE.MeshStandardMaterial({ name: 'thatch', color: 0xb08645, roughness: 1, flatShading: true });
  const thatchDarkMat = new THREE.MeshStandardMaterial({ name: 'thatchDark', color: 0x99743a, roughness: 1, flatShading: true });
  const woodMat = new THREE.MeshStandardMaterial({ name: 'wood', color: 0x6a4a30, roughness: 0.9, flatShading: true });
  const darkMat = new THREE.MeshStandardMaterial({ name: 'dark', color: 0x2a201a, roughness: 1, flatShading: true });
  const stoneMat = new THREE.MeshStandardMaterial({ name: 'stone', color: 0x8b857c, roughness: 0.95, flatShading: true });
  const clayMat = new THREE.MeshStandardMaterial({ name: 'clay', color: 0xb4603e, roughness: 0.9, flatShading: true });
  const dirtMat = new THREE.MeshStandardMaterial({ name: 'dirt', color: 0xa88c64, roughness: 1, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.26, 1.53, 0.06);
  const boxGeo2 = new THREE.BoxGeometry(0.72, 0.08, 0.05);
  const boxGeo3 = new THREE.BoxGeometry(0.14, 1.79, 0.14);
  const boxGeo4 = new THREE.BoxGeometry(0.74, 0.08, 0.1);
  const boxGeo5 = new THREE.BoxGeometry(0.04, 0.5, 0.05);
  const cylinderGeo = new THREE.CylinderGeometry(0.04, 0.05, 1.1, 5);

  // Parts
  const dirtPatch = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(3.7, 1), 0.05, 2), dirtMat);
  dirtPatch.name = 'dirtPatch';
  dirtPatch.position.set(0, 0.1098, 0.3);
  dirtPatch.scale.set(1, 0.03, 1);
  root.add(dirtPatch);
  const plinth = new THREE.Mesh(new THREE.CylinderGeometry(2.26, 2.32, 0.4, 12), mudDarkMat);
  plinth.name = 'plinth';
  plinth.position.set(0, 0.26, 0);
  plinth.rotation.set(0, deg(15), 0);
  root.add(plinth);
  const walls = new THREE.Mesh(jitter(new THREE.CylinderGeometry(2.134, 2.2, 1.95, 12, 2), 0.025, 8), mudMat);
  walls.name = 'walls';
  walls.position.set(0, 1.035, 0);
  walls.rotation.set(0, deg(15), 0);
  root.add(walls);
  const baseStone = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.177, 0), 0.02, 41), stoneMat);
  baseStone.name = 'baseStone';
  baseStone.position.set(0.9071, 0.1131, 2.2436);
  baseStone.rotation.set(0, deg(34.4148), 0);
  baseStone.scale.set(1.2, 0.7, 1);
  root.add(baseStone);
  const baseStone2 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.2135, 0), 0.02, 42), stoneMat);
  baseStone2.name = 'baseStone';
  baseStone2.position.set(1.7048, 0.1571, 1.7176);
  baseStone2.rotation.set(0, deg(78.3076), 0);
  baseStone2.scale.set(1.2, 0.7, 1);
  root.add(baseStone2);
  const baseStone3 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1866, 0), 0.02, 43), stoneMat);
  baseStone3.name = 'baseStone';
  baseStone3.position.set(2.2123, 0.1191, 0.981);
  baseStone3.rotation.set(0, deg(69.8691), 0);
  baseStone3.scale.set(1.2, 0.7, 1);
  root.add(baseStone3);
  const baseStone4 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1804, 0), 0.02, 44), stoneMat);
  baseStone4.name = 'baseStone';
  baseStone4.position.set(2.417, 0.1343, 0.1204);
  baseStone4.rotation.set(0, deg(55.1928), 0);
  baseStone4.scale.set(1.2, 0.7, 1);
  root.add(baseStone4);
  const baseStone5 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1658, 0), 0.02, 45), stoneMat);
  baseStone5.name = 'baseStone';
  baseStone5.position.set(2.2588, 0.1104, -0.8686);
  baseStone5.rotation.set(0, deg(82.4452), 0);
  baseStone5.scale.set(1.2, 0.7, 1);
  root.add(baseStone5);
  const baseStone6 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1933, 0), 0.02, 46), stoneMat);
  baseStone6.name = 'baseStone';
  baseStone6.position.set(1.7897, 0.1289, -1.629);
  baseStone6.rotation.set(0, deg(74.0987), 0);
  baseStone6.scale.set(1.2, 0.7, 1);
  root.add(baseStone6);
  const baseStone7 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1893, 0), 0.02, 47), stoneMat);
  baseStone7.name = 'baseStone';
  baseStone7.position.set(1.084, 0.1273, -2.1636);
  baseStone7.rotation.set(0, deg(20.7889), 0);
  baseStone7.scale.set(1.2, 0.7, 1);
  root.add(baseStone7);
  const baseStone8 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1879, 0), 0.02, 48), stoneMat);
  baseStone8.name = 'baseStone';
  baseStone8.position.set(-0.0192, 0.1348, -2.4199);
  baseStone8.rotation.set(0, deg(8.8042), 0);
  baseStone8.scale.set(1.2, 0.7, 1);
  root.add(baseStone8);
  const baseStone9 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.2083, 0), 0.02, 49), stoneMat);
  baseStone9.name = 'baseStone';
  baseStone9.position.set(-0.9861, 0.1401, -2.21);
  baseStone9.rotation.set(0, deg(80.8509), 0);
  baseStone9.scale.set(1.2, 0.7, 1);
  root.add(baseStone9);
  const baseStone10 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1953, 0), 0.02, 50), stoneMat);
  baseStone10.name = 'baseStone';
  baseStone10.position.set(-1.7515, 0.1246, -1.67);
  baseStone10.rotation.set(0, deg(16.5162), 0);
  baseStone10.scale.set(1.2, 0.7, 1);
  root.add(baseStone10);
  const baseStone11 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1829, 0), 0.02, 51), stoneMat);
  baseStone11.name = 'baseStone';
  baseStone11.position.set(-2.2102, 0.1279, -0.9856);
  baseStone11.rotation.set(0, deg(28.034), 0);
  baseStone11.scale.set(1.2, 0.7, 1);
  root.add(baseStone11);
  const baseStone12 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1855, 0), 0.02, 52), stoneMat);
  baseStone12.name = 'baseStone';
  baseStone12.position.set(-2.4194, 0.1399, 0.0525);
  baseStone12.rotation.set(0, deg(34.9767), 0);
  baseStone12.scale.set(1.2, 0.7, 1);
  root.add(baseStone12);
  const baseStone13 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1949, 0), 0.02, 53), stoneMat);
  baseStone13.name = 'baseStone';
  baseStone13.position.set(-2.1673, 0.138, 1.0767);
  baseStone13.rotation.set(0, deg(67.8013), 0);
  baseStone13.scale.set(1.2, 0.7, 1);
  root.add(baseStone13);
  const baseStone14 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.2119, 0), 0.02, 54), stoneMat);
  baseStone14.name = 'baseStone';
  baseStone14.position.set(-1.7612, 0.1343, 1.6596);
  baseStone14.rotation.set(0, deg(82.9309), 0);
  baseStone14.scale.set(1.2, 0.7, 1);
  root.add(baseStone14);
  const baseStone15 = new THREE.Mesh(jitter(new THREE.OctahedronGeometry(0.1984, 0), 0.02, 55), stoneMat);
  baseStone15.name = 'baseStone';
  baseStone15.position.set(-0.8196, 0.1402, 2.277);
  baseStone15.rotation.set(0, deg(11.4987), 0);
  baseStone15.scale.set(1.2, 0.7, 1);
  root.add(baseStone15);
  const doorOpening = new THREE.Mesh(new THREE.BoxGeometry(0.86, 1.65, 0.06), darkMat);
  doorOpening.name = 'doorOpening';
  doorOpening.position.set(0, 1.005, 2.125);
  root.add(doorOpening);
  const doorPlank = new THREE.Mesh(boxGeo, woodMat);
  doorPlank.name = 'doorPlank';
  doorPlank.position.set(-0.2706, 0.965, 2.165);
  doorPlank.rotation.set(0, 0, deg(-1.3211));
  root.add(doorPlank);
  const doorPlank2 = new THREE.Mesh(boxGeo, woodMat);
  doorPlank2.name = 'doorPlank';
  doorPlank2.position.set(-0.008, 0.965, 2.165);
  doorPlank2.rotation.set(0, 0, deg(0.6726));
  root.add(doorPlank2);
  const doorPlank3 = new THREE.Mesh(boxGeo, woodMat);
  doorPlank3.name = 'doorPlank';
  doorPlank3.position.set(0.2678, 0.965, 2.165);
  doorPlank3.rotation.set(0, 0, deg(0.8563));
  root.add(doorPlank3);
  const doorBrace = new THREE.Mesh(boxGeo2, darkMat);
  doorBrace.name = 'doorBrace';
  doorBrace.position.set(0, 0.66, 2.205);
  root.add(doorBrace);
  const doorBrace2 = new THREE.Mesh(boxGeo2, darkMat);
  doorBrace2.name = 'doorBrace';
  doorBrace2.position.set(0, 1.36, 2.205);
  root.add(doorBrace2);
  const doorPost = new THREE.Mesh(boxGeo3, woodMat);
  doorPost.name = 'doorPost';
  doorPost.position.set(-0.5, 0.955, 2.145);
  root.add(doorPost);
  const doorPost2 = new THREE.Mesh(boxGeo3, woodMat);
  doorPost2.name = 'doorPost';
  doorPost2.position.set(0.5, 0.955, 2.145);
  root.add(doorPost2);
  const lintel = new THREE.Mesh(new THREE.BoxGeometry(1.3, 0.16, 0.16), woodMat);
  lintel.name = 'lintel';
  lintel.position.set(0, 1.89, 2.155);
  lintel.rotation.set(0, 0, deg(2));
  root.add(lintel);
  const doorStep = new THREE.Mesh(new THREE.BoxGeometry(1.1, 0.08, 0.6), stoneMat);
  doorStep.name = 'doorStep';
  doorStep.position.set(0, 0.04, 2.425);
  root.add(doorStep);
  const window = new THREE.Group();
  window.name = 'window';
  window.position.set(2.125, 1.31, 0);
  window.rotation.set(0, deg(90), 0);
  root.add(window);
  const windowOpening = new THREE.Mesh(new THREE.BoxGeometry(0.6, 0.5, 0.06), darkMat);
  windowOpening.name = 'windowOpening';
  window.add(windowOpening);
  const windowSill = new THREE.Mesh(boxGeo4, woodMat);
  windowSill.name = 'windowSill';
  windowSill.position.set(0, -0.28, 0.04);
  window.add(windowSill);
  const windowHead = new THREE.Mesh(boxGeo4, woodMat);
  windowHead.name = 'windowHead';
  windowHead.position.set(0, 0.28, 0.04);
  window.add(windowHead);
  const windowBar = new THREE.Mesh(boxGeo5, woodMat);
  windowBar.name = 'windowBar';
  windowBar.position.set(-0.15, 0, 0.05);
  window.add(windowBar);
  const windowBar2 = new THREE.Mesh(boxGeo5, woodMat);
  windowBar2.name = 'windowBar';
  windowBar2.position.set(0, 0, 0.05);
  window.add(windowBar2);
  const windowBar3 = new THREE.Mesh(boxGeo5, woodMat);
  windowBar3.name = 'windowBar';
  windowBar3.position.set(0.15, 0, 0.05);
  window.add(windowBar3);
  const rafter = new THREE.Mesh(cylinderGeo, woodMat);
  rafter.name = 'rafter';
  rafter.position.set(0.8189, 2.03, 2.5203);
  rafter.rotation.set(deg(112.2196), deg(-25.8187), deg(-17.5052));
  root.add(rafter);
  const rafter2 = new THREE.Mesh(cylinderGeo, woodMat);
  rafter2.name = 'rafter';
  rafter2.position.set(2.1439, 2.03, 1.5576);
  rafter2.rotation.set(deg(46.5429), deg(-44.8048), deg(-87.5709));
  root.add(rafter2);
  const rafter3 = new THREE.Mesh(cylinderGeo, woodMat);
  rafter3.name = 'rafter';
  rafter3.position.set(2.65, 2.03, 0);
  rafter3.rotation.set(0, 0, deg(-118.8108));
  root.add(rafter3);
  const rafter4 = new THREE.Mesh(cylinderGeo, woodMat);
  rafter4.name = 'rafter';
  rafter4.position.set(2.1439, 2.03, -1.5576);
  rafter4.rotation.set(deg(-46.5429), deg(44.8048), deg(-87.5709));
  root.add(rafter4);
  const rafter5 = new THREE.Mesh(cylinderGeo, woodMat);
  rafter5.name = 'rafter';
  rafter5.position.set(0.8189, 2.03, -2.5203);
  rafter5.rotation.set(deg(-112.2196), deg(25.8187), deg(-17.5052));
  root.add(rafter5);
  const rafter6 = new THREE.Mesh(cylinderGeo, woodMat);
  rafter6.name = 'rafter';
  rafter6.position.set(-0.8189, 2.03, -2.5203);
  rafter6.rotation.set(deg(-112.2196), deg(-25.8187), deg(17.5052));
  root.add(rafter6);
  const rafter7 = new THREE.Mesh(cylinderGeo, woodMat);
  rafter7.name = 'rafter';
  rafter7.position.set(-2.1439, 2.03, -1.5576);
  rafter7.rotation.set(deg(-46.5429), deg(-44.8048), deg(87.5709));
  root.add(rafter7);
  const rafter8 = new THREE.Mesh(cylinderGeo, woodMat);
  rafter8.name = 'rafter';
  rafter8.position.set(-2.65, 2.03, 0);
  rafter8.rotation.set(0, 0, deg(118.8108));
  root.add(rafter8);
  const rafter9 = new THREE.Mesh(cylinderGeo, woodMat);
  rafter9.name = 'rafter';
  rafter9.position.set(-2.1439, 2.03, 1.5576);
  rafter9.rotation.set(deg(46.5429), deg(44.8048), deg(87.5709));
  root.add(rafter9);
  const rafter10 = new THREE.Mesh(cylinderGeo, woodMat);
  rafter10.name = 'rafter';
  rafter10.position.set(-0.8189, 2.03, 2.5203);
  rafter10.rotation.set(deg(112.2196), deg(25.8187), deg(17.5052));
  root.add(rafter10);
  const thatchRoof = new THREE.Mesh(jitter(lathe([[2.024, 0.35], [3, -0.25], [3.06, 0.04], [2.1312, 0.8681], [2.2612, 0.7981], [1.3656, 1.6135], [1.4956, 1.5435], [0.66, 2.359]], 14), 0.06, 13), thatchMat);
  thatchRoof.name = 'thatchRoof';
  thatchRoof.position.set(0, 2.01, 0);
  root.add(thatchRoof);
  const thatchCap = new THREE.Mesh(jitter(lathe([[0.396, 2.339], [0.96, 2.079], [1, 2.299], [0.231, 3.0667], [0.001, 3.37]], 12), 0.035, 17), thatchDarkMat);
  thatchCap.name = 'thatchCap';
  thatchCap.position.set(0, 2.01, 0);
  root.add(thatchCap);
  const binding = new THREE.Mesh(new THREE.TorusGeometry(0.4092, 0.05, 4, 10), woodMat);
  binding.name = 'binding';
  binding.position.set(0, 4.824, 0);
  binding.rotation.set(deg(90), 0, 0);
  root.add(binding);
  const topKnot = new THREE.Mesh(new THREE.ConeGeometry(0.12, 0.45, 6), thatchDarkMat);
  topKnot.name = 'topKnot';
  topKnot.position.set(0, 5.505, 0);
  root.add(topKnot);
  const topStick = new THREE.Mesh(new THREE.CylinderGeometry(0.035, 0.035, 0.6, 5), woodMat);
  topStick.name = 'topStick';
  topStick.position.set(0, 5.93, 0);
  root.add(topStick);
  const claypot = new THREE.Mesh(lathe([[0.001, 0], [0.16, 0.02], [0.24, 0.18], [0.2, 0.38], [0.12, 0.46], [0.14, 0.52]], 8), clayMat);
  claypot.name = 'claypot';
  claypot.position.set(0.95, 0.02, 2.675);
  root.add(claypot);
  const potOpening = new THREE.Mesh(new THREE.CylinderGeometry(0.13, 0.13, 0.02, 8), darkMat);
  potOpening.name = 'potOpening';
  potOpening.position.set(0.95, 0.53, 2.675);
  root.add(potOpening);
  const claypot2 = new THREE.Mesh(lathe([[0.001, 0], [0.128, 0.02], [0.192, 0.144], [0.16, 0.304], [0.096, 0.368], [0.112, 0.416]], 8), clayMat);
  claypot2.name = 'claypot';
  claypot2.position.set(1.35, 0.02, 2.375);
  root.add(claypot2);
  const potOpening2 = new THREE.Mesh(new THREE.CylinderGeometry(0.104, 0.104, 0.02, 8), darkMat);
  potOpening2.name = 'potOpening';
  potOpening2.position.set(1.35, 0.43, 2.375);
  root.add(potOpening2);
  const claypot3 = new THREE.Mesh(lathe([[0.001, 0], [0.104, 0.02], [0.156, 0.117], [0.13, 0.247], [0.078, 0.299], [0.091, 0.338]], 8), clayMat);
  claypot3.name = 'claypot';
  claypot3.position.set(1.15, 0.02, 3.075);
  root.add(claypot3);
  const potOpening3 = new THREE.Mesh(new THREE.CylinderGeometry(0.0845, 0.0845, 0.02, 8), darkMat);
  potOpening3.name = 'potOpening';
  potOpening3.position.set(1.15, 0.355, 3.075);
  root.add(potOpening3);
  const firewood = new THREE.Mesh(new THREE.CylinderGeometry(0.11, 0.11, 0.956, 6), woodMat);
  firewood.name = 'firewood';
  firewood.position.set(-2.9065, 0.11, 0.4159);
  firewood.rotation.set(deg(90), 0, deg(-3.4186));
  root.add(firewood);
  const firewood2 = new THREE.Mesh(new THREE.CylinderGeometry(0.11, 0.11, 0.907, 6), woodMat);
  firewood2.name = 'firewood';
  firewood2.position.set(-2.6941, 0.11, 0.3621);
  firewood2.rotation.set(deg(90), 0, deg(2.8938));
  root.add(firewood2);
  const firewood3 = new THREE.Mesh(new THREE.CylinderGeometry(0.11, 0.11, 1.0204, 6), woodMat);
  firewood3.name = 'firewood';
  firewood3.position.set(-2.445, 0.11, 0.3773);
  firewood3.rotation.set(deg(90), 0, deg(-4.7073));
  root.add(firewood3);
  const firewood4 = new THREE.Mesh(new THREE.CylinderGeometry(0.11, 0.11, 0.9429, 6), woodMat);
  firewood4.name = 'firewood';
  firewood4.position.set(-2.769, 0.3, 0.4471);
  firewood4.rotation.set(deg(90), 0, deg(2.4454));
  root.add(firewood4);
  const firewood5 = new THREE.Mesh(new THREE.CylinderGeometry(0.11, 0.11, 0.9491, 6), woodMat);
  firewood5.name = 'firewood';
  firewood5.position.set(-2.5846, 0.3, 0.3586);
  firewood5.rotation.set(deg(90), 0, deg(-2.5872));
  root.add(firewood5);
  const firewood6 = new THREE.Mesh(new THREE.CylinderGeometry(0.11, 0.11, 1.0643, 6), woodMat);
  firewood6.name = 'firewood';
  firewood6.position.set(-2.6662, 0.49, 0.3911);
  firewood6.rotation.set(deg(90), 0, deg(1.8375));
  root.add(firewood6);

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

export default createHut;

評価とコメント

—
まだ評価はありません。最初の評価をしてみましょう。
5
0
4
0
3
0
2
0
1
0

評価やコメントをするにはログインしてください。

0 件のコメント

まだコメントはありません。このモデルの使い方や改善できる点を共有しましょう。

関連モデル

同じカテゴリまたは似たタグ