Codels
2,6 mil tris12,3 × 12,9 × 7,53 m
Módulo ES autocontido — depende apenas do three. Chame a factory e adicione o grupo à sua cena.
/**
 * Treehouse — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 2,556 · Size (W × H × D): 12.30 × 12.92 × 7.53 m
 *
 * Usage:
 *   import { createTreehouse } from './treehouse.js';
 *   
 *   const model = createTreehouse();
 *   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;
}

// 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);
}

// Tube along a smooth curve through the given points.
function tube(path, radius, tubularSegments, radialSegments, closed = false) {
  const curve = new THREE.CatmullRomCurve3(path.map(([x, y, z]) => new THREE.Vector3(x, y, z)), closed);
  return new THREE.TubeGeometry(curve, tubularSegments, radius, radialSegments, closed);
}

export function createTreehouse() {
  const root = new THREE.Group();
  root.name = 'Treehouse';

  // Materials
  const barkMat = new THREE.MeshStandardMaterial({ name: 'bark', color: 0x6b4a33, roughness: 0.95, flatShading: true });
  const woodMat = new THREE.MeshStandardMaterial({ name: 'wood', color: 0xb88a57, roughness: 0.9, flatShading: true });
  const woodDarkMat = new THREE.MeshStandardMaterial({ name: 'woodDark', color: 0x8a6038, roughness: 0.9, flatShading: true });
  const leavesMat = new THREE.MeshStandardMaterial({ name: 'leaves', color: 0x5ea34b, roughness: 0.9, flatShading: true });
  const leavesAltMat = new THREE.MeshStandardMaterial({ name: 'leavesAlt', color: 0x4e8f45, roughness: 0.9, flatShading: true });
  const roofMat = new THREE.MeshStandardMaterial({ name: 'roof', color: 0xc4573d, roughness: 0.85, flatShading: true });
  const ropeMat = new THREE.MeshStandardMaterial({ name: 'rope', color: 0xd9c597, roughness: 0.95, flatShading: true });
  const glassMat = new THREE.MeshStandardMaterial({ name: 'glass', color: 0xffd98a, roughness: 0.8, emissive: 0xf2b04a, emissiveIntensity: 0.5, flatShading: true });
  const grassMat = new THREE.MeshStandardMaterial({ name: 'grass', color: 0x6c9945, roughness: 0.95, flatShading: true });

  // Shared geometries
  const cylinderGeo = new THREE.CylinderGeometry(0.12, 0.3, 1.4481, 6);
  const boxGeo = new THREE.BoxGeometry(0.16, 0.22, 4.4);
  const boxGeo2 = new THREE.BoxGeometry(4.4, 0.22, 0.16);
  const boxGeo3 = new THREE.BoxGeometry(0.14, 2.6031, 0.14);
  const boxGeo4 = new THREE.BoxGeometry(2.82, 0.03, 0.02);
  const boxGeo5 = new THREE.BoxGeometry(0.02, 0.03, 2.32);
  const boxGeo6 = new THREE.BoxGeometry(0.14, 2.1, 0.14);
  const boxGeo7 = new THREE.BoxGeometry(3.4, 0.1, 1.924);
  const boxGeo8 = new THREE.BoxGeometry(3.42, 0.05, 0.6798);
  const boxGeo9 = new THREE.BoxGeometry(0.1, 0.95, 0.1);
  const boxGeo10 = new THREE.BoxGeometry(0.07, 3.32, 0.07);
  const boxGeo11 = new THREE.BoxGeometry(0.07, 4.36, 0.07);
  const boxGeo12 = new THREE.BoxGeometry(0.07, 1.67, 0.07);
  const boxGeo13 = new THREE.BoxGeometry(0.08, 5.228, 0.08);
  const boxGeo14 = new THREE.BoxGeometry(0.5, 0.05, 0.08);
  const boxGeo15 = new THREE.BoxGeometry(0.1, 1, 0.1);

  // Parts
  const grassPatch = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(3, 1), 0.05, 3), grassMat);
  grassPatch.name = 'grassPatch';
  grassPatch.position.set(0, 0.104, 0.3);
  grassPatch.scale.set(1, 0.035, 1);
  root.add(grassPatch);
  const trunk = new THREE.Mesh(jitter(new THREE.CylinderGeometry(0.4, 0.68, 9.6, 8), 0.04, 5), barkMat);
  trunk.name = 'trunk';
  trunk.position.set(0, 4.8332, 0);
  root.add(trunk);
  const root2 = new THREE.Mesh(cylinderGeo, barkMat);
  root2.name = 'root';
  root2.position.set(0.3602, 0.56, 0.852);
  root2.rotation.set(deg(116.4501), deg(-35.2152), deg(-22.243));
  root.add(root2);
  const root3 = new THREE.Mesh(cylinderGeo, barkMat);
  root3.name = 'root';
  root3.position.set(0.9216, 0.56, -0.0793);
  root3.rotation.set(deg(-3.9416), deg(7.8934), deg(-126.9838));
  root.add(root3);
  const root4 = new THREE.Mesh(cylinderGeo, barkMat);
  root4.name = 'root';
  root4.position.set(0.2094, 0.56, -0.901);
  root4.rotation.set(deg(-124.1817), deg(20.7594), deg(-11.083));
  root.add(root4);
  const root5 = new THREE.Mesh(cylinderGeo, barkMat);
  root5.name = 'root';
  root5.position.set(-0.7922, 0.56, -0.4775);
  root5.rotation.set(deg(-35.6553), deg(-45.3028), deg(104.7616));
  root.add(root5);
  const root6 = new THREE.Mesh(cylinderGeo, barkMat);
  root6.name = 'root';
  root6.position.set(-0.699, 0.56, 0.6059);
  root6.rotation.set(deg(59.1828), deg(52.7222), deg(82.2189));
  root.add(root6);
  const branch = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.24, 3.6287, 6), barkMat);
  branch.name = 'branch';
  branch.position.set(1.404, 7.5, -0.486);
  branch.rotation.set(deg(-13.242), deg(5.0272), deg(-41.4327));
  root.add(branch);
  const branch2 = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.24, 3.6426, 6), barkMat);
  branch2.name = 'branch';
  branch2.position.set(-1.35, 7.8, -0.648);
  branch2.rotation.set(deg(-17.7572), deg(-6.4112), deg(39.4485));
  root.add(branch2);
  const branch3 = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.24, 3.3409, 6), barkMat);
  branch3.name = 'branch';
  branch3.position.set(0.324, 8.8, -1.188);
  branch3.rotation.set(deg(-37.3582), deg(3.227), deg(-9.5257));
  root.add(branch3);
  const branch4 = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.24, 3.1004, 6), barkMat);
  branch4.name = 'branch';
  branch4.position.set(-0.486, 7.3, 0.864);
  branch4.rotation.set(deg(28.4188), deg(3.9545), deg(15.5275));
  root.add(branch4);
  const branch5 = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.24, 3.2405, 6), barkMat);
  branch5.name = 'branch';
  branch5.position.set(1.026, 9.2, 0.486);
  branch5.rotation.set(deg(14.8485), deg(-4.3858), deg(-32.7518));
  root.add(branch5);
  const leafCluster = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(1.9, 0), 0.19, 30), leavesMat);
  leafCluster.name = 'leafCluster';
  leafCluster.position.set(2.6, 8.8, -0.9);
  root.add(leafCluster);
  const leafCluster2 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(1.178, 0), 0.152, 60), leavesAltMat);
  leafCluster2.name = 'leafCluster';
  leafCluster2.position.set(2.3034, 9.845, -1.3243);
  root.add(leafCluster2);
  const leafCluster3 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(1.8, 0), 0.18, 31), leavesAltMat);
  leafCluster3.name = 'leafCluster';
  leafCluster3.position.set(-2.5, 9.1, -1.2);
  root.add(leafCluster3);
  const leafCluster4 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(1.116, 0), 0.144, 61), leavesMat);
  leafCluster4.name = 'leafCluster';
  leafCluster4.position.set(-2.3878, 10.09, -0.7586);
  root.add(leafCluster4);
  const leafCluster5 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(2, 0), 0.2, 32), leavesMat);
  leafCluster5.name = 'leafCluster';
  leafCluster5.position.set(0.6, 10.1, -2.2);
  root.add(leafCluster5);
  const leafCluster6 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(1.24, 0), 0.16, 62), leavesAltMat);
  leafCluster6.name = 'leafCluster';
  leafCluster6.position.set(0.1139, 11.2, -2.6863);
  root.add(leafCluster6);
  const leafCluster7 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(1.4, 0), 0.14, 33), leavesAltMat);
  leafCluster7.name = 'leafCluster';
  leafCluster7.position.set(-0.9, 8.6, 1.6);
  root.add(leafCluster7);
  const leafCluster8 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.868, 0), 0.112, 63), leavesMat);
  leafCluster8.name = 'leafCluster';
  leafCluster8.position.set(-0.6256, 9.37, 1.7401);
  root.add(leafCluster8);
  const leafCluster9 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(1.5, 0), 0.15, 34), leavesMat);
  leafCluster9.name = 'leafCluster';
  leafCluster9.position.set(1.9, 10.5, 0.9);
  root.add(leafCluster9);
  const leafCluster10 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.93, 0), 0.12, 64), leavesAltMat);
  leafCluster10.name = 'leafCluster';
  leafCluster10.position.set(1.9767, 11.325, 1.1365);
  root.add(leafCluster10);
  const leafCluster11 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(2.3, 0), 0.23, 35), leavesAltMat);
  leafCluster11.name = 'leafCluster';
  leafCluster11.position.set(0, 10.2, -0.4);
  root.add(leafCluster11);
  const leafCluster12 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(1.426, 0), 0.184, 65), leavesMat);
  leafCluster12.name = 'leafCluster';
  leafCluster12.position.set(-0.6574, 11.465, 0.0281);
  root.add(leafCluster12);
  const joist = new THREE.Mesh(boxGeo, woodDarkMat);
  joist.name = 'joist';
  joist.position.set(-1.9, 4.01, 0);
  root.add(joist);
  const joist2 = new THREE.Mesh(boxGeo, woodDarkMat);
  joist2.name = 'joist';
  joist2.position.set(1.9, 4.01, 0);
  root.add(joist2);
  const joist3 = new THREE.Mesh(boxGeo2, woodDarkMat);
  joist3.name = 'joist';
  joist3.position.set(0, 4.01, 0.75);
  root.add(joist3);
  const joist4 = new THREE.Mesh(boxGeo2, woodDarkMat);
  joist4.name = 'joist';
  joist4.position.set(0, 4.01, -0.75);
  root.add(joist4);
  const brace = new THREE.Mesh(boxGeo3, woodDarkMat);
  brace.name = 'brace';
  brace.position.set(-1.11, 3.125, -1.06);
  brace.rotation.set(deg(-59.1992), deg(28.9013), deg(39.0324));
  root.add(brace);
  const brace2 = new THREE.Mesh(boxGeo3, woodDarkMat);
  brace2.name = 'brace';
  brace2.position.set(-1.11, 3.125, 1.06);
  brace2.rotation.set(deg(-120.8008), deg(28.9013), deg(140.9676));
  root.add(brace2);
  const brace3 = new THREE.Mesh(boxGeo3, woodDarkMat);
  brace3.name = 'brace';
  brace3.position.set(1.11, 3.125, -1.06);
  brace3.rotation.set(deg(-59.1992), deg(-28.9013), deg(-39.0324));
  root.add(brace3);
  const brace4 = new THREE.Mesh(boxGeo3, woodDarkMat);
  brace4.name = 'brace';
  brace4.position.set(1.11, 3.125, 1.06);
  brace4.rotation.set(deg(-120.8008), deg(-28.9013), deg(-140.9676));
  root.add(brace4);
  const deckPlank = new THREE.Mesh(new THREE.BoxGeometry(4.3583, 0.08, 0.2893), woodMat);
  deckPlank.name = 'deckPlank';
  deckPlank.position.set(0.025, 4.16, -2.0429);
  deckPlank.rotation.set(0, deg(0.3659), 0);
  root.add(deckPlank);
  const deckPlank2 = new THREE.Mesh(new THREE.BoxGeometry(4.4075, 0.08, 0.2893), woodDarkMat);
  deckPlank2.name = 'deckPlank';
  deckPlank2.position.set(0.0497, 4.16, -1.7286);
  deckPlank2.rotation.set(0, deg(-0.6217), 0);
  root.add(deckPlank2);
  const deckPlank3 = new THREE.Mesh(new THREE.BoxGeometry(4.3532, 0.08, 0.2893), woodDarkMat);
  deckPlank3.name = 'deckPlank';
  deckPlank3.position.set(-0.0112, 4.16, -1.4143);
  deckPlank3.rotation.set(0, deg(-0.1708), 0);
  root.add(deckPlank3);
  const deckPlank4 = new THREE.Mesh(new THREE.BoxGeometry(4.3365, 0.08, 0.2893), woodMat);
  deckPlank4.name = 'deckPlank';
  deckPlank4.position.set(-0.01, 4.16, -1.1);
  deckPlank4.rotation.set(0, deg(-1.0699), 0);
  root.add(deckPlank4);
  const deckPlank5 = new THREE.Mesh(new THREE.BoxGeometry(4.3453, 0.08, 0.2893), woodMat);
  deckPlank5.name = 'deckPlank';
  deckPlank5.position.set(-0.0176, 4.16, -0.7857);
  deckPlank5.rotation.set(0, deg(-0.7919), 0);
  root.add(deckPlank5);
  const deckPlank6 = new THREE.Mesh(new THREE.BoxGeometry(4.4256, 0.08, 0.2893), woodMat);
  deckPlank6.name = 'deckPlank';
  deckPlank6.position.set(-0.0219, 4.16, -0.4714);
  deckPlank6.rotation.set(0, deg(0.0747), 0);
  root.add(deckPlank6);
  const deckPlank7 = new THREE.Mesh(new THREE.BoxGeometry(4.363, 0.08, 0.2893), woodMat);
  deckPlank7.name = 'deckPlank';
  deckPlank7.position.set(-0.01, 4.16, -0.1571);
  deckPlank7.rotation.set(0, deg(0.6077), 0);
  root.add(deckPlank7);
  const deckPlank8 = new THREE.Mesh(new THREE.BoxGeometry(4.321, 0.08, 0.2893), woodMat);
  deckPlank8.name = 'deckPlank';
  deckPlank8.position.set(0.0074, 4.16, 0.1571);
  deckPlank8.rotation.set(0, deg(0.0257), 0);
  root.add(deckPlank8);
  const deckPlank9 = new THREE.Mesh(new THREE.BoxGeometry(4.3159, 0.08, 0.2893), woodMat);
  deckPlank9.name = 'deckPlank';
  deckPlank9.position.set(0.0207, 4.16, 0.4714);
  deckPlank9.rotation.set(0, deg(-0.3028), 0);
  root.add(deckPlank9);
  const deckPlank10 = new THREE.Mesh(new THREE.BoxGeometry(4.3155, 0.08, 0.2893), woodMat);
  deckPlank10.name = 'deckPlank';
  deckPlank10.position.set(-0.0088, 4.16, 0.7857);
  deckPlank10.rotation.set(0, deg(0.8489), 0);
  root.add(deckPlank10);
  const deckPlank11 = new THREE.Mesh(new THREE.BoxGeometry(4.2969, 0.08, 0.2893), woodDarkMat);
  deckPlank11.name = 'deckPlank';
  deckPlank11.position.set(-0.0112, 4.16, 1.1);
  deckPlank11.rotation.set(0, deg(-0.662), 0);
  root.add(deckPlank11);
  const deckPlank12 = new THREE.Mesh(new THREE.BoxGeometry(4.3799, 0.08, 0.2893), woodMat);
  deckPlank12.name = 'deckPlank';
  deckPlank12.position.set(0.0257, 4.16, 1.4143);
  deckPlank12.rotation.set(0, deg(-1.1947), 0);
  root.add(deckPlank12);
  const deckPlank13 = new THREE.Mesh(new THREE.BoxGeometry(4.2872, 0.08, 0.2893), woodMat);
  deckPlank13.name = 'deckPlank';
  deckPlank13.position.set(0.002, 4.16, 1.7286);
  deckPlank13.rotation.set(0, deg(-0.1142), 0);
  root.add(deckPlank13);
  const deckPlank14 = new THREE.Mesh(new THREE.BoxGeometry(4.3807, 0.08, 0.2893), woodMat);
  deckPlank14.name = 'deckPlank';
  deckPlank14.position.set(-0.0456, 4.16, 2.0429);
  deckPlank14.rotation.set(0, deg(0.0852), 0);
  root.add(deckPlank14);
  const cabinWalls = new THREE.Mesh(new THREE.BoxGeometry(2.8, 2.1, 2.3), woodMat);
  cabinWalls.name = 'cabinWalls';
  cabinWalls.position.set(0, 5.25, -0.4);
  root.add(cabinWalls);
  const boardLine = new THREE.Mesh(boxGeo4, woodDarkMat);
  boardLine.name = 'boardLine';
  boardLine.position.set(0, 4.55, 0.76);
  root.add(boardLine);
  const boardLine2 = new THREE.Mesh(boxGeo5, woodDarkMat);
  boardLine2.name = 'boardLine';
  boardLine2.position.set(1.41, 4.55, -0.4);
  root.add(boardLine2);
  const boardLine3 = new THREE.Mesh(boxGeo5, woodDarkMat);
  boardLine3.name = 'boardLine';
  boardLine3.position.set(-1.41, 4.55, -0.4);
  root.add(boardLine3);
  const boardLine4 = new THREE.Mesh(boxGeo4, woodDarkMat);
  boardLine4.name = 'boardLine';
  boardLine4.position.set(0, 4.9, 0.76);
  root.add(boardLine4);
  const boardLine5 = new THREE.Mesh(boxGeo5, woodDarkMat);
  boardLine5.name = 'boardLine';
  boardLine5.position.set(1.41, 4.9, -0.4);
  root.add(boardLine5);
  const boardLine6 = new THREE.Mesh(boxGeo5, woodDarkMat);
  boardLine6.name = 'boardLine';
  boardLine6.position.set(-1.41, 4.9, -0.4);
  root.add(boardLine6);
  const boardLine7 = new THREE.Mesh(boxGeo4, woodDarkMat);
  boardLine7.name = 'boardLine';
  boardLine7.position.set(0, 5.25, 0.76);
  root.add(boardLine7);
  const boardLine8 = new THREE.Mesh(boxGeo5, woodDarkMat);
  boardLine8.name = 'boardLine';
  boardLine8.position.set(1.41, 5.25, -0.4);
  root.add(boardLine8);
  const boardLine9 = new THREE.Mesh(boxGeo5, woodDarkMat);
  boardLine9.name = 'boardLine';
  boardLine9.position.set(-1.41, 5.25, -0.4);
  root.add(boardLine9);
  const boardLine10 = new THREE.Mesh(boxGeo4, woodDarkMat);
  boardLine10.name = 'boardLine';
  boardLine10.position.set(0, 5.6, 0.76);
  root.add(boardLine10);
  const boardLine11 = new THREE.Mesh(boxGeo5, woodDarkMat);
  boardLine11.name = 'boardLine';
  boardLine11.position.set(1.41, 5.6, -0.4);
  root.add(boardLine11);
  const boardLine12 = new THREE.Mesh(boxGeo5, woodDarkMat);
  boardLine12.name = 'boardLine';
  boardLine12.position.set(-1.41, 5.6, -0.4);
  root.add(boardLine12);
  const boardLine13 = new THREE.Mesh(boxGeo4, woodDarkMat);
  boardLine13.name = 'boardLine';
  boardLine13.position.set(0, 5.95, 0.76);
  root.add(boardLine13);
  const boardLine14 = new THREE.Mesh(boxGeo5, woodDarkMat);
  boardLine14.name = 'boardLine';
  boardLine14.position.set(1.41, 5.95, -0.4);
  root.add(boardLine14);
  const boardLine15 = new THREE.Mesh(boxGeo5, woodDarkMat);
  boardLine15.name = 'boardLine';
  boardLine15.position.set(-1.41, 5.95, -0.4);
  root.add(boardLine15);
  const cornerPost = new THREE.Mesh(boxGeo6, woodDarkMat);
  cornerPost.name = 'cornerPost';
  cornerPost.position.set(-1.37, 5.25, -1.52);
  root.add(cornerPost);
  const cornerPost2 = new THREE.Mesh(boxGeo6, woodDarkMat);
  cornerPost2.name = 'cornerPost';
  cornerPost2.position.set(-1.37, 5.25, 0.72);
  root.add(cornerPost2);
  const cornerPost3 = new THREE.Mesh(boxGeo6, woodDarkMat);
  cornerPost3.name = 'cornerPost';
  cornerPost3.position.set(1.37, 5.25, -1.52);
  root.add(cornerPost3);
  const cornerPost4 = new THREE.Mesh(boxGeo6, woodDarkMat);
  cornerPost4.name = 'cornerPost';
  cornerPost4.position.set(1.37, 5.25, 0.72);
  root.add(cornerPost4);
  const cabinGables = new THREE.Mesh(extrude([[-1.15, 0], [1.15, 0], [0, 0.98]], 2.8), woodMat);
  cabinGables.name = 'cabinGables';
  cabinGables.position.set(0, 6.3, -0.4);
  cabinGables.rotation.set(0, deg(90), 0);
  root.add(cabinGables);
  const doorFrame = new THREE.Mesh(new THREE.BoxGeometry(0.86, 1.78, 0.06), woodDarkMat);
  doorFrame.name = 'doorFrame';
  doorFrame.position.set(-0.6, 5.09, 0.77);
  root.add(doorFrame);
  const door = new THREE.Mesh(new THREE.BoxGeometry(0.72, 1.7, 0.06), roofMat);
  door.name = 'door';
  door.position.set(-0.6, 5.05, 0.8);
  root.add(door);
  const doorKnob = new THREE.Mesh(new THREE.SphereGeometry(0.05, 6, 4), ropeMat);
  doorKnob.name = 'doorKnob';
  doorKnob.position.set(-0.36, 5.1, 0.85);
  root.add(doorKnob);
  const windowFrame = new THREE.Mesh(new THREE.BoxGeometry(0.66, 0.6, 0.05), woodDarkMat);
  windowFrame.name = 'windowFrame';
  windowFrame.position.set(0.65, 5.45, 0.77);
  root.add(windowFrame);
  const window = new THREE.Mesh(new THREE.BoxGeometry(0.5, 0.45, 0.05), glassMat);
  window.name = 'window';
  window.position.set(0.65, 5.45, 0.79);
  root.add(window);
  const windowCross = new THREE.Mesh(new THREE.BoxGeometry(0.04, 0.45, 0.06), woodDarkMat);
  windowCross.name = 'windowCross';
  windowCross.position.set(0.65, 5.45, 0.81);
  root.add(windowCross);
  const windowCross2 = new THREE.Mesh(new THREE.BoxGeometry(0.5, 0.04, 0.06), woodDarkMat);
  windowCross2.name = 'windowCross';
  windowCross2.position.set(0.65, 5.45, 0.81);
  root.add(windowCross2);
  const windowSill = new THREE.Mesh(new THREE.BoxGeometry(0.8, 0.06, 0.16), woodDarkMat);
  windowSill.name = 'windowSill';
  windowSill.position.set(0.65, 5.12, 0.83);
  root.add(windowSill);
  const roundWindowFrame = new THREE.Mesh(new THREE.CylinderGeometry(0.32, 0.32, 0.06, 10), woodDarkMat);
  roundWindowFrame.name = 'roundWindowFrame';
  roundWindowFrame.position.set(1.42, 5.5, -0.4);
  roundWindowFrame.rotation.set(0, 0, deg(90));
  root.add(roundWindowFrame);
  const roundWindow = new THREE.Mesh(new THREE.CylinderGeometry(0.24, 0.24, 0.06, 10), glassMat);
  roundWindow.name = 'roundWindow';
  roundWindow.position.set(1.44, 5.5, -0.4);
  roundWindow.rotation.set(0, 0, deg(90));
  root.add(roundWindow);
  const roofSlab = new THREE.Mesh(boxGeo7, roofMat);
  roofSlab.name = 'roofSlab';
  roofSlab.position.set(0, 6.7262, -1.1361);
  roofSlab.rotation.set(deg(-41.0091), 0, 0);
  root.add(roofSlab);
  const roofRow = new THREE.Mesh(boxGeo8, roofMat);
  roofRow.name = 'roofRow';
  roofRow.position.set(0, 7.2074, -0.7046);
  roofRow.rotation.set(deg(-46.0091), 0, 0);
  root.add(roofRow);
  const roofRow2 = new THREE.Mesh(boxGeo8, roofMat);
  roofRow2.name = 'roofRow';
  roofRow2.position.set(0, 6.7865, -1.1886);
  roofRow2.rotation.set(deg(-46.0091), 0, 0);
  root.add(roofRow2);
  const roofRow3 = new THREE.Mesh(boxGeo8, roofMat);
  roofRow3.name = 'roofRow';
  roofRow3.position.set(0, 6.3657, -1.6725);
  roofRow3.rotation.set(deg(-46.0091), 0, 0);
  root.add(roofRow3);
  const roofSlab2 = new THREE.Mesh(boxGeo7, roofMat);
  roofSlab2.name = 'roofSlab';
  roofSlab2.position.set(0, 6.7262, 0.3361);
  roofSlab2.rotation.set(deg(41.0091), 0, 0);
  root.add(roofSlab2);
  const roofRow4 = new THREE.Mesh(boxGeo8, roofMat);
  roofRow4.name = 'roofRow';
  roofRow4.position.set(0, 7.2074, -0.0954);
  roofRow4.rotation.set(deg(46.0091), 0, 0);
  root.add(roofRow4);
  const roofRow5 = new THREE.Mesh(boxGeo8, roofMat);
  roofRow5.name = 'roofRow';
  roofRow5.position.set(0, 6.7865, 0.3886);
  roofRow5.rotation.set(deg(46.0091), 0, 0);
  root.add(roofRow5);
  const roofRow6 = new THREE.Mesh(boxGeo8, roofMat);
  roofRow6.name = 'roofRow';
  roofRow6.position.set(0, 6.3657, 0.8725);
  roofRow6.rotation.set(deg(46.0091), 0, 0);
  root.add(roofRow6);
  const ridge = new THREE.Mesh(new THREE.BoxGeometry(3.5, 0.14, 0.14), woodDarkMat);
  ridge.name = 'ridge';
  ridge.position.set(0, 7.4988, -0.4);
  ridge.rotation.set(deg(45), 0, 0);
  root.add(ridge);
  const flagStick = new THREE.Mesh(new THREE.CylinderGeometry(0.025, 0.025, 1.2, 5), woodDarkMat);
  flagStick.name = 'flagStick';
  flagStick.position.set(1.6, 7.9, -0.4);
  root.add(flagStick);
  const pennant = new THREE.Mesh(extrude([[0, 0], [0.6, 0.14], [0, 0.32]], 0.02), roofMat);
  pennant.name = 'pennant';
  pennant.position.set(1.62, 8.12, -0.4);
  pennant.rotation.set(0, deg(-15), 0);
  root.add(pennant);
  const railPost = new THREE.Mesh(boxGeo9, woodDarkMat);
  railPost.name = 'railPost';
  railPost.position.set(-2.14, 4.675, 2.14);
  root.add(railPost);
  const railPost2 = new THREE.Mesh(boxGeo9, woodDarkMat);
  railPost2.name = 'railPost';
  railPost2.position.set(-1.07, 4.675, 2.14);
  root.add(railPost2);
  const railPost3 = new THREE.Mesh(boxGeo9, woodDarkMat);
  railPost3.name = 'railPost';
  railPost3.position.set(0, 4.675, 2.14);
  root.add(railPost3);
  const railPost4 = new THREE.Mesh(boxGeo9, woodDarkMat);
  railPost4.name = 'railPost';
  railPost4.position.set(1.1, 4.675, 2.14);
  root.add(railPost4);
  const railPost5 = new THREE.Mesh(boxGeo9, woodDarkMat);
  railPost5.name = 'railPost';
  railPost5.position.set(2.14, 4.675, 2.14);
  root.add(railPost5);
  const rail = new THREE.Mesh(boxGeo10, woodMat);
  rail.name = 'rail';
  rail.position.set(-0.52, 5.1, 2.14);
  rail.rotation.set(deg(-90), 0, deg(-90));
  root.add(rail);
  const rail2 = new THREE.Mesh(boxGeo10, woodMat);
  rail2.name = 'rail';
  rail2.position.set(-0.52, 4.65, 2.14);
  rail2.rotation.set(deg(-90), 0, deg(-90));
  root.add(rail2);
  const railPost6 = new THREE.Mesh(boxGeo9, woodDarkMat);
  railPost6.name = 'railPost';
  railPost6.position.set(2.14, 4.675, 1.07);
  root.add(railPost6);
  const railPost7 = new THREE.Mesh(boxGeo9, woodDarkMat);
  railPost7.name = 'railPost';
  railPost7.position.set(2.14, 4.675, 0);
  root.add(railPost7);
  const railPost8 = new THREE.Mesh(boxGeo9, woodDarkMat);
  railPost8.name = 'railPost';
  railPost8.position.set(2.14, 4.675, -1.07);
  root.add(railPost8);
  const railPost9 = new THREE.Mesh(boxGeo9, woodDarkMat);
  railPost9.name = 'railPost';
  railPost9.position.set(2.14, 4.675, -2.14);
  root.add(railPost9);
  const rail3 = new THREE.Mesh(boxGeo11, woodMat);
  rail3.name = 'rail';
  rail3.position.set(2.14, 5.1, 0);
  rail3.rotation.set(deg(-90), 0, 0);
  root.add(rail3);
  const rail4 = new THREE.Mesh(boxGeo11, woodMat);
  rail4.name = 'rail';
  rail4.position.set(2.14, 4.65, 0);
  rail4.rotation.set(deg(-90), 0, 0);
  root.add(rail4);
  const railPost10 = new THREE.Mesh(boxGeo9, woodDarkMat);
  railPost10.name = 'railPost';
  railPost10.position.set(1.07, 4.675, -2.14);
  root.add(railPost10);
  const railPost11 = new THREE.Mesh(boxGeo9, woodDarkMat);
  railPost11.name = 'railPost';
  railPost11.position.set(0, 4.675, -2.14);
  root.add(railPost11);
  const railPost12 = new THREE.Mesh(boxGeo9, woodDarkMat);
  railPost12.name = 'railPost';
  railPost12.position.set(-1.07, 4.675, -2.14);
  root.add(railPost12);
  const railPost13 = new THREE.Mesh(boxGeo9, woodDarkMat);
  railPost13.name = 'railPost';
  railPost13.position.set(-2.14, 4.675, -2.14);
  root.add(railPost13);
  const rail5 = new THREE.Mesh(boxGeo11, woodMat);
  rail5.name = 'rail';
  rail5.position.set(0, 5.1, -2.14);
  rail5.rotation.set(deg(-90), 0, deg(90));
  root.add(rail5);
  const railPost14 = new THREE.Mesh(boxGeo9, woodDarkMat);
  railPost14.name = 'railPost';
  railPost14.position.set(-2.14, 4.675, -1.07);
  root.add(railPost14);
  const railPost15 = new THREE.Mesh(boxGeo9, woodDarkMat);
  railPost15.name = 'railPost';
  railPost15.position.set(-2.14, 4.675, -0.55);
  root.add(railPost15);
  const railPost16 = new THREE.Mesh(boxGeo9, woodDarkMat);
  railPost16.name = 'railPost';
  railPost16.position.set(-2.14, 4.675, 0.55);
  root.add(railPost16);
  const railPost17 = new THREE.Mesh(boxGeo9, woodDarkMat);
  railPost17.name = 'railPost';
  railPost17.position.set(-2.14, 4.675, 1.07);
  root.add(railPost17);
  const rail6 = new THREE.Mesh(boxGeo12, woodMat);
  rail6.name = 'rail';
  rail6.position.set(-2.14, 5.1, -1.345);
  rail6.rotation.set(deg(-90), 0, deg(-180));
  root.add(rail6);
  const rail7 = new THREE.Mesh(boxGeo12, woodMat);
  rail7.name = 'rail';
  rail7.position.set(-2.14, 5.1, 1.345);
  rail7.rotation.set(deg(-90), 0, deg(-180));
  root.add(rail7);
  const ladder = new THREE.Group();
  ladder.name = 'ladder';
  ladder.position.set(1.62, 0, 0);
  root.add(ladder);
  const ladderRail = new THREE.Mesh(boxGeo13, woodDarkMat);
  ladderRail.name = 'ladderRail';
  ladderRail.position.set(-0.24, 2.55, 2.725);
  ladderRail.rotation.set(deg(-12.7071), 0, 0);
  ladder.add(ladderRail);
  const ladderRail2 = new THREE.Mesh(boxGeo13, woodDarkMat);
  ladderRail2.name = 'ladderRail';
  ladderRail2.position.set(0.24, 2.55, 2.725);
  ladderRail2.rotation.set(deg(-12.7071), 0, 0);
  ladder.add(ladderRail2);
  const ladderRung = new THREE.Mesh(boxGeo14, woodMat);
  ladderRung.name = 'ladderRung';
  ladderRung.position.set(0, 0.38, 3.2143);
  ladder.add(ladderRung);
  const ladderRung2 = new THREE.Mesh(boxGeo14, woodMat);
  ladderRung2.name = 'ladderRung';
  ladderRung2.position.set(0, 0.76, 3.1286);
  ladder.add(ladderRung2);
  const ladderRung3 = new THREE.Mesh(boxGeo14, woodMat);
  ladderRung3.name = 'ladderRung';
  ladderRung3.position.set(0, 1.14, 3.0429);
  ladder.add(ladderRung3);
  const ladderRung4 = new THREE.Mesh(boxGeo14, woodMat);
  ladderRung4.name = 'ladderRung';
  ladderRung4.position.set(0, 1.52, 2.9573);
  ladder.add(ladderRung4);
  const ladderRung5 = new THREE.Mesh(boxGeo14, woodMat);
  ladderRung5.name = 'ladderRung';
  ladderRung5.position.set(0, 1.9, 2.8716);
  ladder.add(ladderRung5);
  const ladderRung6 = new THREE.Mesh(boxGeo14, woodMat);
  ladderRung6.name = 'ladderRung';
  ladderRung6.position.set(0, 2.28, 2.7859);
  ladder.add(ladderRung6);
  const ladderRung7 = new THREE.Mesh(boxGeo14, woodMat);
  ladderRung7.name = 'ladderRung';
  ladderRung7.position.set(0, 2.66, 2.7002);
  ladder.add(ladderRung7);
  const ladderRung8 = new THREE.Mesh(boxGeo14, woodMat);
  ladderRung8.name = 'ladderRung';
  ladderRung8.position.set(0, 3.04, 2.6145);
  ladder.add(ladderRung8);
  const ladderRung9 = new THREE.Mesh(boxGeo14, woodMat);
  ladderRung9.name = 'ladderRung';
  ladderRung9.position.set(0, 3.42, 2.5288);
  ladder.add(ladderRung9);
  const ladderRung10 = new THREE.Mesh(boxGeo14, woodMat);
  ladderRung10.name = 'ladderRung';
  ladderRung10.position.set(0, 3.8, 2.4431);
  ladder.add(ladderRung10);
  const ladderRung11 = new THREE.Mesh(boxGeo14, woodMat);
  ladderRung11.name = 'ladderRung';
  ladderRung11.position.set(0, 4.18, 2.3575);
  ladder.add(ladderRung11);
  const ladderRung12 = new THREE.Mesh(boxGeo14, woodMat);
  ladderRung12.name = 'ladderRung';
  ladderRung12.position.set(0, 4.56, 2.2718);
  ladder.add(ladderRung12);
  const bridgePlank = new THREE.Mesh(new THREE.BoxGeometry(0.26, 0.05, 0.9575), woodMat);
  bridgePlank.name = 'bridgePlank';
  bridgePlank.position.set(-2.4, 4.0722, 0.0151);
  bridgePlank.rotation.set(deg(-0.9853), deg(0.7928), deg(23.427));
  root.add(bridgePlank);
  const bridgePlank2 = new THREE.Mesh(new THREE.BoxGeometry(0.26, 0.05, 0.9848), woodDarkMat);
  bridgePlank2.name = 'bridgePlank';
  bridgePlank2.position.set(-2.8, 3.91, 0.0272);
  bridgePlank2.rotation.set(deg(-1.1859), deg(3.0068), deg(20.1699));
  root.add(bridgePlank2);
  const bridgePlank3 = new THREE.Mesh(new THREE.BoxGeometry(0.26, 0.05, 0.9072), woodMat);
  bridgePlank3.name = 'bridgePlank';
  bridgePlank3.position.set(-3.2, 3.7858, -0.0259);
  bridgePlank3.rotation.set(deg(-0.9826), deg(3.7384), deg(13.7903));
  root.add(bridgePlank3);
  const bridgePlank4 = new THREE.Mesh(new THREE.BoxGeometry(0.26, 0.05, 0.9186), woodDarkMat);
  bridgePlank4.name = 'bridgePlank';
  bridgePlank4.position.set(-3.6, 3.7186, -0.0118);
  bridgePlank4.rotation.set(deg(0.0581), deg(-0.8492), deg(4.9261));
  root.add(bridgePlank4);
  const bridgePlank5 = new THREE.Mesh(new THREE.BoxGeometry(0.26, 0.05, 0.9797), woodDarkMat);
  bridgePlank5.name = 'bridgePlank';
  bridgePlank5.position.set(-4, 3.7186, 0.0271);
  bridgePlank5.rotation.set(deg(0.1337), deg(3.2062), deg(-4.9261));
  root.add(bridgePlank5);
  const bridgePlank6 = new THREE.Mesh(new THREE.BoxGeometry(0.26, 0.05, 1.0062), woodDarkMat);
  bridgePlank6.name = 'bridgePlank';
  bridgePlank6.position.set(-4.4, 3.7858, -0.0018);
  bridgePlank6.rotation.set(deg(0.0574), deg(-2.3236), deg(-13.7903));
  root.add(bridgePlank6);
  const bridgePlank7 = new THREE.Mesh(new THREE.BoxGeometry(0.26, 0.05, 0.9928), woodDarkMat);
  bridgePlank7.name = 'bridgePlank';
  bridgePlank7.position.set(-4.8, 3.91, -0.0268);
  bridgePlank7.rotation.set(deg(-0.5539), deg(0.7624), deg(-20.1699));
  root.add(bridgePlank7);
  const bridgePlank8 = new THREE.Mesh(new THREE.BoxGeometry(0.26, 0.05, 0.9897), woodMat);
  bridgePlank8.name = 'bridgePlank';
  bridgePlank8.position.set(-5.2, 4.0722, -0.0169);
  bridgePlank8.rotation.set(deg(-0.9977), deg(-3.6682), deg(-23.427));
  root.add(bridgePlank8);
  const bridgeRope = new THREE.Mesh(tube([[-2.2, 5.05, -0.5], [-3, 4.8273, -0.5], [-3.8, 4.735, -0.5], [-4.6, 4.8273, -0.5], [-5.4, 5.05, -0.5]], 0.025, 10, 3), ropeMat);
  bridgeRope.name = 'bridgeRope';
  root.add(bridgeRope);
  const bridgeRope2 = new THREE.Mesh(tube([[-2.2, 4.2, -0.5], [-3, 3.8818, -0.5], [-3.8, 3.75, -0.5], [-4.6, 3.8818, -0.5], [-5.4, 4.2, -0.5]], 0.025, 10, 3), ropeMat);
  bridgeRope2.name = 'bridgeRope';
  root.add(bridgeRope2);
  const bridgeRope3 = new THREE.Mesh(tube([[-2.2, 5.05, 0.5], [-3, 4.8273, 0.5], [-3.8, 4.735, 0.5], [-4.6, 4.8273, 0.5], [-5.4, 5.05, 0.5]], 0.025, 10, 3), ropeMat);
  bridgeRope3.name = 'bridgeRope';
  root.add(bridgeRope3);
  const bridgeRope4 = new THREE.Mesh(tube([[-2.2, 4.2, 0.5], [-3, 3.8818, 0.5], [-3.8, 3.75, 0.5], [-4.6, 3.8818, 0.5], [-5.4, 4.2, 0.5]], 0.025, 10, 3), ropeMat);
  bridgeRope4.name = 'bridgeRope';
  root.add(bridgeRope4);
  const landing = new THREE.Mesh(new THREE.BoxGeometry(1.3, 0.08, 1.4), woodMat);
  landing.name = 'landing';
  landing.position.set(-6, 4.16, 0);
  root.add(landing);
  const landingPost = new THREE.Mesh(boxGeo15, woodDarkMat);
  landingPost.name = 'landingPost';
  landingPost.position.set(-5.45, 4.62, -0.5);
  root.add(landingPost);
  const landingPost2 = new THREE.Mesh(boxGeo15, woodDarkMat);
  landingPost2.name = 'landingPost';
  landingPost2.position.set(-6.55, 4.62, -0.6);
  root.add(landingPost2);
  const landingPost3 = new THREE.Mesh(boxGeo15, woodDarkMat);
  landingPost3.name = 'landingPost';
  landingPost3.position.set(-5.45, 4.62, 0.5);
  root.add(landingPost3);
  const landingPost4 = new THREE.Mesh(boxGeo15, woodDarkMat);
  landingPost4.name = 'landingPost';
  landingPost4.position.set(-6.55, 4.62, 0.6);
  root.add(landingPost4);
  const landingRail = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.06, 1.3), woodMat);
  landingRail.name = 'landingRail';
  landingRail.position.set(-6.55, 5.05, 0);
  root.add(landingRail);
  const sideBranch = new THREE.Mesh(new THREE.CylinderGeometry(0.14, 0.32, 6.2169, 6), barkMat);
  sideBranch.name = 'sideBranch';
  sideBranch.position.set(-3.15, 2.84, 0.05);
  sideBranch.rotation.set(deg(-0.9217), deg(-0.604), deg(66.477));
  root.add(sideBranch);
  const leafCluster13 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.9, 0), 0.08, 77), leavesAltMat);
  leafCluster13.name = 'leafCluster';
  leafCluster13.position.set(-6.9, 4.7, -0.6);
  root.add(leafCluster13);

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

export default createTreehouse;

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