UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

147 lines (109 loc) 4.28 kB
import { make3DSymbolicDisplay } from "./make3DSymbolicDisplay.js"; import { Transform } from "../../../src/engine/ecs/transform/Transform.js"; import { BoxBufferGeometry, Group, Line, LineBasicMaterial, Mesh, MeshBasicMaterial } from "three"; import { buildThreeJSHelperEntity } from "./buildThreeJSHelperEntity.js"; import { ParticleEmitter } from "../../../src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js"; import { makeHelperSphereGeometry } from "./makeHelperSphereGeometry.js"; import { EmissionShapeType } from "../../../src/engine/graphics/particles/particular/engine/emitter/EmissionShapeType.js"; /** * * @param {Engine} engine */ export function makeParticleEmitterSymbolicDisplay(engine) { const wireframeMaterial = new MeshBasicMaterial({ wireframe: true, depthTest: true }); const lineMaterial = new LineBasicMaterial({ depthTest: true, depthWrite: false, transparent: true, linewidth: 1, fog: false, color: '#FFFFFF', opacity: 0.5 }); const centerMaterial = new MeshBasicMaterial({ color: 0xFF0000, transparent: true, opacity: 0.2 }); const sphereBufferGeometry = makeHelperSphereGeometry(0.5, 64); const boxGeometry = new BoxBufferGeometry(1, 1, 1, 1, 1, 1,); const centerGeometry = new BoxBufferGeometry(0.03, 0.03, 0.03, 1, 1, 1,); /** * * @param {ParticleEmitter} emitter * @param {Transform} transform * @param {number} entity * @param {SymbolicDisplayInternalAPI} api * @returns {Entity} */ function factory([emitter, transform, entity], api) { const group = new Group(); group.name = 'Particle Emitter Gizmo'; /** * * @param {ParticleLayer} layer */ function addLayer(layer) { const emissionShape = layer.emissionShape; const center = new Mesh(centerGeometry, centerMaterial); center.name = "Center Marker"; center.frustumCulled = false; center.position.copy(layer.position); group.add(center); let geometry; let mesh; if (emissionShape === EmissionShapeType.Box) { geometry = boxGeometry; mesh = new Mesh(geometry, wireframeMaterial); } else if (emissionShape === EmissionShapeType.Sphere) { geometry = sphereBufferGeometry; mesh = new Line(geometry, lineMaterial); } function updateScale() { center.scale.set( 1 / transform.scale.x, 1 / transform.scale.y, 1 / transform.scale.z ); mesh.scale.set( layer.scale.x, layer.scale.y, layer.scale.z ); } function updatePosition() { mesh.position.copy(layer.position); } if (mesh !== undefined) { mesh.frustumCulled = false; updateScale(); updatePosition(); group.add(mesh); api.bind(layer.position.onChanged, updatePosition); api.bind(layer.scale.onChanged, updateScale); api.bind(transform.scale.onChanged, updateScale); } } /** * * @param {ParticleLayer} layer */ function removeLayer(layer) { // TODO implement } emitter.traverseLayers(addLayer); const builder = buildThreeJSHelperEntity(group, entity); /** * * @type {Transform} */ const t = builder.getComponent(Transform); api.bindTransform(transform, t); api.bind(emitter.layers.on.added, addLayer, {}); api.bind(emitter.layers.on.removed, removeLayer, {}); api.emit(builder); } return make3DSymbolicDisplay({ engine, components: [ParticleEmitter, Transform], factory }); }