File size: 1,886 Bytes
970fc3e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | import { UI_THEME as T } from "../../shared/ui-theme.mjs";
import * as THREE from "three";
function createPathGuide(world) {
const group = new THREE.Group();
world.add(group);
let key = "";
return { sync(path) {
const next = JSON.stringify(path?.points);
if (next === key) return;
key = next;
for (const o of [...group.children]) {
group.remove(o);
o.traverse((c) => {
c.geometry?.dispose();
c.material?.dispose();
});
}
if (!path) return;
const points = path.points.map((p) => new THREE.Vector3(p[0], p[1] + 0.035, p[2])), curve = new THREE.CurvePath();
for (let i = 1; i < points.length; i++) curve.add(new THREE.LineCurve3(points[i - 1], points[i]));
const halo = new THREE.Mesh(new THREE.TubeGeometry(curve, Math.max(16, points.length * 2), 0.022, 6, false), new THREE.MeshBasicMaterial({ toneMapped: false, color: T.panel, depthTest: false }));
halo.renderOrder = 12;
group.add(halo);
const line = new THREE.Mesh(new THREE.TubeGeometry(curve, Math.max(16, points.length * 2), 0.012, 6, false), new THREE.MeshBasicMaterial({ toneMapped: false, color: T.accent, depthTest: false }));
line.renderOrder = 13;
group.add(line);
for (const point of [points[0], points.at(-1)]) {
const node = new THREE.Mesh(new THREE.SphereGeometry(0.04, 10, 8), new THREE.MeshBasicMaterial({ toneMapped: false, color: T.accent, depthTest: false }));
node.position.copy(point);
node.renderOrder = 14;
group.add(node);
}
const direction = points.at(-1).clone().sub(points.at(-2)).normalize();
const arrow = new THREE.ArrowHelper(direction, points.at(-1), 0.35, T.accent, 0.14, 0.09);
arrow.line.material.toneMapped = arrow.cone.material.toneMapped = false;
group.add(arrow);
}, show(value) {
group.visible = value;
} };
}
export {
createPathGuide
};
|