@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
147 lines (109 loc) • 4.28 kB
JavaScript
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
});
}