Codels
2334 三角面5.43 × 7.10 × 5.32 m

在代码中使用

在编辑器中改编
自包含的 ES 模块,仅依赖 three。调用工厂函数,然后把返回的 group 添加到场景中。
/**
 * Palm Tree — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 2,334 · Size (W × H × D): 5.43 × 7.10 × 5.32 m
 *
 * Usage:
 *   import { createPalmTree } from './palm-tree.js';
 *   
 *   const model = createPalmTree();
 *   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);
}

export function createPalmTree() {
  const root = new THREE.Group();
  root.name = 'PalmTree';

  // Materials
  const barkMat = new THREE.MeshStandardMaterial({ name: 'bark', color: 0xa27c54, roughness: 0.95, flatShading: true });
  const barkDarkMat = new THREE.MeshStandardMaterial({ name: 'barkDark', color: 0x86653f, roughness: 0.95, flatShading: true });
  const leafMat = new THREE.MeshStandardMaterial({ name: 'leaf', color: 0x4e9a3a, roughness: 0.8, flatShading: true });
  const leafDarkMat = new THREE.MeshStandardMaterial({ name: 'leafDark', color: 0x428131, roughness: 0.85, flatShading: true });
  const huskMat = new THREE.MeshStandardMaterial({ name: 'husk', color: 0x5e3d22, roughness: 0.9, flatShading: true });

  // Shared geometries
  const extrudeGeo = extrude([[-0.03, 0], [1.04, 0], [0.988, 0.4082], [0.91, 0.2406], [0.728, 0.3627], [0.65, 0.2059], [0.468, 0.2964], [0.39, 0.1583], [0.208, 0.2085], [0.13, 0.0961], [-0.052, 0.092]], 0.025);
  const extrudeGeo2 = extrude([[-0.03, 0], [1.04, 0], [0.988, -0.4082], [0.91, -0.2406], [0.728, -0.3627], [0.65, -0.2059], [0.468, -0.2964], [0.39, -0.1583], [0.208, -0.2085], [0.13, -0.0961], [-0.052, -0.092]], 0.025);
  const extrudeGeo3 = extrude([[-0.03, 0], [1.04, 0], [0.988, 0.3768], [0.91, 0.2476], [0.728, 0.4167], [0.65, 0.2658], [0.468, 0.4353], [0.39, 0.2707], [0.208, 0.4325], [0.13, 0.2623], [-0.052, 0.4082]], 0.025);
  const extrudeGeo4 = extrude([[-0.03, 0], [1.04, 0], [0.988, -0.3768], [0.91, -0.2476], [0.728, -0.4167], [0.65, -0.2658], [0.468, -0.4353], [0.39, -0.2707], [0.208, -0.4325], [0.13, -0.2623], [-0.052, -0.4082]], 0.025);
  const extrudeGeo5 = extrude([[-0.03, 0], [1.04, 0], [0.988, 0.01], [0.91, 0.035], [0.728, 0.127], [0.65, 0.1143], [0.468, 0.2341], [0.39, 0.1722], [0.208, 0.316], [0.13, 0.2164], [-0.052, 0.3768]], 0.025);
  const extrudeGeo6 = extrude([[-0.03, 0], [1.04, 0], [0.988, -0.01], [0.91, -0.035], [0.728, -0.127], [0.65, -0.1143], [0.468, -0.2341], [0.39, -0.1722], [0.208, -0.316], [0.13, -0.2164], [-0.052, -0.3768]], 0.025);
  const sphereGeo = new THREE.SphereGeometry(0.184, 7, 5);

  // Parts
  const trunk1 = new THREE.Mesh(new THREE.CylinderGeometry(0.2322, 0.2862, 0.4666, 7, 1, true), barkDarkMat);
  trunk1.name = 'trunk1';
  trunk1.position.set(-0.5368, 0.2383, 0);
  trunk1.rotation.set(0, 0, deg(-0.8199));
  root.add(trunk1);
  const trunk2 = new THREE.Mesh(new THREE.CylinderGeometry(0.2254, 0.2778, 0.4819, 7, 1, true), barkMat);
  trunk2.name = 'trunk2';
  trunk2.position.set(-0.524, 0.6923, 0);
  trunk2.rotation.set(0, 0, deg(-2.3786));
  root.add(trunk2);
  const trunk3 = new THREE.Mesh(new THREE.CylinderGeometry(0.2186, 0.2695, 0.4826, 7, 1, true), barkDarkMat);
  trunk3.name = 'trunk3';
  trunk3.position.set(-0.4985, 1.1538, 0);
  trunk3.rotation.set(0, 0, deg(-3.9603));
  root.add(trunk3);
  const trunk4 = new THREE.Mesh(new THREE.CylinderGeometry(0.2118, 0.2611, 0.4837, 7, 1, true), barkMat);
  trunk4.name = 'trunk4';
  trunk4.position.set(-0.4601, 1.6154, 0);
  trunk4.rotation.set(0, 0, deg(-5.536));
  root.add(trunk4);
  const trunk5 = new THREE.Mesh(new THREE.CylinderGeometry(0.2051, 0.2527, 0.4851, 7, 1, true), barkDarkMat);
  trunk5.name = 'trunk5';
  trunk5.position.set(-0.409, 2.0769, 0);
  trunk5.rotation.set(0, 0, deg(-7.1033));
  root.add(trunk5);
  const trunk6 = new THREE.Mesh(new THREE.CylinderGeometry(0.1983, 0.2444, 0.4869, 7, 1, true), barkMat);
  trunk6.name = 'trunk6';
  trunk6.position.set(-0.3451, 2.5385, 0);
  trunk6.rotation.set(0, 0, deg(-8.66));
  root.add(trunk6);
  const trunk7 = new THREE.Mesh(new THREE.CylinderGeometry(0.1915, 0.236, 0.489, 7, 1, true), barkDarkMat);
  trunk7.name = 'trunk7';
  trunk7.position.set(-0.2684, 3, 0);
  trunk7.rotation.set(0, 0, deg(-10.204));
  root.add(trunk7);
  const trunk8 = new THREE.Mesh(new THREE.CylinderGeometry(0.1847, 0.2276, 0.4914, 7, 1, true), barkMat);
  trunk8.name = 'trunk8';
  trunk8.position.set(-0.1789, 3.4615, 0);
  trunk8.rotation.set(0, 0, deg(-11.7331));
  root.add(trunk8);
  const trunk9 = new THREE.Mesh(new THREE.CylinderGeometry(0.1779, 0.2193, 0.4942, 7, 1, true), barkDarkMat);
  trunk9.name = 'trunk9';
  trunk9.position.set(-0.0767, 3.9231, 0);
  trunk9.rotation.set(0, 0, deg(-13.2454));
  root.add(trunk9);
  const trunk10 = new THREE.Mesh(new THREE.CylinderGeometry(0.1711, 0.2109, 0.4972, 7, 1, true), barkMat);
  trunk10.name = 'trunk10';
  trunk10.position.set(0.0383, 4.3846, 0);
  trunk10.rotation.set(0, 0, deg(-14.7392));
  root.add(trunk10);
  const trunk11 = new THREE.Mesh(new THREE.CylinderGeometry(0.1643, 0.2025, 0.5007, 7, 1, true), barkDarkMat);
  trunk11.name = 'trunk11';
  trunk11.position.set(0.1662, 4.8462, 0);
  trunk11.rotation.set(0, 0, deg(-16.2128));
  root.add(trunk11);
  const trunk12 = new THREE.Mesh(new THREE.CylinderGeometry(0.1575, 0.1942, 0.5044, 7, 1, true), barkMat);
  trunk12.name = 'trunk12';
  trunk12.position.set(0.3067, 5.3077, 0);
  trunk12.rotation.set(0, 0, deg(-17.6647));
  root.add(trunk12);
  const trunk13 = new THREE.Mesh(new THREE.CylinderGeometry(0.1508, 0.1858, 0.5084, 7, 1, true), barkDarkMat);
  trunk13.name = 'trunk13';
  trunk13.position.set(0.4601, 5.7692, 0);
  trunk13.rotation.set(0, 0, deg(-19.0935));
  root.add(trunk13);
  const rootFlare = new THREE.Mesh(new THREE.CylinderGeometry(0.2835, 0.3915, 0.3, 7), barkDarkMat);
  rootFlare.name = 'rootFlare';
  rootFlare.position.set(-0.54, 0.15, 0);
  root.add(rootFlare);
  const crown = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.2511, 0), 0.0251, 5), huskMat);
  crown.name = 'crown';
  crown.position.set(0.54, 6.067, 0);
  root.add(crown);
  const frond1 = new THREE.Group();
  frond1.name = 'frond1';
  frond1.position.set(0.54, 6.0837, 0);
  frond1.rotation.set(0, deg(4.384), 0);
  root.add(frond1);
  const leaf1L = new THREE.Mesh(extrudeGeo, leafDarkMat);
  leaf1L.name = 'leaf1L';
  leaf1L.position.set(0.1004, 0, 0);
  leaf1L.rotation.set(deg(61.9547), deg(30.1076), deg(14.9614));
  frond1.add(leaf1L);
  const leaf1R = new THREE.Mesh(extrudeGeo2, leafDarkMat);
  leaf1R.name = 'leaf1R';
  leaf1R.position.set(0.1004, 0, 0);
  leaf1R.rotation.set(deg(118.0453), deg(30.1076), deg(-14.9614));
  frond1.add(leaf1R);
  const leaf2L = new THREE.Mesh(extrudeGeo3, leafDarkMat);
  leaf2L.name = 'leaf2L';
  leaf2L.position.set(0.9522, 0.5596, 0);
  leaf2L.rotation.set(deg(65.8986), deg(5.099), deg(2.2768));
  frond1.add(leaf2L);
  const leaf2R = new THREE.Mesh(extrudeGeo4, leafDarkMat);
  leaf2R.name = 'leaf2R';
  leaf2R.position.set(0.9522, 0.5596, 0);
  leaf2R.rotation.set(deg(114.1014), deg(5.099), deg(-2.2768));
  frond1.add(leaf2R);
  const leaf3L = new THREE.Mesh(extrudeGeo5, leafDarkMat);
  leaf3L.name = 'leaf3L';
  leaf3L.position.set(1.9666, 0.6588, 0);
  leaf3L.rotation.set(deg(58.0254), deg(-39.8173), deg(-21.7883));
  frond1.add(leaf3L);
  const leaf3R = new THREE.Mesh(extrudeGeo6, leafDarkMat);
  leaf3R.name = 'leaf3R';
  leaf3R.position.set(1.9666, 0.6588, 0);
  leaf3R.rotation.set(deg(121.9746), deg(-39.8173), deg(21.7883));
  frond1.add(leaf3R);
  const frond2 = new THREE.Group();
  frond2.name = 'frond2';
  frond2.position.set(0.54, 6.0837, 0);
  frond2.rotation.set(0, deg(49.4217), 0);
  root.add(frond2);
  const leaf1L2 = new THREE.Mesh(extrudeGeo, leafMat);
  leaf1L2.name = 'leaf1L';
  leaf1L2.position.set(0.1004, 0, 0);
  leaf1L2.rotation.set(deg(62.4351), deg(28.484), deg(13.9797));
  frond2.add(leaf1L2);
  const leaf1R2 = new THREE.Mesh(extrudeGeo2, leafMat);
  leaf1R2.name = 'leaf1R';
  leaf1R2.position.set(0.1004, 0, 0);
  leaf1R2.rotation.set(deg(117.5649), deg(28.484), deg(-13.9797));
  frond2.add(leaf1R2);
  const leaf2L2 = new THREE.Mesh(extrudeGeo3, leafMat);
  leaf2L2.name = 'leaf2L';
  leaf2L2.position.set(0.9697, 0.5321, 0);
  leaf2L2.rotation.set(deg(65.9347), deg(4.0936), deg(1.826));
  frond2.add(leaf2L2);
  const leaf2R2 = new THREE.Mesh(extrudeGeo4, leafMat);
  leaf2R2.name = 'leaf2R';
  leaf2R2.position.set(0.9697, 0.5321, 0);
  leaf2R2.rotation.set(deg(114.0653), deg(4.0936), deg(-1.826));
  frond2.add(leaf2R2);
  const leaf3L2 = new THREE.Mesh(extrudeGeo5, leafMat);
  leaf3L2.name = 'leaf3L';
  leaf3L2.position.set(1.9858, 0.6117, 0);
  leaf3L2.rotation.set(deg(61.5421), deg(-31.3979), deg(-15.7682));
  frond2.add(leaf3L2);
  const leaf3R2 = new THREE.Mesh(extrudeGeo6, leafMat);
  leaf3R2.name = 'leaf3R';
  leaf3R2.position.set(1.9858, 0.6117, 0);
  leaf3R2.rotation.set(deg(118.4579), deg(-31.3979), deg(15.7682));
  frond2.add(leaf3R2);
  const frond3 = new THREE.Group();
  frond3.name = 'frond3';
  frond3.position.set(0.54, 6.0837, 0);
  frond3.rotation.set(0, deg(80.3901), 0);
  root.add(frond3);
  const leaf1L3 = new THREE.Mesh(extrudeGeo, leafDarkMat);
  leaf1L3.name = 'leaf1L';
  leaf1L3.position.set(0.1004, 0, 0);
  leaf1L3.rotation.set(deg(59.7099), deg(36.2532), deg(19.0561));
  frond3.add(leaf1L3);
  const leaf1R3 = new THREE.Mesh(extrudeGeo2, leafDarkMat);
  leaf1R3.name = 'leaf1R';
  leaf1R3.position.set(0.1004, 0, 0);
  leaf1R3.rotation.set(deg(120.2901), deg(36.2532), deg(-19.0561));
  frond3.add(leaf1R3);
  const leaf2L3 = new THREE.Mesh(extrudeGeo3, leafDarkMat);
  leaf2L3.name = 'leaf2L';
  leaf2L3.position.set(0.8773, 0.6597, 0);
  leaf2L3.rotation.set(deg(65.6853), deg(8.9489), deg(4.0203));
  frond3.add(leaf2L3);
  const leaf2R3 = new THREE.Mesh(extrudeGeo4, leafDarkMat);
  leaf2R3.name = 'leaf2R';
  leaf2R3.position.set(0.8773, 0.6597, 0);
  leaf2R3.rotation.set(deg(114.3147), deg(8.9489), deg(-4.0203));
  frond3.add(leaf2R3);
  const leaf3L3 = new THREE.Mesh(extrudeGeo5, leafDarkMat);
  leaf3L3.name = 'leaf3L';
  leaf3L3.position.set(1.8816, 0.8333, 0);
  leaf3L3.rotation.set(deg(58.9492), deg(-37.949), deg(-20.3169));
  frond3.add(leaf3L3);
  const leaf3R3 = new THREE.Mesh(extrudeGeo6, leafDarkMat);
  leaf3R3.name = 'leaf3R';
  leaf3R3.position.set(1.8816, 0.8333, 0);
  leaf3R3.rotation.set(deg(121.0508), deg(-37.949), deg(20.3169));
  frond3.add(leaf3R3);
  const frond4 = new THREE.Group();
  frond4.name = 'frond4';
  frond4.position.set(0.54, 6.0837, 0);
  frond4.rotation.set(0, deg(135.2108), 0);
  root.add(frond4);
  const leaf1L4 = new THREE.Mesh(extrudeGeo, leafMat);
  leaf1L4.name = 'leaf1L';
  leaf1L4.position.set(0.1004, 0, 0);
  leaf1L4.rotation.set(deg(63.53), deg(24.1439), deg(11.5118));
  frond4.add(leaf1L4);
  const leaf1R4 = new THREE.Mesh(extrudeGeo2, leafMat);
  leaf1R4.name = 'leaf1R';
  leaf1R4.position.set(0.1004, 0, 0);
  leaf1R4.rotation.set(deg(116.47), deg(24.1439), deg(-11.5118));
  frond4.add(leaf1R4);
  const leaf2L4 = new THREE.Mesh(extrudeGeo3, leafMat);
  leaf2L4.name = 'leaf2L';
  leaf2L4.position.set(1.0118, 0.4563, 0);
  leaf2L4.rotation.set(deg(65.9921), deg(1.4244), deg(0.6343));
  frond4.add(leaf2L4);
  const leaf2R4 = new THREE.Mesh(extrudeGeo4, leafMat);
  leaf2R4.name = 'leaf2R';
  leaf2R4.position.set(1.0118, 0.4563, 0);
  leaf2R4.rotation.set(deg(114.0079), deg(1.4244), deg(-0.6343));
  frond4.add(leaf2R4);
  const leaf3L4 = new THREE.Mesh(extrudeGeo5, leafMat);
  leaf3L4.name = 'leaf3L';
  leaf3L4.position.set(2.0306, 0.4841, 0);
  leaf3L4.rotation.set(deg(55.2653), deg(-44.4508), deg(-25.8983));
  frond4.add(leaf3L4);
  const leaf3R4 = new THREE.Mesh(extrudeGeo6, leafMat);
  leaf3R4.name = 'leaf3R';
  leaf3R4.position.set(2.0306, 0.4841, 0);
  leaf3R4.rotation.set(deg(124.7347), deg(-44.4508), deg(25.8983));
  frond4.add(leaf3R4);
  const frond5 = new THREE.Group();
  frond5.name = 'frond5';
  frond5.position.set(0.54, 6.0837, 0);
  frond5.rotation.set(0, deg(173.2544), 0);
  root.add(frond5);
  const leaf1L5 = new THREE.Mesh(extrudeGeo, leafDarkMat);
  leaf1L5.name = 'leaf1L';
  leaf1L5.position.set(0.1004, 0, 0);
  leaf1L5.rotation.set(deg(61.2549), deg(32.2467), deg(16.3129));
  frond5.add(leaf1L5);
  const leaf1R5 = new THREE.Mesh(extrudeGeo2, leafDarkMat);
  leaf1R5.name = 'leaf1R';
  leaf1R5.position.set(0.1004, 0, 0);
  leaf1R5.rotation.set(deg(118.7451), deg(32.2467), deg(-16.3129));
  frond5.add(leaf1R5);
  const leaf2L5 = new THREE.Mesh(extrudeGeo3, leafDarkMat);
  leaf2L5.name = 'leaf2L';
  leaf2L5.position.set(0.9277, 0.5953, 0);
  leaf2L5.rotation.set(deg(65.8384), deg(6.4305), deg(2.8763));
  frond5.add(leaf2L5);
  const leaf2R5 = new THREE.Mesh(extrudeGeo4, leafDarkMat);
  leaf2R5.name = 'leaf2R';
  leaf2R5.position.set(0.9277, 0.5953, 0);
  leaf2R5.rotation.set(deg(114.1616), deg(6.4305), deg(-2.8763));
  frond5.add(leaf2R5);
  const leaf3L5 = new THREE.Mesh(extrudeGeo5, leafDarkMat);
  leaf3L5.name = 'leaf3L';
  leaf3L5.position.set(1.9392, 0.7202, 0);
  leaf3L5.rotation.set(deg(59.6284), deg(-36.4425), deg(-19.1936));
  frond5.add(leaf3L5);
  const leaf3R5 = new THREE.Mesh(extrudeGeo6, leafDarkMat);
  leaf3R5.name = 'leaf3R';
  leaf3R5.position.set(1.9392, 0.7202, 0);
  leaf3R5.rotation.set(deg(120.3716), deg(-36.4425), deg(19.1936));
  frond5.add(leaf3R5);
  const frond6 = new THREE.Group();
  frond6.name = 'frond6';
  frond6.position.set(0.54, 6.0837, 0);
  frond6.rotation.set(0, deg(214.8782), 0);
  root.add(frond6);
  const leaf1L6 = new THREE.Mesh(extrudeGeo, leafMat);
  leaf1L6.name = 'leaf1L';
  leaf1L6.position.set(0.1004, 0, 0);
  leaf1L6.rotation.set(deg(63.1676), deg(25.6979), deg(12.3718));
  frond6.add(leaf1L6);
  const leaf1R6 = new THREE.Mesh(extrudeGeo2, leafMat);
  leaf1R6.name = 'leaf1R';
  leaf1R6.position.set(0.1004, 0, 0);
  leaf1R6.rotation.set(deg(116.8324), deg(25.6979), deg(-12.3718));
  frond6.add(leaf1R6);
  const leaf2L6 = new THREE.Mesh(extrudeGeo3, leafMat);
  leaf2L6.name = 'leaf2L';
  leaf2L6.position.set(0.9975, 0.4838, 0);
  leaf2L6.rotation.set(deg(65.978), deg(2.3773), deg(1.0591));
  frond6.add(leaf2L6);
  const leaf2R6 = new THREE.Mesh(extrudeGeo4, leafMat);
  leaf2R6.name = 'leaf2R';
  leaf2R6.position.set(0.9975, 0.4838, 0);
  leaf2R6.rotation.set(deg(114.022), deg(2.3773), deg(-1.0591));
  frond6.add(leaf2R6);
  const leaf3L6 = new THREE.Mesh(extrudeGeo5, leafMat);
  leaf3L6.name = 'leaf3L';
  leaf3L6.position.set(2.0157, 0.5301, 0);
  leaf3L6.rotation.set(deg(56.7727), deg(-42.0746), deg(-23.6993));
  frond6.add(leaf3L6);
  const leaf3R6 = new THREE.Mesh(extrudeGeo6, leafMat);
  leaf3R6.name = 'leaf3R';
  leaf3R6.position.set(2.0157, 0.5301, 0);
  leaf3R6.rotation.set(deg(123.2273), deg(-42.0746), deg(23.6993));
  frond6.add(leaf3R6);
  const frond7 = new THREE.Group();
  frond7.name = 'frond7';
  frond7.position.set(0.54, 6.0837, 0);
  frond7.rotation.set(0, deg(269.735), 0);
  root.add(frond7);
  const leaf1L7 = new THREE.Mesh(extrudeGeo, leafDarkMat);
  leaf1L7.name = 'leaf1L';
  leaf1L7.position.set(0.1004, 0, 0);
  leaf1L7.rotation.set(deg(60.9388), deg(33.1387), deg(16.8981));
  frond7.add(leaf1L7);
  const leaf1R7 = new THREE.Mesh(extrudeGeo2, leafDarkMat);
  leaf1R7.name = 'leaf1R';
  leaf1R7.position.set(0.1004, 0, 0);
  leaf1R7.rotation.set(deg(119.0612), deg(33.1387), deg(-16.8981));
  frond7.add(leaf1R7);
  const leaf2L7 = new THREE.Mesh(extrudeGeo3, leafDarkMat);
  leaf2L7.name = 'leaf2L';
  leaf2L7.position.set(0.917, 0.6099, 0);
  leaf2L7.rotation.set(deg(65.8089), deg(6.9882), deg(3.1284));
  frond7.add(leaf2L7);
  const leaf2R7 = new THREE.Mesh(extrudeGeo4, leafDarkMat);
  leaf2R7.name = 'leaf2R';
  leaf2R7.position.set(0.917, 0.6099, 0);
  leaf2R7.rotation.set(deg(114.1911), deg(6.9882), deg(-3.1284));
  frond7.add(leaf2R7);
  const leaf3L7 = new THREE.Mesh(extrudeGeo5, leafDarkMat);
  leaf3L7.name = 'leaf3L';
  leaf3L7.position.set(1.9271, 0.7456, 0);
  leaf3L7.rotation.set(deg(58.6217), deg(-38.6335), deg(-20.8454));
  frond7.add(leaf3L7);
  const leaf3R7 = new THREE.Mesh(extrudeGeo6, leafDarkMat);
  leaf3R7.name = 'leaf3R';
  leaf3R7.position.set(1.9271, 0.7456, 0);
  leaf3R7.rotation.set(deg(121.3783), deg(-38.6335), deg(20.8454));
  frond7.add(leaf3R7);
  const frond8 = new THREE.Group();
  frond8.name = 'frond8';
  frond8.position.set(0.54, 6.0837, 0);
  frond8.rotation.set(0, deg(305.6146), 0);
  root.add(frond8);
  const leaf1L8 = new THREE.Mesh(extrudeGeo, leafMat);
  leaf1L8.name = 'leaf1L';
  leaf1L8.position.set(0.1004, 0, 0);
  leaf1L8.rotation.set(deg(59.302), deg(37.1818), deg(19.7383));
  frond8.add(leaf1L8);
  const leaf1R8 = new THREE.Mesh(extrudeGeo2, leafMat);
  leaf1R8.name = 'leaf1R';
  leaf1R8.position.set(0.1004, 0, 0);
  leaf1R8.rotation.set(deg(120.698), deg(37.1818), deg(-19.7383));
  frond8.add(leaf1R8);
  const leaf2L8 = new THREE.Mesh(extrudeGeo3, leafMat);
  leaf2L8.name = 'leaf2L';
  leaf2L8.position.set(0.8647, 0.6742, 0);
  leaf2L8.rotation.set(deg(65.6419), deg(9.5381), deg(4.2903));
  frond8.add(leaf2L8);
  const leaf2R8 = new THREE.Mesh(extrudeGeo4, leafMat);
  leaf2R8.name = 'leaf2R';
  leaf2R8.position.set(0.8647, 0.6742, 0);
  leaf2R8.rotation.set(deg(114.3581), deg(9.5381), deg(-4.2903));
  frond8.add(leaf2R8);
  const leaf3L8 = new THREE.Mesh(extrudeGeo5, leafMat);
  leaf3L8.name = 'leaf3L';
  leaf3L8.position.set(1.867, 0.8591, 0);
  leaf3L8.rotation.set(deg(59.2931), deg(-37.2015), deg(-19.7529));
  frond8.add(leaf3L8);
  const leaf3R8 = new THREE.Mesh(extrudeGeo6, leafMat);
  leaf3R8.name = 'leaf3R';
  leaf3R8.position.set(1.867, 0.8591, 0);
  leaf3R8.rotation.set(deg(120.7069), deg(-37.2015), deg(19.7529));
  frond8.add(leaf3R8);
  const coconut1 = new THREE.Mesh(sphereGeo, huskMat);
  coconut1.name = 'coconut1';
  coconut1.position.set(0.7404, 5.8896, 0.0847);
  root.add(coconut1);
  const coconut2 = new THREE.Mesh(sphereGeo, huskMat);
  coconut2.name = 'coconut2';
  coconut2.position.set(0.3664, 5.8896, 0.1312);
  root.add(coconut2);
  const coconut3 = new THREE.Mesh(sphereGeo, huskMat);
  coconut3.name = 'coconut3';
  coconut3.position.set(0.5132, 5.8896, -0.216);
  root.add(coconut3);

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

export default createPalmTree;

评分与评论

—
暂无评分,快来抢先评分吧。
5
0
4
0
3
0
2
0
1
0

登录后即可评分和评论。

0 条评论

暂无评论。分享一下你是如何使用这个模型的,或者有哪些可以改进的地方。

相关模型

同一分类或相似标签