@megavr/ecsy-babylon
Version:
babylon.js ecsy binding and helpers
95 lines (89 loc) • 3.81 kB
text/typescript
import * as BABYLON from "@babylonjs/core";
import { System, Entity } from "ecsy";
import { Particle, ParticleTypes } from "../components/index";
import { ParticleColorProperties } from "../components/types/index";
import { getScene, getAssetManager } from "../utils/gameUtils";
import { xyzToVector3 } from "../utils/mathUtils";
import { updateObjectValue, updateObjectVector3, updateObjectsTransform, disposeObject } from "../utils/objectUtils";
import { updateTexture, hexToColor4 } from "../utils/materialUtils";
/** System for Particle component */
export class ParticleSystem extends System {
/** @hidden */
static queries = {
particle: { components: [Particle], listen: { added: true, removed: true, changed: [Particle] } },
};
/** @hidden */
queries: any;
/** @hidden */
execute() {
this.queries.particle.added.forEach((entity: Entity) => {
let particle = entity.getComponent(Particle);
particle.object = new BABYLON.ParticleSystem(particle.type!, particle.capacity!, getScene(this, particle.scene));
let particleObject = particle.object;
switch (particle.type) {
case ParticleTypes.Point:
particleObject.createPointEmitter(xyzToVector3(particle.direction1), xyzToVector3(particle.direction2));
break;
case ParticleTypes.Box:
particleObject.createBoxEmitter(xyzToVector3(particle.direction1), xyzToVector3(particle.direction2), xyzToVector3(particle.minEmitBox), xyzToVector3(particle.maxEmitBox));
break;
case ParticleTypes.Sphere:
particleObject.createSphereEmitter(particle.radius, particle.radiusRange);
break;
case ParticleTypes.DirectedSphere:
particleObject.createDirectedSphereEmitter(particle.radius, xyzToVector3(particle.direction1), xyzToVector3(particle.direction2));
break;
case ParticleTypes.Hemisphere:
particleObject.createHemisphericEmitter(particle.radius, particle.radiusRange);
break;
case ParticleTypes.Cylinder:
particleObject.createCylinderEmitter(particle.radius, particle.height, particle.radiusRange, Math.random());
break;
case ParticleTypes.DirectedCylinder:
particleObject.createDirectedCylinderEmitter(particle.radius, particle.height, particle.radiusRange, xyzToVector3(particle.direction1), xyzToVector3(particle.direction2));
break;
case ParticleTypes.Cone:
particleObject.createConeEmitter(particle.radius, particle.angle);
break;
}
this._updateParticle(particle);
updateObjectsTransform(entity);
particleObject.start();
});
this.queries.particle.changed.forEach((entity: Entity) => {
this._updateParticle(entity.getComponent(Particle));
});
this.queries.particle.removed.forEach((entity: Entity) => {
let particle = entity.getComponent(Particle);
particle.object.stop();
disposeObject(particle);
});
}
private _updateParticle(particle: Particle) {
for (let prop in particle) {
switch (prop) {
case "emitter":
case "direction1":
case "direction2":
case "minEmitBox":
case "maxEmitBox":
updateObjectVector3(particle, prop);
break;
case "texture":
updateTexture(particle, particle.texture!, getAssetManager(this, particle.scene));
break;
case "color":
this._updateColor(particle, particle.color!);
break;
default:
updateObjectValue(particle, prop);
break;
}
}
}
private _updateColor(particle: Particle, color: ParticleColorProperties) {
for (let prop in color) {
(particle.object as any)[prop] = hexToColor4((color as any)[prop]);
}
}
}