Codels
2K tris5.84 × 6.61 × 5.66 m

Use it in code

Remix in the editor
Self-contained ES module — only depends on three. Call the factory and add the group to your scene.
/**
 * Weeping Willow — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 2,002 · Size (W × H × D): 5.84 × 6.61 × 5.66 m
 *
 * Usage:
 *   import { createWillowTree } from './willow-tree.js';
 *   
 *   const model = createWillowTree();
 *   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 createWillowTree() {
  const root = new THREE.Group();
  root.name = 'WillowTree';

  // Materials
  const barkMat = new THREE.MeshStandardMaterial({ name: 'bark', color: 0x5f4a3a, roughness: 0.95, flatShading: true });
  const barkDarkMat = new THREE.MeshStandardMaterial({ name: 'barkDark', color: 0x4a392d, roughness: 0.95, flatShading: true });
  const leafMat = new THREE.MeshStandardMaterial({ name: 'leaf', color: 0x7fa244, roughness: 0.85, flatShading: true });
  const leafLightMat = new THREE.MeshStandardMaterial({ name: 'leafLight', color: 0x8bb65d, roughness: 0.85, flatShading: true });
  const leafDarkMat = new THREE.MeshStandardMaterial({ name: 'leafDark', color: 0x587d32, roughness: 0.9, flatShading: true });

  // Parts
  const trunk = new THREE.Mesh(lathe([[0, 0], [0.7378, 0], [0.5425, 0.35], [0.4557, 1.05], [0.4861, 1.736], [0.4123, 2.8], [0.3038, 3.22], [0, 3.22]], 7), barkMat);
  trunk.name = 'trunk';
  root.add(trunk);
  const root1 = new THREE.Mesh(new THREE.CylinderGeometry(0.0651, 0.2387, 0.9355, 5), barkDarkMat);
  root1.name = 'root1';
  root1.position.set(0.5867, 0.2062, 0.199);
  root1.rotation.set(deg(19.4815), deg(-23.323), deg(-100.4959));
  root.add(root1);
  const root2 = new THREE.Mesh(new THREE.CylinderGeometry(0.0651, 0.2387, 0.8926, 5), barkDarkMat);
  root2.name = 'root2';
  root2.position.set(0.1676, 0.2062, 0.573);
  root2.rotation.set(deg(103.1263), deg(-20.7676), deg(-16.5488));
  root.add(root2);
  const root3 = new THREE.Mesh(new THREE.CylinderGeometry(0.0651, 0.2387, 0.8875, 5), barkDarkMat);
  root3.name = 'root3';
  root3.position.set(-0.5941, 0.2062, 0.0171);
  root3.rotation.set(deg(1.5676), deg(2.1766), deg(108.4817));
  root.add(root3);
  const root4 = new THREE.Mesh(new THREE.CylinderGeometry(0.0651, 0.2387, 0.9768, 5), barkDarkMat);
  root4.name = 'root4';
  root4.position.set(-0.4312, 0.2062, -0.4745);
  root4.rotation.set(deg(-67.4606), deg(-39.9006), deg(57.0618));
  root.add(root4);
  const root5 = new THREE.Mesh(new THREE.CylinderGeometry(0.0651, 0.2387, 0.9876, 5), barkDarkMat);
  root5.name = 'root5';
  root5.position.set(0.4085, 0.2062, -0.5015);
  root5.rotation.set(deg(-73.001), deg(39.0161), deg(-51.1673));
  root.add(root5);
  const limb1 = new THREE.Mesh(new THREE.CylinderGeometry(0.0868, 0.2387, 3.2935, 5), barkMat);
  limb1.name = 'limb1';
  limb1.position.set(0.5951, 3.913, 0.5473);
  limb1.rotation.set(deg(19.453), deg(-3.6802), deg(-21.2311));
  root.add(limb1);
  const limb2 = new THREE.Mesh(new THREE.CylinderGeometry(0.0868, 0.2387, 3.4494, 5), barkMat);
  limb2.name = 'limb2';
  limb2.position.set(-0.3588, 3.9524, 0.7245);
  limb2.rotation.set(deg(24.8689), deg(2.6596), deg(12.0198));
  root.add(limb2);
  const limb3 = new THREE.Mesh(new THREE.CylinderGeometry(0.0868, 0.2387, 3.1548, 5), barkMat);
  limb3.name = 'limb3';
  limb3.position.set(-0.7327, 3.7424, -0.3418);
  limb3.rotation.set(deg(-12.5328), deg(-3.1042), deg(27.7226));
  root.add(limb3);
  const limb4 = new THREE.Mesh(new THREE.CylinderGeometry(0.0868, 0.2387, 2.9407, 5), barkMat);
  limb4.name = 'limb4';
  limb4.position.set(0.4803, 3.8693, -0.6503);
  limb4.rotation.set(deg(-26.3385), deg(4.5156), deg(-19.1291));
  root.add(limb4);
  const crownCore = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(1, 1), 0.06, 5), leafDarkMat);
  crownCore.name = 'crownCore';
  crownCore.position.set(0, 4.9, 0);
  crownCore.scale.set(2.352, 1.68, 2.352);
  root.add(crownCore);
  const crownRim1 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.9071, 0), 0.1088, 65), leafMat);
  crownRim1.name = 'crownRim1';
  crownRim1.position.set(2.0556, 5.1013, 0.099);
  crownRim1.rotation.set(deg(48.493), deg(199.7259), 0);
  crownRim1.scale.set(1, 0.62, 1);
  root.add(crownRim1);
  const crownRim2 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.7871, 0), 0.0945, 66), leafLightMat);
  crownRim2.name = 'crownRim2';
  crownRim2.position.set(1.5896, 5.0005, 1.3072);
  crownRim2.rotation.set(deg(7.3249), deg(83.1078), 0);
  crownRim2.scale.set(1, 0.62, 1);
  root.add(crownRim2);
  const crownRim3 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.9183, 0), 0.1102, 67), leafMat);
  crownRim3.name = 'crownRim3';
  crownRim3.position.set(0.5377, 5.1877, 1.9865);
  crownRim3.rotation.set(deg(5.6389), deg(359.2737), 0);
  crownRim3.scale.set(1, 0.62, 1);
  root.add(crownRim3);
  const crownRim4 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.8036, 0), 0.0964, 68), leafMat);
  crownRim4.name = 'crownRim4';
  crownRim4.position.set(-0.812, 5.1773, 1.891);
  crownRim4.rotation.set(deg(18.2571), deg(293.1892), 0);
  crownRim4.scale.set(1, 0.62, 1);
  root.add(crownRim4);
  const crownRim5 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.8709, 0), 0.1045, 69), leafLightMat);
  crownRim5.name = 'crownRim5';
  crownRim5.position.set(-1.9668, 5.2462, 0.6057);
  crownRim5.rotation.set(deg(24.8256), deg(338.5117), 0);
  crownRim5.scale.set(1, 0.62, 1);
  root.add(crownRim5);
  const crownRim6 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.9057, 0), 0.1087, 70), leafMat);
  crownRim6.name = 'crownRim6';
  crownRim6.position.set(-1.9057, 5.1515, -0.777);
  crownRim6.rotation.set(deg(19.7232), deg(303.1468), 0);
  crownRim6.scale.set(1, 0.62, 1);
  root.add(crownRim6);
  const crownRim7 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.8271, 0), 0.0992, 71), leafMat);
  crownRim7.name = 'crownRim7';
  crownRim7.position.set(-0.8401, 5.1443, -1.8787);
  crownRim7.rotation.set(deg(42.4054), deg(216.8137), 0);
  crownRim7.scale.set(1, 0.62, 1);
  root.add(crownRim7);
  const crownRim8 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.7784, 0), 0.0934, 72), leafLightMat);
  crownRim8.name = 'crownRim8';
  crownRim8.position.set(0.6355, 5.1426, -1.9574);
  crownRim8.rotation.set(deg(50.8301), deg(9.3264), 0);
  crownRim8.scale.set(1, 0.62, 1);
  root.add(crownRim8);
  const crownRim9 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.7802, 0), 0.0936, 73), leafMat);
  crownRim9.name = 'crownRim9';
  crownRim9.position.set(1.6893, 5.1869, -1.1754);
  crownRim9.rotation.set(deg(11.4885), deg(92.1976), 0);
  crownRim9.scale.set(1, 0.62, 1);
  root.add(crownRim9);
  const crownTop1 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.9309, 1), 0.0931, 85), leafLightMat);
  crownTop1.name = 'crownTop1';
  crownTop1.position.set(0.4169, 6.0004, -0.0789);
  crownTop1.rotation.set(deg(16.5319), deg(137.5261), 0);
  crownTop1.scale.set(1, 0.6, 1);
  root.add(crownTop1);
  const crownTop2 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.8868, 1), 0.0887, 86), leafMat);
  crownTop2.name = 'crownTop2';
  crownTop2.position.set(0.192, 5.9164, -0.7095);
  crownTop2.rotation.set(deg(39.0597), deg(68.3514), 0);
  crownTop2.scale.set(1, 0.6, 1);
  root.add(crownTop2);
  const crownTop3 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.8663, 1), 0.0866, 87), leafLightMat);
  crownTop3.name = 'crownTop3';
  crownTop3.position.set(-0.8924, 5.8324, -0.3225);
  crownTop3.rotation.set(deg(37.6333), deg(216.9541), 0);
  crownTop3.scale.set(1, 0.6, 1);
  root.add(crownTop3);
  const crownTop4 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.9735, 1), 0.0973, 88), leafMat);
  crownTop4.name = 'crownTop4';
  crownTop4.position.set(-0.3701, 5.7484, 1.06);
  crownTop4.rotation.set(deg(5.7245), deg(341.9506), 0);
  crownTop4.scale.set(1, 0.6, 1);
  root.add(crownTop4);
  const crownTop5 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.8963, 1), 0.0896, 89), leafLightMat);
  crownTop5.name = 'crownTop5';
  crownTop5.position.set(1.261, 5.6644, 0.175);
  crownTop5.rotation.set(deg(14.729), deg(325.4174), 0);
  crownTop5.scale.set(1, 0.6, 1);
  root.add(crownTop5);
  const crownTop6 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.9187, 1), 0.0919, 90), leafMat);
  crownTop6.name = 'crownTop6';
  crownTop6.position.set(0.6813, 5.5804, -1.2315);
  crownTop6.rotation.set(deg(33.4072), deg(28.1006), 0);
  crownTop6.scale.set(1, 0.6, 1);
  root.add(crownTop6);
  const strand1Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2164, 0.2381, 1.3538, 5, 1, true), leafMat);
  strand1Arch.name = 'strand1Arch';
  strand1Arch.position.set(2.2126, 4.4407, -0.1207);
  strand1Arch.rotation.set(deg(-1.5205), deg(5.854), deg(-150.9024));
  root.add(strand1Arch);
  const strand1 = new THREE.Mesh(new THREE.ConeGeometry(0.2251, 2.7436, 5), leafMat);
  strand1.name = 'strand1';
  strand1.position.set(2.5697, 2.5739, -0.1402);
  strand1.rotation.set(deg(0.4619), deg(-4.5734), deg(-176.5605));
  root.add(strand1);
  const strand2Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2065, 0.2272, 1.2182, 5, 1, true), leafLightMat);
  strand2Arch.name = 'strand2Arch';
  strand2Arch.position.set(2.1661, 4.6447, 0.4361);
  strand2Arch.rotation.set(deg(6.4559), deg(-20.9376), deg(-146.0532));
  root.add(strand2Arch);
  const strand2 = new THREE.Mesh(new THREE.ConeGeometry(0.2148, 2.8966, 5), leafLightMat);
  strand2.name = 'strand2';
  strand2.position.set(2.5149, 2.7707, 0.5064);
  strand2.rotation.set(deg(122.4701), deg(-85.9817), deg(-56.9159));
  root.add(strand2);
  const strand3Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2155, 0.237, 1.3043, 5, 1, true), leafMat);
  strand3Arch.name = 'strand3Arch';
  strand3Arch.position.set(1.9293, 4.4697, 1.0559);
  strand3Arch.rotation.set(deg(21.9482), deg(-52.3346), deg(-136.9269));
  root.add(strand3Arch);
  const strand3 = new THREE.Mesh(new THREE.ConeGeometry(0.2241, 2.3952, 5), leafMat);
  strand3.name = 'strand3';
  strand3.position.set(2.2195, 2.7953, 1.2147);
  strand3.rotation.set(deg(12.6896), deg(-78.0072), deg(-165.354));
  root.add(strand3);
  const strand4Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.1971, 0.2168, 1.2955, 5, 1, true), leafDarkMat);
  strand4Arch.name = 'strand4Arch';
  strand4Arch.position.set(1.8276, 4.5719, 1.297);
  strand4Arch.rotation.set(deg(39.4718), deg(-60.1072), deg(-116.3982));
  root.add(strand4Arch);
  const strand4 = new THREE.Mesh(new THREE.ConeGeometry(0.205, 2.3424, 5), leafDarkMat);
  strand4.name = 'strand4';
  strand4.position.set(2.1299, 2.9432, 1.5116);
  strand4.rotation.set(deg(173.4026), deg(-58.6752), deg(-5.3907));
  root.add(strand4);
  const strand5Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.1854, 0.2039, 1.2786, 5, 1, true), leafMat);
  strand5Arch.name = 'strand5Arch';
  strand5Arch.position.set(1.3718, 4.4879, 1.788);
  strand5Arch.rotation.set(deg(107.7265), deg(-61.4921), deg(-46.9557));
  root.add(strand5Arch);
  const strand5 = new THREE.Mesh(new THREE.ConeGeometry(0.1928, 2.9101, 5), leafMat);
  strand5.name = 'strand5';
  strand5.position.set(1.6155, 2.5875, 2.1056);
  strand5.rotation.set(deg(175.851), deg(-34.2545), deg(-2.5281));
  root.add(strand5);
  const strand6Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.22, 0.242, 1.2998, 5, 1, true), leafLightMat);
  strand6Arch.name = 'strand6Arch';
  strand6Arch.position.set(1.1511, 4.5849, 1.9452);
  strand6Arch.rotation.set(deg(123.4812), deg(-52.3117), deg(-29.5756));
  root.add(strand6Arch);
  const strand6 = new THREE.Mesh(new THREE.ConeGeometry(0.2288, 3.0574, 5), leafLightMat);
  strand6.name = 'strand6';
  strand6.position.set(1.3607, 2.624, 2.2993);
  strand6.rotation.set(deg(176.6102), deg(-13.9377), deg(-1.8009));
  root.add(strand6);
  const strand7Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2236, 0.246, 1.3773, 5, 1, true), leafMat);
  strand7Arch.name = 'strand7Arch';
  strand7Arch.position.set(0.7451, 4.4258, 2.1262);
  strand7Arch.rotation.set(deg(141.3418), deg(-35.0605), deg(-12.6451));
  root.add(strand7Arch);
  const strand7 = new THREE.Mesh(new THREE.ConeGeometry(0.2326, 2.2465, 5), leafMat);
  strand7.name = 'strand7';
  strand7.position.set(0.8707, 2.8197, 2.4846);
  strand7.rotation.set(deg(176.7724), deg(0.6699), deg(-1.135));
  root.add(strand7);
  const strand8Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.1837, 0.2021, 1.3227, 5, 1, true), leafDarkMat);
  strand8Arch.name = 'strand8Arch';
  strand8Arch.position.set(0.0013, 4.448, 2.2284);
  strand8Arch.rotation.set(deg(149.6172), deg(-0.0646), deg(-0.0175));
  root.add(strand8Arch);
  const strand8 = new THREE.Mesh(new THREE.ConeGeometry(0.191, 2.5412, 5), leafDarkMat);
  strand8.name = 'strand8';
  strand8.position.set(0.0016, 2.6884, 2.5926);
  strand8.rotation.set(deg(176.5667), deg(10.2855), deg(-0.0021));
  root.add(strand8);
  const strand9Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2189, 0.2408, 1.2926, 5, 1, true), leafMat);
  strand9Arch.name = 'strand9Arch';
  strand9Arch.position.set(-0.3232, 4.6377, 2.1853);
  strand9Arch.rotation.set(deg(149.0601), deg(15.6667), deg(4.361));
  root.add(strand9Arch);
  const strand9 = new THREE.Mesh(new THREE.ConeGeometry(0.2276, 2.7543, 5), leafMat);
  strand9.name = 'strand9';
  strand9.position.set(-0.3746, 2.7982, 2.5327);
  strand9.rotation.set(deg(176.1766), deg(40.3551), deg(0.6589));
  root.add(strand9);
  const strand10Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2073, 0.228, 1.3231, 5, 1, true), leafLightMat);
  strand10Arch.name = 'strand10Arch';
  strand10Arch.position.set(-0.771, 4.5351, 2.1082);
  strand10Arch.rotation.set(deg(140.4846), deg(36.3624), deg(13.4556));
  root.add(strand10Arch);
  const strand10 = new THREE.Mesh(new THREE.ConeGeometry(0.2156, 2.5137, 5), leafLightMat);
  strand10.name = 'strand10';
  strand10.position.set(-0.9014, 2.8129, 2.4648);
  strand10.rotation.set(deg(175.5884), deg(45.1815), deg(1.6723));
  root.add(strand10);
  const strand11Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2032, 0.2235, 1.3514, 5, 1, true), leafMat);
  strand11Arch.name = 'strand11Arch';
  strand11Arch.position.set(-1.3655, 4.5452, 1.7486);
  strand11Arch.rotation.set(deg(113.3144), deg(65.426), deg(45.8183));
  root.add(strand11Arch);
  const strand11 = new THREE.Mesh(new THREE.ConeGeometry(0.2113, 2.8094, 5), leafMat);
  strand11.name = 'strand11';
  strand11.position.set(-1.5885, 2.6408, 2.0342);
  strand11.rotation.set(deg(160.946), deg(82.5332), deg(16.4787));
  root.add(strand11);
  const strand12Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2233, 0.2456, 1.401, 5, 1, true), leafDarkMat);
  strand12Arch.name = 'strand12Arch';
  strand12Arch.position.set(-1.7252, 4.5024, 1.4418);
  strand12Arch.rotation.set(deg(54.6074), deg(65.7112), deg(102.7285));
  root.add(strand12Arch);
  const strand12 = new THREE.Mesh(new THREE.ConeGeometry(0.2322, 2.1717, 5), leafDarkMat);
  strand12.name = 'strand12';
  strand12.position.set(-2.0113, 2.9166, 1.6809);
  strand12.rotation.set(deg(-1.718), deg(10.4348), deg(177.3217));
  root.add(strand12);
  const strand13Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.1966, 0.2163, 1.3048, 5, 1, true), leafMat);
  strand13Arch.name = 'strand13Arch';
  strand13Arch.position.set(-1.9137, 4.5627, 1.1971);
  strand13Arch.rotation.set(deg(31.8611), deg(54.9256), deg(122.4502));
  root.add(strand13Arch);
  const strand13 = new THREE.Mesh(new THREE.ConeGeometry(0.2045, 2.8427, 5), leafMat);
  strand13.name = 'strand13';
  strand13.position.set(-2.2546, 2.6894, 1.4103);
  strand13.rotation.set(deg(2.0291), deg(52.8787), deg(175.1737));
  root.add(strand13);
  const strand14Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2177, 0.2395, 1.3593, 5, 1, true), leafLightMat);
  strand14Arch.name = 'strand14Arch';
  strand14Arch.position.set(-2.136, 4.407, 0.6332);
  strand14Arch.rotation.set(deg(9.564), deg(30.5229), deg(145.9083));
  root.add(strand14Arch);
  const strand14 = new THREE.Mesh(new THREE.ConeGeometry(0.2264, 2.7613, 5), leafLightMat);
  strand14.name = 'strand14';
  strand14.position.set(-2.4909, 2.5357, 0.7384);
  strand14.rotation.set(deg(-2.7279), deg(-27.9788), deg(176.2719));
  root.add(strand14);
  const strand15Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2102, 0.2312, 1.3734, 5, 1, true), leafMat);
  strand15Arch.name = 'strand15Arch';
  strand15Arch.position.set(-2.2479, 4.5586, 0.0988);
  strand15Arch.rotation.set(deg(1.3436), deg(4.6444), deg(147.746));
  root.add(strand15Arch);
  const strand15 = new THREE.Mesh(new THREE.ConeGeometry(0.2186, 2.7038, 5), leafMat);
  strand15.name = 'strand15';
  strand15.position.set(-2.6381, 2.7168, 0.1159);
  strand15.rotation.set(deg(-0.7015), deg(-9.1072), deg(176.5258));
  root.add(strand15);
  const strand16Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2134, 0.2347, 1.3503, 5, 1, true), leafDarkMat);
  strand16Arch.name = 'strand16Arch';
  strand16Arch.position.set(-2.2172, 4.4669, -0.4053);
  strand16Arch.rotation.set(deg(-6.019), deg(-18.9302), deg(144.9949));
  root.add(strand16Arch);
  const strand16 = new THREE.Mesh(new THREE.ConeGeometry(0.2219, 2.5875, 5), leafDarkMat);
  strand16.name = 'strand16';
  strand16.position.set(-2.6019, 2.7013, -0.4756);
  strand16.rotation.set(deg(-0.6717), deg(-20.8765), deg(176.3848));
  root.add(strand16);
  const strand17Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.223, 0.2453, 1.2354, 5, 1, true), leafMat);
  strand17Arch.name = 'strand17Arch';
  strand17Arch.position.set(-2.0715, 4.5893, -0.7883);
  strand17Arch.rotation.set(deg(-14.1829), deg(-37.6651), deg(139.9204));
  root.add(strand17Arch);
  const strand17 = new THREE.Mesh(new THREE.ConeGeometry(0.2319, 2.8625, 5), leafMat);
  strand17.name = 'strand17';
  strand17.position.set(-2.4096, 2.7363, -0.917);
  strand17.rotation.set(deg(-167.1702), deg(-74.4298), deg(12.0368));
  root.add(strand17);
  const strand18Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.1924, 0.2117, 1.2011, 5, 1, true), leafLightMat);
  strand18Arch.name = 'strand18Arch';
  strand18Arch.position.set(-1.8748, 4.6583, -1.1077);
  strand18Arch.rotation.set(deg(-25.0033), deg(-55.5336), deg(134.3251));
  root.add(strand18Arch);
  const strand18 = new THREE.Mesh(new THREE.ConeGeometry(0.2001, 2.4989, 5), leafLightMat);
  strand18.name = 'strand18';
  strand18.position.set(-2.1434, 2.9661, -1.2664);
  strand18.rotation.set(deg(-134.6417), deg(-85.7189), deg(43.6901));
  root.add(strand18);
  const strand19Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2206, 0.2426, 1.2972, 5, 1, true), leafMat);
  strand19Arch.name = 'strand19Arch';
  strand19Arch.position.set(-1.573, 4.6653, -1.571);
  strand19Arch.rotation.set(deg(-78.4734), deg(-67.7446), deg(78.8393));
  root.add(strand19Arch);
  const strand19 = new THREE.Mesh(new THREE.ConeGeometry(0.2294, 2.7495, 5), leafMat);
  strand19.name = 'strand19';
  strand19.position.set(-1.8313, 2.8349, -1.8289);
  strand19.rotation.set(deg(-174.4121), deg(-52.4239), deg(3.9848));
  root.add(strand19);
  const strand20Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.1929, 0.2122, 1.2636, 5, 1, true), leafDarkMat);
  strand20Arch.name = 'strand20Arch';
  strand20Arch.position.set(-1.1724, 4.6488, -1.8543);
  strand20Arch.rotation.set(deg(-130.6609), deg(-58.1658), deg(28.6613));
  root.add(strand20Arch);
  const strand20 = new THREE.Mesh(new THREE.ConeGeometry(0.2006, 2.8414, 5), leafDarkMat);
  strand20.name = 'strand20';
  strand20.position.set(-1.3533, 2.759, -2.1404);
  strand20.rotation.set(deg(-176.1438), deg(-27.4467), deg(2.0669));
  root.add(strand20);
  const strand21Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2089, 0.2298, 1.195, 5, 1, true), leafMat);
  strand21Arch.name = 'strand21Arch';
  strand21Arch.position.set(-0.8621, 4.5915, -1.9998);
  strand21Arch.rotation.set(deg(-142.8147), deg(-43.0163), deg(15.1027));
  root.add(strand21Arch);
  const strand21 = new THREE.Mesh(new THREE.ConeGeometry(0.2172, 2.3154, 5), leafMat);
  strand21.name = 'strand21';
  strand21.position.set(-0.9835, 3.0037, -2.2813);
  strand21.rotation.set(deg(-175.9429), deg(-33.6156), deg(1.6315));
  root.add(strand21);
  const strand22Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.1882, 0.207, 1.3142, 5, 1, true), leafLightMat);
  strand22Arch.name = 'strand22Arch';
  strand22Arch.position.set(-0.5184, 4.6702, -2.1898);
  strand22Arch.rotation.set(deg(-144.0065), deg(-24.2894), deg(7.9979));
  root.add(strand22Arch);
  const strand22 = new THREE.Mesh(new THREE.ConeGeometry(0.1957, 3.1379, 5), leafLightMat);
  strand22.name = 'strand22';
  strand22.position.set(-0.6115, 2.6341, -2.5828);
  strand22.rotation.set(deg(-177.3384), deg(40.6927), deg(1.0427));
  root.add(strand22);
  const strand23Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2063, 0.2269, 1.3634, 5, 1, true), leafMat);
  strand23Arch.name = 'strand23Arch';
  strand23Arch.position.set(0.0491, 4.5738, -2.238);
  strand23Arch.rotation.set(deg(-148.9652), deg(2.3329), deg(-0.6478));
  root.add(strand23Arch);
  const strand23 = new THREE.Mesh(new THREE.ConeGeometry(0.2146, 2.7124, 5), leafMat);
  strand23.name = 'strand23';
  strand23.position.set(0.0574, 2.7242, -2.6172);
  strand23.rotation.set(deg(-176.54), deg(19.8716), deg(-0.08));
  root.add(strand23);
  const strand24Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2064, 0.227, 1.2618, 5, 1, true), leafDarkMat);
  strand24Arch.name = 'strand24Arch';
  strand24Arch.position.set(0.7421, 4.5629, -2.0839);
  strand24Arch.rotation.set(deg(-143.1995), deg(35.9428), deg(-12.3173));
  root.add(strand24Arch);
  const strand24 = new THREE.Mesh(new THREE.ConeGeometry(0.2146, 2.2011, 5), leafDarkMat);
  strand24.name = 'strand24';
  strand24.position.set(0.8554, 3.012, -2.4019);
  strand24.rotation.set(deg(-172.7101), deg(74.1345), deg(-4.2149));
  root.add(strand24);
  const strand25Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2222, 0.2444, 1.2755, 5, 1, true), leafMat);
  strand25Arch.name = 'strand25Arch';
  strand25Arch.position.set(1.1041, 4.5504, -1.9025);
  strand25Arch.rotation.set(deg(-133.1512), deg(54.291), deg(-25.0483));
  root.add(strand25Arch);
  const strand25 = new THREE.Mesh(new THREE.ConeGeometry(0.2311, 2.8272, 5), leafMat);
  strand25.name = 'strand25';
  strand25.position.set(1.2768, 2.6809, -2.2);
  strand25.rotation.set(deg(-2.5404), deg(72.6113), deg(-174.2268));
  root.add(strand25);
  const strand26Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2008, 0.2208, 1.2042, 5, 1, true), leafLightMat);
  strand26Arch.name = 'strand26Arch';
  strand26Arch.position.set(1.3659, 4.4805, -1.724);
  strand26Arch.rotation.set(deg(-109.127), deg(64.6287), deg(-48.4668));
  root.add(strand26Arch);
  const strand26 = new THREE.Mesh(new THREE.ConeGeometry(0.2088, 2.8606, 5), leafLightMat);
  strand26.name = 'strand26';
  strand26.position.set(1.5801, 2.6231, -1.9942);
  strand26.rotation.set(deg(-3.096), deg(69.7441), deg(-173.8328));
  root.add(strand26);
  const strand27Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2171, 0.2388, 1.2948, 5, 1, true), leafMat);
  strand27Arch.name = 'strand27Arch';
  strand27Arch.position.set(1.772, 4.6294, -1.3349);
  strand27Arch.rotation.set(deg(-43.4493), deg(63.1538), deg(-114.0932));
  root.add(strand27Arch);
  const strand27 = new THREE.Mesh(new THREE.ConeGeometry(0.2258, 2.9122, 5), leafMat);
  strand27.name = 'strand27';
  strand27.position.set(2.0638, 2.7144, -1.5547);
  strand27.rotation.set(deg(0.5789), deg(28.4795), deg(-176.8803));
  root.add(strand27);
  const strand28Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.1963, 0.2159, 1.2359, 5, 1, true), leafDarkMat);
  strand28Arch.name = 'strand28Arch';
  strand28Arch.position.set(1.9759, 4.6203, -0.958);
  strand28Arch.rotation.set(deg(-18.4159), deg(47.2587), deg(-139.3375));
  root.add(strand28Arch);
  const strand28 = new THREE.Mesh(new THREE.ConeGeometry(0.2041, 2.9236, 5), leafDarkMat);
  strand28.name = 'strand28';
  strand28.position.set(2.2845, 2.7084, -1.1076);
  strand28.rotation.set(deg(1.2664), deg(4.309), deg(-176.9019));
  root.add(strand28);
  const strand29Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.1855, 0.2041, 1.2724, 5, 1, true), leafMat);
  strand29Arch.name = 'strand29Arch';
  strand29Arch.position.set(2.1866, 4.602, -0.4994);
  strand29Arch.rotation.set(deg(-7.7642), deg(23.4168), deg(-143.739));
  root.add(strand29Arch);
  const strand29 = new THREE.Mesh(new THREE.ConeGeometry(0.193, 2.8167, 5), leafMat);
  strand29.name = 'strand29';
  strand29.position.set(2.5638, 2.7448, -0.5856);
  strand29.rotation.set(deg(2.6758), deg(-29.6814), deg(-176.1464));
  root.add(strand29);
  const innerStrand1Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2015, 0.2216, 1.2617, 5, 1, true), leafMat);
  innerStrand1Arch.name = 'innerStrand1Arch';
  innerStrand1Arch.position.set(1.5977, 4.617, 0.4156);
  innerStrand1Arch.rotation.set(deg(7.7887), deg(-27.2297), deg(-148.6024));
  root.add(innerStrand1Arch);
  const innerStrand1 = new THREE.Mesh(new THREE.ConeGeometry(0.2095, 2.1904, 5), leafMat);
  innerStrand1.name = 'innerStrand1';
  innerStrand1.position.set(1.9067, 3.0584, 0.496);
  innerStrand1.rotation.set(deg(141.476), deg(-84.5713), deg(-37.7833));
  root.add(innerStrand1);
  const innerStrand2Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.1964, 0.216, 1.2443, 5, 1, true), leafDarkMat);
  innerStrand2Arch.name = 'innerStrand2Arch';
  innerStrand2Arch.position.set(1.3094, 4.573, 1.062);
  innerStrand2Arch.rotation.set(deg(51.9109), deg(-63.8185), deg(-103.9671));
  root.add(innerStrand2Arch);
  const innerStrand2 = new THREE.Mesh(new THREE.ConeGeometry(0.2043, 2.3124, 5), leafDarkMat);
  innerStrand2.name = 'innerStrand2';
  innerStrand2.position.set(1.5875, 2.9818, 1.2875);
  innerStrand2.rotation.set(deg(171.3503), deg(-67.5941), deg(-7.0097));
  root.add(innerStrand2);
  const innerStrand3Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.232, 0.2552, 1.2622, 5, 1, true), leafMat);
  innerStrand3Arch.name = 'innerStrand3Arch';
  innerStrand3Arch.position.set(0.5809, 4.6577, 1.5284);
  innerStrand3Arch.rotation.set(deg(146.3384), deg(-38.8024), deg(-12.1622));
  root.add(innerStrand3Arch);
  const innerStrand3 = new THREE.Mesh(new THREE.ConeGeometry(0.2413, 1.7529, 5), leafMat);
  innerStrand3.name = 'innerStrand3';
  innerStrand3.position.set(0.6842, 3.326, 1.8);
  innerStrand3.rotation.set(deg(176.2606), deg(-23.4633), deg(-1.3292));
  root.add(innerStrand3);
  const innerStrand4Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.1967, 0.2164, 1.2774, 5, 1, true), leafDarkMat);
  innerStrand4Arch.name = 'innerStrand4Arch';
  innerStrand4Arch.position.set(-0.3143, 4.633, 1.6682);
  innerStrand4Arch.rotation.set(deg(144.5774), deg(19.4589), deg(6.2685));
  root.add(innerStrand4Arch);
  const innerStrand4 = new THREE.Mesh(new THREE.ConeGeometry(0.2046, 1.8057, 5), leafDarkMat);
  innerStrand4.name = 'innerStrand4';
  innerStrand4.position.set(-0.3799, 3.2826, 2.0167);
  innerStrand4.rotation.set(deg(174.7252), deg(71.5111), deg(2.0037));
  root.add(innerStrand4);
  const innerStrand5Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2219, 0.2441, 1.2856, 5, 1, true), leafMat);
  innerStrand5Arch.name = 'innerStrand5Arch';
  innerStrand5Arch.position.set(-1.0848, 4.5698, 1.316);
  innerStrand5Arch.rotation.set(deg(100.195), deg(62.9575), deg(54.2249));
  root.add(innerStrand5Arch);
  const innerStrand5 = new THREE.Mesh(new THREE.ConeGeometry(0.2308, 2.2392, 5), leafMat);
  innerStrand5.name = 'innerStrand5';
  innerStrand5.position.set(-1.3237, 3.0189, 1.6057);
  innerStrand5.rotation.set(deg(160.3285), deg(82.5795), deg(17.1561));
  root.add(innerStrand5);
  const innerStrand6Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.1967, 0.2164, 1.2813, 5, 1, true), leafDarkMat);
  innerStrand6Arch.name = 'innerStrand6Arch';
  innerStrand6Arch.position.set(-1.5637, 4.6509, 0.706);
  innerStrand6Arch.rotation.set(deg(19.2176), deg(42.7294), deg(133.1964));
  root.add(innerStrand6Arch);
  const innerStrand6 = new THREE.Mesh(new THREE.ConeGeometry(0.2046, 1.928, 5), leafDarkMat);
  innerStrand6.name = 'innerStrand6';
  innerStrand6.position.set(-1.9068, 3.2498, 0.8609);
  innerStrand6.rotation.set(deg(1.6188), deg(44.0659), deg(175.6431));
  root.add(innerStrand6);
  const innerStrand7Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.225, 0.2475, 1.298, 5, 1, true), leafMat);
  innerStrand7Arch.name = 'innerStrand7Arch';
  innerStrand7Arch.position.set(-1.6593, 4.6387, -0.0497);
  innerStrand7Arch.rotation.set(deg(-0.8421), deg(-3.2108), deg(150.6165));
  root.add(innerStrand7Arch);
  const innerStrand7 = new THREE.Mesh(new THREE.ConeGeometry(0.234, 1.8693, 5), leafMat);
  innerStrand7.name = 'innerStrand7';
  innerStrand7.position.set(-1.9781, 3.2381, -0.0592);
  innerStrand7.rotation.set(deg(-11.6243), deg(-73.5605), deg(167.7876));
  root.add(innerStrand7);
  const innerStrand8Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2084, 0.2292, 1.3011, 5, 1, true), leafDarkMat);
  innerStrand8Arch.name = 'innerStrand8Arch';
  innerStrand8Arch.position.set(-1.4171, 4.6242, -0.8395);
  innerStrand8Arch.rotation.set(deg(-24.6102), deg(-55.9345), deg(135.3337));
  root.add(innerStrand8Arch);
  const innerStrand8 = new THREE.Mesh(new THREE.ConeGeometry(0.2167, 1.7695, 5), leafDarkMat);
  innerStrand8.name = 'innerStrand8';
  innerStrand8.position.set(-1.6779, 3.2553, -0.994);
  innerStrand8.rotation.set(deg(-22.9899), deg(-82.9718), deg(155.0939));
  root.add(innerStrand8);
  const innerStrand9Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.205, 0.2255, 1.3578, 5, 1, true), leafMat);
  innerStrand9Arch.name = 'innerStrand9Arch';
  innerStrand9Arch.position.set(-1.019, 4.5834, -1.3729);
  innerStrand9Arch.rotation.set(deg(-113.18), deg(-61.7188), deg(43.0232));
  root.add(innerStrand9Arch);
  const innerStrand9 = new THREE.Mesh(new THREE.ConeGeometry(0.2132, 2.2003, 5), leafMat);
  innerStrand9.name = 'innerStrand9';
  innerStrand9.position.set(-1.2446, 3.001, -1.6768);
  innerStrand9.rotation.set(deg(-175.9122), deg(-33.0055), deg(2.4395));
  root.add(innerStrand9);
  const innerStrand10Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2223, 0.2445, 1.332, 5, 1, true), leafDarkMat);
  innerStrand10Arch.name = 'innerStrand10Arch';
  innerStrand10Arch.position.set(-0.3455, 4.4921, -1.6148);
  innerStrand10Arch.rotation.set(deg(-150.9361), deg(-22.7315), deg(5.9654));
  root.add(innerStrand10Arch);
  const innerStrand10 = new THREE.Mesh(new THREE.ConeGeometry(0.2312, 1.7231, 5), leafDarkMat);
  innerStrand10.name = 'innerStrand10';
  innerStrand10.position.set(-0.4094, 3.1389, -1.9138);
  innerStrand10.rotation.set(deg(-176.4381), deg(-15.8684), deg(0.7464));
  root.add(innerStrand10);
  const innerStrand11Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2174, 0.2391, 1.3196, 5, 1, true), leafMat);
  innerStrand11Arch.name = 'innerStrand11Arch';
  innerStrand11Arch.position.set(0.5626, 4.5938, -1.5695);
  innerStrand11Arch.rotation.set(deg(-144.9779), deg(36.4781), deg(-11.8718));
  root.add(innerStrand11Arch);
  const innerStrand11 = new THREE.Mesh(new THREE.ConeGeometry(0.2261, 2.2024, 5), leafMat);
  innerStrand11.name = 'innerStrand11';
  innerStrand11.position.set(0.676, 3.0142, -1.8859);
  innerStrand11.rotation.set(deg(-175.4), deg(49.7302), deg(-1.7917));
  root.add(innerStrand11);
  const innerStrand12Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.2218, 0.244, 1.2712, 5, 1, true), leafDarkMat);
  innerStrand12Arch.name = 'innerStrand12Arch';
  innerStrand12Arch.position.set(1.2861, 4.5313, -1.0134);
  innerStrand12Arch.rotation.set(deg(-45.7166), deg(66.6782), deg(-114.6958));
  root.add(innerStrand12Arch);
  const innerStrand12 = new THREE.Mesh(new THREE.ConeGeometry(0.2307, 1.7513, 5), leafDarkMat);
  innerStrand12.name = 'innerStrand12';
  innerStrand12.position.set(1.516, 3.1908, -1.1946);
  innerStrand12.rotation.set(deg(0.0634), deg(37.3971), deg(-176.6053));
  root.add(innerStrand12);
  const innerStrand13Arch = new THREE.Mesh(new THREE.CylinderGeometry(0.217, 0.2387, 1.2308, 5, 1, true), leafMat);
  innerStrand13Arch.name = 'innerStrand13Arch';
  innerStrand13Arch.position.set(1.5785, 4.6488, -0.5351);
  innerStrand13Arch.rotation.set(deg(-11.9098), deg(34.161), deg(-142.4982));
  root.add(innerStrand13Arch);
  const innerStrand13 = new THREE.Mesh(new THREE.ConeGeometry(0.2257, 1.8058, 5), leafMat);
  innerStrand13.name = 'innerStrand13';
  innerStrand13.position.set(1.885, 3.3182, -0.639);
  innerStrand13.rotation.set(deg(2.7184), deg(-26.3822), deg(-176.3698));
  root.add(innerStrand13);

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

export default createWillowTree;

Ratings & comments

—
No ratings yet — be the first.
5
0
4
0
3
0
2
0
1
0

Sign in to rate and comment.

0 comments

No comments yet. Share how you used this model or what could be better.

Related models

Same category or similar tags