1460 三角面8.00 × 2.46 × 8.00 m
在代码中使用
在编辑器中改编roundabout.js · 475 行
自包含的 ES 模块,仅依赖 three。调用工厂函数,然后把返回的 group 添加到场景中。
/**
* Roundabout — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 1,460 · Size (W × H × D): 8.00 × 2.46 × 8.00 m
*
* Usage:
* import { createRoundabout } from './roundabout.js';
*
* const model = createRoundabout();
* 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);
}
// 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 createRoundabout() {
const root = new THREE.Group();
root.name = 'Roundabout';
// Materials
const asphaltMat = new THREE.MeshStandardMaterial({ name: 'asphalt', color: 0x41454b, roughness: 0.95, flatShading: true });
const whiteMat = new THREE.MeshStandardMaterial({ name: 'white', color: 0xecebe4, roughness: 0.7, flatShading: true });
const curbMat = new THREE.MeshStandardMaterial({ name: 'curb', color: 0xb4b2ab, roughness: 0.9, flatShading: true });
const paverMat = new THREE.MeshStandardMaterial({ name: 'paver', color: 0x92918b, roughness: 0.95, flatShading: true });
const grassMat = new THREE.MeshStandardMaterial({ name: 'grass', color: 0x6f9a45, roughness: 0.95, flatShading: true });
const leafMat = new THREE.MeshStandardMaterial({ name: 'leaf', color: 0x4f7f36, roughness: 0.9, flatShading: true });
const trunkMat = new THREE.MeshStandardMaterial({ name: 'trunk', color: 0x7a5636, roughness: 0.9, flatShading: true });
// Shared geometries
const extrudeGeo = extrude([[1.35, 4], [1.35, 3.3731], [1.3943, 3.1105], [1.5224, 2.877], [1.72, 2.6984], [2.2627, 2.2627], [2.6984, 1.72], [2.877, 1.5224], [3.1105, 1.3943], [3.3731, 1.35], [4, 1.35], [4, 1.49], [3.3731, 1.49], [3.1564, 1.5266], [2.9638, 1.6322], [2.8165, 1.7953], [2.3617, 2.3617], [1.7953, 2.8165], [1.6322, 2.9638], [1.5266, 3.1564], [1.49, 3.3731], [1.49, 4]], 0.165);
const extrudeGeo2 = extrude([[1.496, 3.994], [1.496, 3.3791], [1.994, 3.3791], [1.994, 3.994]], 0.15);
const extrudeGeo3 = extrude([[1.496, 3.3671], [1.5329, 3.1565], [1.6357, 2.9691], [1.7934, 2.8248], [2.0612, 3.2448], [2.0264, 3.2779], [2.0033, 3.32], [1.9941, 3.3671]], 0.15);
const extrudeGeo4 = extrude([[1.8035, 2.8183], [2.3617, 2.3702], [2.7139, 2.7224], [2.0712, 3.2383]], 0.15);
const extrudeGeo5 = extrude([[2.3702, 2.3617], [2.8183, 1.8035], [3.2383, 2.0712], [2.7224, 2.7139]], 0.15);
const extrudeGeo6 = extrude([[2.8248, 1.7934], [2.9691, 1.6357], [3.1565, 1.5329], [3.3671, 1.496], [3.3671, 1.9941], [3.32, 2.0033], [3.2779, 2.0264], [3.2448, 2.0612]], 0.15);
const extrudeGeo7 = extrude([[3.3791, 1.496], [3.994, 1.496], [3.994, 1.994], [3.3791, 1.994]], 0.15);
const extrudeGeo8 = extrude([[2, 4], [2, 3.3731], [2.0083, 3.3238], [2.0323, 3.28], [2.0694, 3.2466], [2.7224, 2.7224], [3.2466, 2.0694], [3.28, 2.0323], [3.3238, 2.0083], [3.3731, 2], [4, 2], [4, 4]], 0.16);
const planeGeo = new THREE.PlaneGeometry(0.1, 0.6269);
const latheGeo = lathe([[1.27, 0], [1.17, 0]], 3, -2.5741, 1.0033);
const latheGeo2 = lathe([[2.83, 0], [2.73, 0]], 2, 0.5675, 0.4359);
const latheGeo3 = lathe([[1.27, 0], [1.17, 0]], 3, -Math.PI, 1.0033);
const extrudeGeo9 = extrude([[0, 3.75], [-0.135, 3.5575], [-0.3, 3.3375], [-0.3, 3.1859], [0, 3.2], [0.3, 3.1859], [0.3, 3.3375], [0.135, 3.5575]], 0.12);
const planeGeo2 = new THREE.PlaneGeometry(0.11, 0.15);
// Parts
const asphalt = new THREE.Mesh(new THREE.BoxGeometry(7.998, 0.02, 7.998), asphaltMat);
asphalt.name = 'asphalt';
asphalt.position.set(0, 0.01, 0);
root.add(asphalt);
const quadrant1 = new THREE.Group();
quadrant1.name = 'quadrant1';
root.add(quadrant1);
const curb = new THREE.Mesh(extrudeGeo, curbMat);
curb.name = 'curb';
curb.position.set(0, 0.0825, 0);
curb.rotation.set(deg(90), 0, 0);
quadrant1.add(curb);
const paver = new THREE.Mesh(extrudeGeo2, paverMat);
paver.name = 'paver';
paver.position.set(0, 0.075, 0);
paver.rotation.set(deg(90), 0, 0);
quadrant1.add(paver);
const paver2 = new THREE.Mesh(extrudeGeo3, paverMat);
paver2.name = 'paver';
paver2.position.set(0, 0.075, 0);
paver2.rotation.set(deg(90), 0, 0);
quadrant1.add(paver2);
const paver3 = new THREE.Mesh(extrudeGeo4, paverMat);
paver3.name = 'paver';
paver3.position.set(0, 0.075, 0);
paver3.rotation.set(deg(90), 0, 0);
quadrant1.add(paver3);
const paver4 = new THREE.Mesh(extrudeGeo5, paverMat);
paver4.name = 'paver';
paver4.position.set(0, 0.075, 0);
paver4.rotation.set(deg(90), 0, 0);
quadrant1.add(paver4);
const paver5 = new THREE.Mesh(extrudeGeo6, paverMat);
paver5.name = 'paver';
paver5.position.set(0, 0.075, 0);
paver5.rotation.set(deg(90), 0, 0);
quadrant1.add(paver5);
const paver6 = new THREE.Mesh(extrudeGeo7, paverMat);
paver6.name = 'paver';
paver6.position.set(0, 0.075, 0);
paver6.rotation.set(deg(90), 0, 0);
quadrant1.add(paver6);
const verge = new THREE.Mesh(extrudeGeo8, grassMat);
verge.name = 'verge';
verge.position.set(0, 0.08, 0);
verge.rotation.set(deg(90), 0, 0);
quadrant1.add(verge);
const edgeLine = new THREE.Mesh(planeGeo, whiteMat);
edgeLine.name = 'edgeLine';
edgeLine.position.set(0.93, 0.025, 3.6865);
edgeLine.rotation.set(deg(-90), 0, deg(180));
quadrant1.add(edgeLine);
const edgeLine2 = new THREE.Mesh(latheGeo, whiteMat);
edgeLine2.name = 'edgeLine';
edgeLine2.position.set(2.15, 0.025, 3.3731);
quadrant1.add(edgeLine2);
const edgeLine3 = new THREE.Mesh(latheGeo2, whiteMat);
edgeLine3.name = 'edgeLine';
edgeLine3.position.set(0, 0.025, 0);
quadrant1.add(edgeLine3);
const edgeLine4 = new THREE.Mesh(latheGeo3, whiteMat);
edgeLine4.name = 'edgeLine';
edgeLine4.position.set(3.3731, 0.025, 2.15);
quadrant1.add(edgeLine4);
const edgeLine5 = new THREE.Mesh(planeGeo, whiteMat);
edgeLine5.name = 'edgeLine';
edgeLine5.position.set(3.6865, 0.025, 0.93);
edgeLine5.rotation.set(deg(-90), 0, deg(90));
quadrant1.add(edgeLine5);
const entry1 = new THREE.Group();
entry1.name = 'entry1';
root.add(entry1);
const splitterIsland = new THREE.Mesh(extrudeGeo9, curbMat);
splitterIsland.name = 'splitterIsland';
splitterIsland.position.set(0, 0.06, 0);
splitterIsland.rotation.set(deg(90), 0, 0);
entry1.add(splitterIsland);
const giveWay = new THREE.Mesh(planeGeo2, whiteMat);
giveWay.name = 'giveWay';
giveWay.position.set(0.7413, 0.025, 3.1746);
giveWay.rotation.set(deg(-90), 0, deg(13.1429));
entry1.add(giveWay);
const giveWay2 = new THREE.Mesh(planeGeo2, whiteMat);
giveWay2.name = 'giveWay';
giveWay2.position.set(0.5254, 0.025, 3.2174);
giveWay2.rotation.set(deg(-90), 0, deg(9.2744));
entry1.add(giveWay2);
const quadrant2 = new THREE.Group();
quadrant2.name = 'quadrant2';
quadrant2.rotation.set(0, deg(90), 0);
root.add(quadrant2);
const curb2 = new THREE.Mesh(extrudeGeo, curbMat);
curb2.name = 'curb';
curb2.position.set(0, 0.0825, 0);
curb2.rotation.set(deg(90), 0, 0);
quadrant2.add(curb2);
const paver7 = new THREE.Mesh(extrudeGeo2, paverMat);
paver7.name = 'paver';
paver7.position.set(0, 0.075, 0);
paver7.rotation.set(deg(90), 0, 0);
quadrant2.add(paver7);
const paver8 = new THREE.Mesh(extrudeGeo3, paverMat);
paver8.name = 'paver';
paver8.position.set(0, 0.075, 0);
paver8.rotation.set(deg(90), 0, 0);
quadrant2.add(paver8);
const paver9 = new THREE.Mesh(extrudeGeo4, paverMat);
paver9.name = 'paver';
paver9.position.set(0, 0.075, 0);
paver9.rotation.set(deg(90), 0, 0);
quadrant2.add(paver9);
const paver10 = new THREE.Mesh(extrudeGeo5, paverMat);
paver10.name = 'paver';
paver10.position.set(0, 0.075, 0);
paver10.rotation.set(deg(90), 0, 0);
quadrant2.add(paver10);
const paver11 = new THREE.Mesh(extrudeGeo6, paverMat);
paver11.name = 'paver';
paver11.position.set(0, 0.075, 0);
paver11.rotation.set(deg(90), 0, 0);
quadrant2.add(paver11);
const paver12 = new THREE.Mesh(extrudeGeo7, paverMat);
paver12.name = 'paver';
paver12.position.set(0, 0.075, 0);
paver12.rotation.set(deg(90), 0, 0);
quadrant2.add(paver12);
const verge2 = new THREE.Mesh(extrudeGeo8, grassMat);
verge2.name = 'verge';
verge2.position.set(0, 0.08, 0);
verge2.rotation.set(deg(90), 0, 0);
quadrant2.add(verge2);
const edgeLine6 = new THREE.Mesh(planeGeo, whiteMat);
edgeLine6.name = 'edgeLine';
edgeLine6.position.set(0.93, 0.025, 3.6865);
edgeLine6.rotation.set(deg(-90), 0, deg(180));
quadrant2.add(edgeLine6);
const edgeLine7 = new THREE.Mesh(latheGeo, whiteMat);
edgeLine7.name = 'edgeLine';
edgeLine7.position.set(2.15, 0.025, 3.3731);
quadrant2.add(edgeLine7);
const edgeLine8 = new THREE.Mesh(latheGeo2, whiteMat);
edgeLine8.name = 'edgeLine';
edgeLine8.position.set(0, 0.025, 0);
quadrant2.add(edgeLine8);
const edgeLine9 = new THREE.Mesh(latheGeo3, whiteMat);
edgeLine9.name = 'edgeLine';
edgeLine9.position.set(3.3731, 0.025, 2.15);
quadrant2.add(edgeLine9);
const edgeLine10 = new THREE.Mesh(planeGeo, whiteMat);
edgeLine10.name = 'edgeLine';
edgeLine10.position.set(3.6865, 0.025, 0.93);
edgeLine10.rotation.set(deg(-90), 0, deg(90));
quadrant2.add(edgeLine10);
const entry2 = new THREE.Group();
entry2.name = 'entry2';
entry2.rotation.set(0, deg(90), 0);
root.add(entry2);
const splitterIsland2 = new THREE.Mesh(extrudeGeo9, curbMat);
splitterIsland2.name = 'splitterIsland';
splitterIsland2.position.set(0, 0.06, 0);
splitterIsland2.rotation.set(deg(90), 0, 0);
entry2.add(splitterIsland2);
const giveWay3 = new THREE.Mesh(planeGeo2, whiteMat);
giveWay3.name = 'giveWay';
giveWay3.position.set(0.7413, 0.025, 3.1746);
giveWay3.rotation.set(deg(-90), 0, deg(13.1429));
entry2.add(giveWay3);
const giveWay4 = new THREE.Mesh(planeGeo2, whiteMat);
giveWay4.name = 'giveWay';
giveWay4.position.set(0.5254, 0.025, 3.2174);
giveWay4.rotation.set(deg(-90), 0, deg(9.2744));
entry2.add(giveWay4);
const quadrant3 = new THREE.Group();
quadrant3.name = 'quadrant3';
quadrant3.rotation.set(0, deg(180), 0);
root.add(quadrant3);
const curb3 = new THREE.Mesh(extrudeGeo, curbMat);
curb3.name = 'curb';
curb3.position.set(0, 0.0825, 0);
curb3.rotation.set(deg(90), 0, 0);
quadrant3.add(curb3);
const paver13 = new THREE.Mesh(extrudeGeo2, paverMat);
paver13.name = 'paver';
paver13.position.set(0, 0.075, 0);
paver13.rotation.set(deg(90), 0, 0);
quadrant3.add(paver13);
const paver14 = new THREE.Mesh(extrudeGeo3, paverMat);
paver14.name = 'paver';
paver14.position.set(0, 0.075, 0);
paver14.rotation.set(deg(90), 0, 0);
quadrant3.add(paver14);
const paver15 = new THREE.Mesh(extrudeGeo4, paverMat);
paver15.name = 'paver';
paver15.position.set(0, 0.075, 0);
paver15.rotation.set(deg(90), 0, 0);
quadrant3.add(paver15);
const paver16 = new THREE.Mesh(extrudeGeo5, paverMat);
paver16.name = 'paver';
paver16.position.set(0, 0.075, 0);
paver16.rotation.set(deg(90), 0, 0);
quadrant3.add(paver16);
const paver17 = new THREE.Mesh(extrudeGeo6, paverMat);
paver17.name = 'paver';
paver17.position.set(0, 0.075, 0);
paver17.rotation.set(deg(90), 0, 0);
quadrant3.add(paver17);
const paver18 = new THREE.Mesh(extrudeGeo7, paverMat);
paver18.name = 'paver';
paver18.position.set(0, 0.075, 0);
paver18.rotation.set(deg(90), 0, 0);
quadrant3.add(paver18);
const verge3 = new THREE.Mesh(extrudeGeo8, grassMat);
verge3.name = 'verge';
verge3.position.set(0, 0.08, 0);
verge3.rotation.set(deg(90), 0, 0);
quadrant3.add(verge3);
const edgeLine11 = new THREE.Mesh(planeGeo, whiteMat);
edgeLine11.name = 'edgeLine';
edgeLine11.position.set(0.93, 0.025, 3.6865);
edgeLine11.rotation.set(deg(-90), 0, deg(180));
quadrant3.add(edgeLine11);
const edgeLine12 = new THREE.Mesh(latheGeo, whiteMat);
edgeLine12.name = 'edgeLine';
edgeLine12.position.set(2.15, 0.025, 3.3731);
quadrant3.add(edgeLine12);
const edgeLine13 = new THREE.Mesh(latheGeo2, whiteMat);
edgeLine13.name = 'edgeLine';
edgeLine13.position.set(0, 0.025, 0);
quadrant3.add(edgeLine13);
const edgeLine14 = new THREE.Mesh(latheGeo3, whiteMat);
edgeLine14.name = 'edgeLine';
edgeLine14.position.set(3.3731, 0.025, 2.15);
quadrant3.add(edgeLine14);
const edgeLine15 = new THREE.Mesh(planeGeo, whiteMat);
edgeLine15.name = 'edgeLine';
edgeLine15.position.set(3.6865, 0.025, 0.93);
edgeLine15.rotation.set(deg(-90), 0, deg(90));
quadrant3.add(edgeLine15);
const entry3 = new THREE.Group();
entry3.name = 'entry3';
entry3.rotation.set(0, deg(180), 0);
root.add(entry3);
const splitterIsland3 = new THREE.Mesh(extrudeGeo9, curbMat);
splitterIsland3.name = 'splitterIsland';
splitterIsland3.position.set(0, 0.06, 0);
splitterIsland3.rotation.set(deg(90), 0, 0);
entry3.add(splitterIsland3);
const giveWay5 = new THREE.Mesh(planeGeo2, whiteMat);
giveWay5.name = 'giveWay';
giveWay5.position.set(0.7413, 0.025, 3.1746);
giveWay5.rotation.set(deg(-90), 0, deg(13.1429));
entry3.add(giveWay5);
const giveWay6 = new THREE.Mesh(planeGeo2, whiteMat);
giveWay6.name = 'giveWay';
giveWay6.position.set(0.5254, 0.025, 3.2174);
giveWay6.rotation.set(deg(-90), 0, deg(9.2744));
entry3.add(giveWay6);
const quadrant4 = new THREE.Group();
quadrant4.name = 'quadrant4';
quadrant4.rotation.set(0, deg(270), 0);
root.add(quadrant4);
const curb4 = new THREE.Mesh(extrudeGeo, curbMat);
curb4.name = 'curb';
curb4.position.set(0, 0.0825, 0);
curb4.rotation.set(deg(90), 0, 0);
quadrant4.add(curb4);
const paver19 = new THREE.Mesh(extrudeGeo2, paverMat);
paver19.name = 'paver';
paver19.position.set(0, 0.075, 0);
paver19.rotation.set(deg(90), 0, 0);
quadrant4.add(paver19);
const paver20 = new THREE.Mesh(extrudeGeo3, paverMat);
paver20.name = 'paver';
paver20.position.set(0, 0.075, 0);
paver20.rotation.set(deg(90), 0, 0);
quadrant4.add(paver20);
const paver21 = new THREE.Mesh(extrudeGeo4, paverMat);
paver21.name = 'paver';
paver21.position.set(0, 0.075, 0);
paver21.rotation.set(deg(90), 0, 0);
quadrant4.add(paver21);
const paver22 = new THREE.Mesh(extrudeGeo5, paverMat);
paver22.name = 'paver';
paver22.position.set(0, 0.075, 0);
paver22.rotation.set(deg(90), 0, 0);
quadrant4.add(paver22);
const paver23 = new THREE.Mesh(extrudeGeo6, paverMat);
paver23.name = 'paver';
paver23.position.set(0, 0.075, 0);
paver23.rotation.set(deg(90), 0, 0);
quadrant4.add(paver23);
const paver24 = new THREE.Mesh(extrudeGeo7, paverMat);
paver24.name = 'paver';
paver24.position.set(0, 0.075, 0);
paver24.rotation.set(deg(90), 0, 0);
quadrant4.add(paver24);
const verge4 = new THREE.Mesh(extrudeGeo8, grassMat);
verge4.name = 'verge';
verge4.position.set(0, 0.08, 0);
verge4.rotation.set(deg(90), 0, 0);
quadrant4.add(verge4);
const edgeLine16 = new THREE.Mesh(planeGeo, whiteMat);
edgeLine16.name = 'edgeLine';
edgeLine16.position.set(0.93, 0.025, 3.6865);
edgeLine16.rotation.set(deg(-90), 0, deg(180));
quadrant4.add(edgeLine16);
const edgeLine17 = new THREE.Mesh(latheGeo, whiteMat);
edgeLine17.name = 'edgeLine';
edgeLine17.position.set(2.15, 0.025, 3.3731);
quadrant4.add(edgeLine17);
const edgeLine18 = new THREE.Mesh(latheGeo2, whiteMat);
edgeLine18.name = 'edgeLine';
edgeLine18.position.set(0, 0.025, 0);
quadrant4.add(edgeLine18);
const edgeLine19 = new THREE.Mesh(latheGeo3, whiteMat);
edgeLine19.name = 'edgeLine';
edgeLine19.position.set(3.3731, 0.025, 2.15);
quadrant4.add(edgeLine19);
const edgeLine20 = new THREE.Mesh(planeGeo, whiteMat);
edgeLine20.name = 'edgeLine';
edgeLine20.position.set(3.6865, 0.025, 0.93);
edgeLine20.rotation.set(deg(-90), 0, deg(90));
quadrant4.add(edgeLine20);
const entry4 = new THREE.Group();
entry4.name = 'entry4';
entry4.rotation.set(0, deg(270), 0);
root.add(entry4);
const splitterIsland4 = new THREE.Mesh(extrudeGeo9, curbMat);
splitterIsland4.name = 'splitterIsland';
splitterIsland4.position.set(0, 0.06, 0);
splitterIsland4.rotation.set(deg(90), 0, 0);
entry4.add(splitterIsland4);
const giveWay7 = new THREE.Mesh(planeGeo2, whiteMat);
giveWay7.name = 'giveWay';
giveWay7.position.set(0.7413, 0.025, 3.1746);
giveWay7.rotation.set(deg(-90), 0, deg(13.1429));
entry4.add(giveWay7);
const giveWay8 = new THREE.Mesh(planeGeo2, whiteMat);
giveWay8.name = 'giveWay';
giveWay8.position.set(0.5254, 0.025, 3.2174);
giveWay8.rotation.set(deg(-90), 0, deg(9.2744));
entry4.add(giveWay8);
const islandCurb = new THREE.Mesh(new THREE.CylinderGeometry(1.35, 1.35, 0.15, 20), curbMat);
islandCurb.name = 'islandCurb';
islandCurb.position.set(0, 0.075, 0);
root.add(islandCurb);
const ringLine = new THREE.Mesh(new THREE.RingGeometry(1.55, 1.65, 24), whiteMat);
ringLine.name = 'ringLine';
ringLine.position.set(0, 0.025, 0);
ringLine.rotation.set(deg(-90), 0, 0);
root.add(ringLine);
const islandGrass = new THREE.Mesh(new THREE.SphereGeometry(1.25, 12, 3, 0, Math.PI * 2, 0, Math.PI / 2), grassMat);
islandGrass.name = 'islandGrass';
islandGrass.position.set(0, 0.1, 0);
islandGrass.scale.set(1, 0.22, 1);
root.add(islandGrass);
const trunk = new THREE.Mesh(new THREE.CylinderGeometry(0.06, 0.1, 1.1, 6), trunkMat);
trunk.name = 'trunk';
trunk.position.set(0, 0.875, 0);
root.add(trunk);
const crown = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.55, 0), 0.06, 3), leafMat);
crown.name = 'crown';
crown.position.set(0, 1.675, 0);
root.add(crown);
const crownTop = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.4, 0), 0.05, 5), leafMat);
crownTop.name = 'crownTop';
crownTop.position.set(0.1, 2.125, -0.05);
root.add(crownTop);
const bush = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.2047, 0), 0.04, 11), leafMat);
bush.name = 'bush';
bush.position.set(0.7368, 0.3762, 0.3115);
bush.scale.set(1, 0.8, 1);
root.add(bush);
const bush2 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.2077, 0), 0.04, 12), leafMat);
bush2.name = 'bush';
bush2.position.set(-0.6382, 0.4003, 0.4824);
bush2.scale.set(1, 0.8, 1);
root.add(bush2);
const bush3 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.2626, 0), 0.04, 13), leafMat);
bush3.name = 'bush';
bush3.position.set(-0.0986, 0.4047, -0.7939);
bush3.scale.set(1, 0.8, 1);
root.add(bush3);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createRoundabout;
评分与评论
0 条评论
暂无评论。分享一下你是如何使用这个模型的,或者有哪些可以改进的地方。
相关模型
同一分类或相似标签









