Codels
932 tris5,39 × 1,99 × 5,95 m
Módulo ES autocontido — depende apenas do three. Chame a factory e adicione o grupo à sua cena.
/**
 * Grassy Hill — Codels 3D model library
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 932 · Size (W × H × D): 5.39 × 1.99 × 5.95 m
 *
 * Usage:
 *   import { createHill } from './hill.js';
 *   
 *   const model = createHill();
 *   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 createHill() {
  const root = new THREE.Group();
  root.name = 'Hill';

  // Materials
  const grassMat = new THREE.MeshStandardMaterial({ name: 'grass', color: 0x6aae45, roughness: 0.9, flatShading: true });
  const grassLightMat = new THREE.MeshStandardMaterial({ name: 'grassLight', color: 0x6eb856, roughness: 0.9, flatShading: true });
  const grassDarkMat = new THREE.MeshStandardMaterial({ name: 'grassDark', color: 0x5b8836, roughness: 0.9, flatShading: true });
  const rockMat = new THREE.MeshStandardMaterial({ name: 'rock', color: 0x95918a, roughness: 0.9, flatShading: true });
  const rockDarkMat = new THREE.MeshStandardMaterial({ name: 'rockDark', color: 0x77736c, roughness: 0.95, flatShading: true });
  const petalMat = new THREE.MeshStandardMaterial({ name: 'petal', color: 0xfff3c4, roughness: 0.7, flatShading: true });
  const petalBlueMat = new THREE.MeshStandardMaterial({ name: 'petalBlue', color: 0x8fb4f5, roughness: 0.7, flatShading: true });

  // Shared geometries
  const cylinderGeo = new THREE.CylinderGeometry(0.012, 0.016, 0.2112, 4);
  const dodecahedronGeo = new THREE.DodecahedronGeometry(0.0549, 0);
  const coneGeo = new THREE.ConeGeometry(0.0338, 0.0845, 3);

  // Parts
  const hill = new THREE.Group();
  hill.name = 'hill';
  hill.position.set(0, 0.0589, 0);
  hill.rotation.set(0, deg(81.9581), 0);
  root.add(hill);
  const mound = new THREE.Mesh(jitter(lathe([[0, 0], [1, 0], [0.8571, 0.1048], [0.7143, 0.2972], [0.5714, 0.5107], [0.4286, 0.7082], [0.2857, 0.8652], [0.1429, 0.9656], [0, 1]], 14), 0.035, 3), grassMat);
  mound.name = 'mound';
  mound.scale.set(3, 1.8, 2.5094);
  hill.add(mound);
  const shoulder = new THREE.Mesh(jitter(lathe([[0, 0], [1, 0], [0.8, 0.1761], [0.6, 0.4683], [0.4, 0.7435], [0.2, 0.933], [0, 1]], 11), 0.05, 10), grassMat);
  shoulder.name = 'shoulder';
  shoulder.position.set(0.1688, 0, 1.2187);
  shoulder.scale.set(1.6904, 1.2571, 1.4369);
  hill.add(shoulder);
  const dressing = new THREE.Group();
  dressing.name = 'dressing';
  root.add(dressing);
  const tuft1 = new THREE.Group();
  tuft1.name = 'tuft1';
  tuft1.position.set(0.4813, 1.7038, -0.1137);
  dressing.add(tuft1);
  const cone6 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2945, 3), grassDarkMat);
  cone6.position.set(0.0621, 0.1272, -0.0039);
  cone6.rotation.set(deg(1.5887), deg(11.1348), deg(-11.9651));
  cone6.scale.set(1, 1, 0.45);
  tuft1.add(cone6);
  const cone7 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2642, 3), grassMat);
  cone7.position.set(-0.0168, 0.1121, 0.0599);
  cone7.rotation.set(deg(14.543), deg(20.4617), deg(4.7895));
  cone7.scale.set(1, 1, 0.45);
  tuft1.add(cone7);
  const cone8 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2776, 3), grassLightMat);
  cone8.position.set(-0.0622, 0.1188, 0.0025);
  cone8.rotation.set(deg(-10.2058), deg(32.4381), deg(19.731));
  cone8.scale.set(1, 1, 0.45);
  tuft1.add(cone8);
  const cone9 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2817, 3), grassDarkMat);
  cone9.position.set(0.0225, 0.1209, -0.058);
  cone9.rotation.set(deg(-12.4737), deg(10.3569), deg(-5.2197));
  cone9.scale.set(1, 1, 0.45);
  tuft1.add(cone9);
  const tuft2 = new THREE.Group();
  tuft2.name = 'tuft2';
  tuft2.position.set(-0.6252, 1.5092, 0.5015);
  dressing.add(tuft2);
  const cone11 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2423, 3), grassDarkMat);
  cone11.position.set(0.0618, 0.1011, -0.0068);
  cone11.rotation.set(deg(2.353), deg(12.3675), deg(-20.9773));
  cone11.scale.set(1, 1, 0.45);
  tuft2.add(cone11);
  const cone12 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2816, 3), grassMat);
  cone12.position.set(-0.0319, 0.1208, 0.0534);
  cone12.rotation.set(deg(17.5024), deg(4.8767), deg(10.7155));
  cone12.scale.set(1, 1, 0.45);
  tuft2.add(cone12);
  const cone13 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.3215, 3), grassLightMat);
  cone13.position.set(-0.0378, 0.1407, -0.0494);
  cone13.rotation.set(deg(-174.0467), deg(62.3921), deg(159.4077));
  cone13.scale.set(1, 1, 0.45);
  tuft2.add(cone13);
  const tuft3 = new THREE.Group();
  tuft3.name = 'tuft3';
  tuft3.position.set(-0.0065, 1.5397, -0.9354);
  dressing.add(tuft3);
  const cone15 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.247, 3), grassDarkMat);
  cone15.position.set(0.0612, 0.1035, -0.0114);
  cone15.rotation.set(deg(157.1232), deg(59.4813), deg(-156.3594));
  cone15.scale.set(1, 1, 0.45);
  tuft3.add(cone15);
  const cone16 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.3437, 3), grassMat);
  cone16.position.set(-0.0422, 0.1518, 0.0457);
  cone16.rotation.set(deg(-144.1052), deg(63.925), deg(154.0345));
  cone16.scale.set(1, 1, 0.45);
  tuft3.add(cone16);
  const cone17 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.3281, 3), grassLightMat);
  cone17.position.set(-0.0303, 0.1441, -0.0543);
  cone17.rotation.set(deg(-173.0964), deg(67.9314), deg(154.0671));
  cone17.scale.set(1, 1, 0.45);
  tuft3.add(cone17);
  const flower4 = new THREE.Group();
  flower4.name = 'flower4';
  flower4.position.set(0.811, 1.2064, 0.8745);
  dressing.add(flower4);
  const cylinder19 = new THREE.Mesh(cylinderGeo, grassDarkMat);
  cylinder19.position.set(0, 0.0856, 0);
  flower4.add(cylinder19);
  const dodecahedron20 = new THREE.Mesh(dodecahedronGeo, petalBlueMat);
  dodecahedron20.position.set(0, 0.2012, 0);
  dodecahedron20.scale.set(1, 0.6, 1);
  flower4.add(dodecahedron20);
  const cone21 = new THREE.Mesh(coneGeo, grassDarkMat);
  cone21.position.set(0.0169, 0.0296, 0);
  cone21.rotation.set(0, deg(122.6426), deg(-40));
  cone21.scale.set(1, 1, 0.4);
  flower4.add(cone21);
  const tuft5 = new THREE.Group();
  tuft5.name = 'tuft5';
  tuft5.position.set(-1.4964, 0.808, 0.0906);
  dressing.add(tuft5);
  const cone23 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.3189, 3), grassDarkMat);
  cone23.position.set(0.06, 0.1395, -0.0163);
  cone23.rotation.set(deg(23.5823), deg(53.5592), deg(-34.7649));
  cone23.scale.set(1, 1, 0.45);
  tuft5.add(cone23);
  const cone24 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2552, 3), grassMat);
  cone24.position.set(-0.0123, 0.1076, 0.061);
  cone24.rotation.set(deg(18.2013), deg(14.4551), deg(3.923));
  cone24.scale.set(1, 1, 0.45);
  tuft5.add(cone24);
  const cone25 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2677, 3), grassLightMat);
  cone25.position.set(-0.059, 0.1138, -0.0198);
  cone25.rotation.set(deg(-20.6286), deg(40.4996), deg(22.2075));
  cone25.scale.set(1, 1, 0.45);
  tuft5.add(cone25);
  const cone26 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.3143, 3), grassDarkMat);
  cone26.position.set(-0.0158, 0.1372, -0.0602);
  cone26.rotation.set(deg(-174.2442), deg(78.2899), deg(153.2604));
  cone26.scale.set(1, 1, 0.45);
  tuft5.add(cone26);
  const tuft6 = new THREE.Group();
  tuft6.name = 'tuft6';
  tuft6.position.set(1.2717, 0.8772, -0.8907);
  dressing.add(tuft6);
  const cone28 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2999, 3), grassDarkMat);
  cone28.position.set(0.06, 0.13, -0.0164);
  cone28.rotation.set(deg(13.1808), deg(45.904), deg(-24.1273));
  cone28.scale.set(1, 1, 0.45);
  tuft6.add(cone28);
  const cone29 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.3501, 3), grassMat);
  cone29.position.set(-0.0389, 0.155, 0.0486);
  cone29.rotation.set(deg(-139.856), deg(62.1964), deg(152.8815));
  cone29.scale.set(1, 1, 0.45);
  tuft6.add(cone29);
  const cone30 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2918, 3), grassLightMat);
  cone30.position.set(-0.0081, 0.1259, -0.0617);
  cone30.rotation.set(deg(-26.9797), deg(78.6867), deg(10.8422));
  cone30.scale.set(1, 1, 0.45);
  tuft6.add(cone30);
  const tuft7 = new THREE.Group();
  tuft7.name = 'tuft7';
  tuft7.position.set(-0.5133, 1.0798, 1.4459);
  dressing.add(tuft7);
  const cone32 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2828, 3), grassDarkMat);
  cone32.position.set(0.061, 0.1214, 0.0121);
  cone32.rotation.set(deg(17.4346), deg(48.0361), deg(-19.5777));
  cone32.scale.set(1, 1, 0.45);
  tuft7.add(cone32);
  const cone33 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2659, 3), grassMat);
  cone33.position.set(-0.02, 0.113, 0.0589);
  cone33.rotation.set(deg(16.7145), deg(30.5895), deg(8.017));
  cone33.scale.set(1, 1, 0.45);
  tuft7.add(cone33);
  const cone34 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.3016, 3), grassLightMat);
  cone34.position.set(-0.0591, 0.1308, 0.0194);
  cone34.rotation.set(deg(-95.487), deg(73.3761), deg(100.5457));
  cone34.scale.set(1, 1, 0.45);
  tuft7.add(cone34);
  const cone35 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2893, 3), grassDarkMat);
  cone35.position.set(0.0168, 0.1247, -0.0599);
  cone35.rotation.set(deg(-13.7255), deg(43.6867), deg(-7.066));
  cone35.scale.set(1, 1, 0.45);
  tuft7.add(cone35);
  const flower8 = new THREE.Group();
  flower8.name = 'flower8';
  flower8.position.set(-1.1403, 0.7735, -1.3096);
  dressing.add(flower8);
  const cylinder37 = new THREE.Mesh(cylinderGeo, grassDarkMat);
  cylinder37.position.set(0, 0.0856, 0);
  flower8.add(cylinder37);
  const dodecahedron38 = new THREE.Mesh(dodecahedronGeo, petalMat);
  dodecahedron38.position.set(0, 0.2012, 0);
  dodecahedron38.scale.set(1, 0.6, 1);
  flower8.add(dodecahedron38);
  const cone39 = new THREE.Mesh(coneGeo, grassDarkMat);
  cone39.position.set(0.0169, 0.0296, 0);
  cone39.rotation.set(0, deg(238.7538), deg(-40));
  cone39.scale.set(1, 1, 0.4);
  flower8.add(cone39);
  const tuft9 = new THREE.Group();
  tuft9.name = 'tuft9';
  tuft9.position.set(1.9049, 0.4961, 0.6603);
  dressing.add(tuft9);
  const cone41 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2432, 3), grassDarkMat);
  cone41.position.set(0.0613, 0.1016, -0.0108);
  cone41.rotation.set(deg(139.2174), deg(64.6924), deg(-139.3171));
  cone41.scale.set(1, 1, 0.45);
  tuft9.add(cone41);
  const cone42 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.3456, 3), grassMat);
  cone42.position.set(-0.0076, 0.1528, 0.0617);
  cone42.rotation.set(deg(12.1417), deg(35.7519), deg(2.0084));
  cone42.scale.set(1, 1, 0.45);
  tuft9.add(cone42);
  const cone43 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2852, 3), grassLightMat);
  cone43.position.set(-0.0599, 0.1226, 0.0168);
  cone43.rotation.set(deg(-132.2155), deg(73.9152), deg(134.3254));
  cone43.scale.set(1, 1, 0.45);
  tuft9.add(cone43);
  const cone44 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2547, 3), grassDarkMat);
  cone44.position.set(-0.0018, 0.1074, -0.0622);
  cone44.rotation.set(deg(-170.0229), deg(89.0312), deg(156.3655));
  cone44.scale.set(1, 1, 0.45);
  tuft9.add(cone44);
  const tuft10 = new THREE.Group();
  tuft10.name = 'tuft10';
  tuft10.position.set(-1.7511, 0.3784, 1.086);
  dressing.add(tuft10);
  const cone46 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.3388, 3), grassDarkMat);
  cone46.position.set(0.0555, 0.1494, 0.0281);
  cone46.rotation.set(deg(8.8138), deg(1.1926), deg(-16.2381));
  cone46.scale.set(1, 1, 0.45);
  tuft10.add(cone46);
  const cone47 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.3345, 3), grassMat);
  cone47.position.set(-0.0285, 0.1472, 0.0553);
  cone47.rotation.set(deg(11.9676), deg(1.8131), deg(6.2051));
  cone47.scale.set(1, 1, 0.45);
  tuft10.add(cone47);
  const cone48 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.3253, 3), grassLightMat);
  cone48.position.set(-0.0616, 0.1426, 0.0086);
  cone48.rotation.set(deg(-82.7502), deg(75.5375), deg(84.9613));
  cone48.scale.set(1, 1, 0.45);
  tuft10.add(cone48);
  const cone49 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.284, 3), grassDarkMat);
  cone49.position.set(-0.0237, 0.122, -0.0575);
  cone49.rotation.set(deg(-23.9666), deg(72.3857), deg(14.2003));
  cone49.scale.set(1, 1, 0.45);
  tuft10.add(cone49);
  const tuft11 = new THREE.Group();
  tuft11.name = 'tuft11';
  tuft11.position.set(0.8196, 0.6473, -1.7902);
  dressing.add(tuft11);
  const cone51 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2598, 3), grassDarkMat);
  cone51.position.set(0.0591, 0.1099, 0.0193);
  cone51.rotation.set(deg(80.3364), deg(69.7829), deg(-74.6527));
  cone51.scale.set(1, 1, 0.45);
  tuft11.add(cone51);
  const cone52 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.326, 3), grassMat);
  cone52.position.set(0.0037, 0.143, 0.0621);
  cone52.rotation.set(deg(16.0906), deg(2.8814), deg(-0.9512));
  cone52.scale.set(1, 1, 0.45);
  tuft11.add(cone52);
  const cone53 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.244, 3), grassLightMat);
  cone53.position.set(-0.0606, 0.102, -0.014);
  cone53.rotation.set(deg(-141.966), deg(74.6174), deg(138.5629));
  cone53.scale.set(1, 1, 0.45);
  tuft11.add(cone53);
  const cone54 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.3364, 3), grassDarkMat);
  cone54.position.set(0.0119, 0.1482, -0.0611);
  cone54.rotation.set(deg(-9.2186), deg(46.8251), deg(-3.2677));
  cone54.scale.set(1, 1, 0.45);
  tuft11.add(cone54);
  const flower12 = new THREE.Group();
  flower12.name = 'flower12';
  flower12.position.set(0.9295, 0.5226, 1.8494);
  dressing.add(flower12);
  const cylinder56 = new THREE.Mesh(cylinderGeo, grassDarkMat);
  cylinder56.position.set(0, 0.0856, 0);
  flower12.add(cylinder56);
  const dodecahedron57 = new THREE.Mesh(dodecahedronGeo, petalBlueMat);
  dodecahedron57.position.set(0, 0.2012, 0);
  dodecahedron57.scale.set(1, 0.6, 1);
  flower12.add(dodecahedron57);
  const cone58 = new THREE.Mesh(coneGeo, grassDarkMat);
  cone58.position.set(0.0169, 0.0296, 0);
  cone58.rotation.set(0, deg(30.0281), deg(-40));
  cone58.scale.set(1, 1, 0.4);
  flower12.add(cone58);
  const tuft13 = new THREE.Group();
  tuft13.name = 'tuft13';
  tuft13.position.set(-2.049, 0.0927, -1.1988);
  dressing.add(tuft13);
  const cone60 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.3532, 3), grassDarkMat);
  cone60.position.set(0.0601, 0.1566, 0.0161);
  cone60.rotation.set(deg(146.4695), deg(69.352), deg(-141.1442));
  cone60.scale.set(1, 1, 0.45);
  tuft13.add(cone60);
  const cone61 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.2447, 3), grassMat);
  cone61.position.set(0.0291, 0.1023, 0.055);
  cone61.rotation.set(deg(124.0359), deg(82.3858), deg(-110.1582));
  cone61.scale.set(1, 1, 0.45);
  tuft13.add(cone61);
  const cone62 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.3596, 3), grassLightMat);
  cone62.position.set(-0.0616, 0.1598, -0.0087);
  cone62.rotation.set(deg(-15.57), deg(39.2519), deg(20.4655));
  cone62.scale.set(1, 1, 0.45);
  tuft13.add(cone62);
  const cone63 = new THREE.Mesh(new THREE.ConeGeometry(0.0691, 0.3653, 3), grassDarkMat);
  cone63.position.set(-0.0142, 0.1626, -0.0606);
  cone63.rotation.set(deg(-29.4695), deg(63.6155), deg(10.4257));
  cone63.scale.set(1, 1, 0.45);
  tuft13.add(cone63);
  const rock1 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.2157, 0), 0.0388, 381), rockMat);
  rock1.name = 'rock1';
  rock1.position.set(1.5083, 0.7935, -0.8617);
  rock1.rotation.set(deg(-7.1934), deg(12.1483), deg(-4.429));
  rock1.scale.set(1.0407, 0.6209, 1);
  dressing.add(rock1);
  const rock2 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.2855, 0), 0.0514, 376), rockDarkMat);
  rock2.name = 'rock2';
  rock2.position.set(0.4331, 1.4334, 1.0493);
  rock2.rotation.set(deg(-5.7611), deg(286.7857), deg(-2.4723));
  rock2.scale.set(1.0804, 0.5755, 1);
  dressing.add(rock2);
  const rock3 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.2467, 0), 0.0444, 382), rockMat);
  rock3.name = 'rock3';
  rock3.position.set(0.9087, 1.0423, 1.2752);
  rock3.rotation.set(deg(5.4397), deg(74.5639), deg(4.4835));
  rock3.scale.set(1.1813, 0.5928, 1);
  dressing.add(rock3);
  const footStone1 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.14, 0), 0.0252, 145), rockMat);
  footStone1.name = 'footStone1';
  footStone1.position.set(-2.614, 0.0743, -1.3306);
  footStone1.rotation.set(deg(-6.4402), deg(345.3177), deg(-2.8507));
  footStone1.scale.set(1.2113, 0.5484, 1);
  dressing.add(footStone1);
  const footStone2 = new THREE.Mesh(jitter(new THREE.DodecahedronGeometry(0.14, 0), 0.0252, 467), rockMat);
  footStone2.name = 'footStone2';
  footStone2.position.set(2.4746, 0.0758, -1.5057);
  footStone2.rotation.set(deg(-3.4121), deg(261.4087), deg(4.0205));
  footStone2.scale.set(1.1825, 0.507, 1);
  dressing.add(footStone2);

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

export default createHill;

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