UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

106 lines (75 loc) 2.74 kB
import { BufferGeometry, Float32BufferAttribute, Group, Line, LineBasicMaterial } from "three"; import Vector3 from "../../../src/core/geom/Vector3.js"; import { min2 } from "../../../src/core/math/min2.js"; import Renderable from "../../../src/engine/ecs/renderable/Renderable.js"; import { buildThreeJSHelperEntity } from "./buildThreeJSHelperEntity.js"; import { make3DSymbolicDisplay } from "./make3DSymbolicDisplay.js"; import Path from "../../../src/engine/navigation/ecs/components/Path.js"; /** * * @return {ComponentSymbolicDisplay} * @param {Engine} engine */ export function makePathSymbolicDisplay(engine) { /** * * @param {Path} path * @param {number} q * @returns {BufferGeometry} */ function buildPathGeometry(path, q) { const geometry = new BufferGeometry(); const vertices = []; const v3 = new Vector3(); const length = path.computeLength(); const minStep = (length / path.getPointCount()) / 10; const step = min2(q, minStep); const p = path; let i = 0; for (let c = 0; c < length; c += step) { p.sample(v3, c); vertices[i++] = v3.x; vertices[i++] = v3.y; vertices[i++] = v3.z; } geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); return geometry; } /** * * @param {Path} path * @param entity * @param {SymbolicDisplayInternalAPI} api * @return {Entity} */ function factory([path, entity], api) { const pathObjectMaterial = new LineBasicMaterial({ color: 0xFF0000, opacity: 0.4 }); pathObjectMaterial.depthTest = false; const q = 0.01; const pathObject = new Line(buildPathGeometry(path, q), pathObjectMaterial); pathObject.castShadow = true; function update() { pathObject.geometry = buildPathGeometry(path, q); b.getComponent(Renderable).computeBoundsFromObject(); } for (let i = 0; i < path.getPointCount(); i++) { const p = new Vector3(); path.getPosition(i, p); api.bind(p.onChanged, () => { update(); }); } const group = new Group(); group.frustumCulled = false; group.add(pathObject); const b = buildThreeJSHelperEntity(group); const r = b.getComponent(Renderable); r.matrixAutoUpdate = false; api.emit(b); } return make3DSymbolicDisplay({ engine, components: [Path], factory }) }