playcanvas
Version:
Open-source WebGL/WebGPU 3D engine for the web
1,055 lines (1,054 loc) • 25.5 kB
JavaScript
import { Vec3 } from "../../../core/math/vec3.js";
import { BLEND_NORMAL, EMITTERSHAPE_BOX, LAYERID_DEPTH, LAYERID_WORLD, PARTICLEORIENTATION_SCREEN } from "../../../scene/constants.js";
import { Mesh } from "../../../scene/mesh.js";
import { ParticleEmitter } from "../../../scene/particle-system/particle-emitter.js";
import { Asset } from "../../asset/asset.js";
import { Component } from "../component.js";
const ASSET_PROPERTIES = ["colorMapAsset", "normalMapAsset", "meshAsset", "renderAsset"];
const _properties = [
"autoPlay",
"numParticles",
"lifetime",
"rate",
"rate2",
"startAngle",
"startAngle2",
"loop",
"preWarm",
"lighting",
"halfLambert",
"intensity",
"depthWrite",
"noFog",
"depthSoftening",
"sort",
"blendType",
"stretch",
"alignToMotion",
"emitterShape",
"emitterExtents",
"emitterExtentsInner",
"emitterRadius",
"emitterRadiusInner",
"initialVelocity",
"wrap",
"wrapBounds",
"localSpace",
"screenSpace",
"colorMapAsset",
"normalMapAsset",
"mesh",
"meshAsset",
"renderAsset",
"orientation",
"particleNormal",
"localVelocityGraph",
"localVelocityGraph2",
"velocityGraph",
"velocityGraph2",
"rotationSpeedGraph",
"rotationSpeedGraph2",
"radialSpeedGraph",
"radialSpeedGraph2",
"scaleGraph",
"scaleGraph2",
"colorGraph",
"colorGraph2",
"alphaGraph",
"alphaGraph2",
"colorMap",
"normalMap",
"animTilesX",
"animTilesY",
"animStartFrame",
"animNumFrames",
"animNumAnimations",
"animIndex",
"randomizeAnimIndex",
"animSpeed",
"animLoop",
"layers"
];
let depthLayer;
class ParticleSystemComponent extends Component {
emitter = null;
_requestedDepth = false;
_drawOrder = 0;
_paused = false;
_evtLayersChanged = null;
_evtLayerAdded = null;
_evtLayerRemoved = null;
_evtSetMeshes = null;
_autoPlay = true;
_numParticles = 1;
_lifetime = 50;
_rate = 1;
_rate2 = null;
_startAngle = 0;
_startAngle2 = null;
_loop = true;
_preWarm = false;
_lighting = false;
_halfLambert = false;
_intensity = 1;
_depthWrite = false;
_noFog = false;
_depthSoftening = 0;
_sort = 0;
_blendType = BLEND_NORMAL;
_stretch = 0;
_alignToMotion = false;
_emitterShape = EMITTERSHAPE_BOX;
_emitterExtents = new Vec3();
_emitterExtentsInner = new Vec3();
_emitterRadius = 0;
_emitterRadiusInner = 0;
_initialVelocity = 0;
_wrap = false;
_wrapBounds = new Vec3();
_localSpace = false;
_screenSpace = false;
_colorMapAsset = null;
_normalMapAsset = null;
_mesh = null;
_meshAsset = null;
_renderAsset = null;
_orientation = PARTICLEORIENTATION_SCREEN;
_particleNormal = new Vec3(0, 1, 0);
_localVelocityGraph = null;
_localVelocityGraph2 = null;
_velocityGraph = null;
_velocityGraph2 = null;
_rotationSpeedGraph = null;
_rotationSpeedGraph2 = null;
_radialSpeedGraph = null;
_radialSpeedGraph2 = null;
_scaleGraph = null;
_scaleGraph2 = null;
_colorGraph = null;
_colorGraph2 = null;
_alphaGraph = null;
_alphaGraph2 = null;
_colorMap = null;
_normalMap = null;
_animTilesX = 1;
_animTilesY = 1;
_animStartFrame = 0;
_animNumFrames = 1;
_animNumAnimations = 1;
_animIndex = 0;
_randomizeAnimIndex = false;
_animSpeed = 1;
_animLoop = true;
_layers = [LAYERID_WORLD];
set autoPlay(arg) {
this._autoPlay = arg;
}
get autoPlay() {
return this._autoPlay;
}
set numParticles(arg) {
this._setComplexProperty("numParticles", arg);
}
get numParticles() {
return this._numParticles;
}
set lifetime(arg) {
this._setComplexProperty("lifetime", arg);
}
get lifetime() {
return this._lifetime;
}
set rate(arg) {
this._setComplexProperty("rate", arg);
}
get rate() {
return this._rate;
}
set rate2(arg) {
this._setComplexProperty("rate2", arg);
}
get rate2() {
return this._rate2;
}
set startAngle(arg) {
this._setComplexProperty("startAngle", arg);
}
get startAngle() {
return this._startAngle;
}
set startAngle2(arg) {
this._setComplexProperty("startAngle2", arg);
}
get startAngle2() {
return this._startAngle2;
}
set loop(arg) {
this._loop = arg;
if (this.emitter) {
this.emitter.loop = arg;
this.emitter.resetTime(arg ? void 0 : this.emitter.lifetime);
this.emitter.resetMaterial();
}
}
get loop() {
return this._loop;
}
set preWarm(arg) {
this._setComplexProperty("preWarm", arg);
}
get preWarm() {
return this._preWarm;
}
set lighting(arg) {
this._setComplexProperty("lighting", arg);
}
get lighting() {
return this._lighting;
}
set halfLambert(arg) {
this._setComplexProperty("halfLambert", arg);
}
get halfLambert() {
return this._halfLambert;
}
set intensity(arg) {
this._setComplexProperty("intensity", arg);
}
get intensity() {
return this._intensity;
}
set depthWrite(arg) {
this._setComplexProperty("depthWrite", arg);
}
get depthWrite() {
return this._depthWrite;
}
set noFog(arg) {
this._setComplexProperty("noFog", arg);
}
get noFog() {
return this._noFog;
}
set depthSoftening(arg) {
const oldValue = this._depthSoftening;
if (oldValue !== arg) {
this._depthSoftening = arg;
if (arg) {
if (this.enabled && this.entity.enabled) this._requestDepth();
} else {
if (this.enabled && this.entity.enabled) this._releaseDepth();
}
if (this.emitter) {
this.emitter.depthSoftening = arg;
this.reset();
this.emitter.resetMaterial();
this.rebuild();
}
}
}
get depthSoftening() {
return this._depthSoftening;
}
set sort(arg) {
this._setComplexProperty("sort", arg);
}
get sort() {
return this._sort;
}
set blendType(arg) {
this._blendType = arg;
if (this.emitter) {
this.emitter.blendType = arg;
this.emitter.material.blendType = arg;
this.emitter.resetMaterial();
this.rebuild();
}
}
get blendType() {
return this._blendType;
}
set stretch(arg) {
this._setComplexProperty("stretch", arg);
}
get stretch() {
return this._stretch;
}
set alignToMotion(arg) {
this._setComplexProperty("alignToMotion", arg);
}
get alignToMotion() {
return this._alignToMotion;
}
set emitterShape(arg) {
this._setComplexProperty("emitterShape", arg);
}
get emitterShape() {
return this._emitterShape;
}
set emitterExtents(arg) {
this._setSimpleProperty("emitterExtents", arg);
}
get emitterExtents() {
return this._emitterExtents;
}
set emitterExtentsInner(arg) {
this._setSimpleProperty("emitterExtentsInner", arg);
}
get emitterExtentsInner() {
return this._emitterExtentsInner;
}
set emitterRadius(arg) {
this._setSimpleProperty("emitterRadius", arg);
}
get emitterRadius() {
return this._emitterRadius;
}
set emitterRadiusInner(arg) {
this._setSimpleProperty("emitterRadiusInner", arg);
}
get emitterRadiusInner() {
return this._emitterRadiusInner;
}
set initialVelocity(arg) {
this._setSimpleProperty("initialVelocity", arg);
}
get initialVelocity() {
return this._initialVelocity;
}
set wrap(arg) {
this._setComplexProperty("wrap", arg);
}
get wrap() {
return this._wrap;
}
set wrapBounds(arg) {
this._setComplexProperty("wrapBounds", arg);
}
get wrapBounds() {
return this._wrapBounds;
}
set localSpace(arg) {
this._setComplexProperty("localSpace", arg);
}
get localSpace() {
return this._localSpace;
}
set screenSpace(arg) {
this._setComplexProperty("screenSpace", arg);
}
get screenSpace() {
return this._screenSpace;
}
set colorMapAsset(arg) {
const assets = this.system.app.assets;
if (this._colorMapAsset) {
const asset = assets.get(this._colorMapAsset);
if (asset) {
this._unbindColorMapAsset(asset);
}
}
if (arg instanceof Asset) {
arg = arg.id;
}
this._colorMapAsset = arg;
if (arg) {
const asset = assets.get(arg);
if (asset) {
this._bindColorMapAsset(asset);
} else {
assets.once(`add:${arg}`, (asset2) => {
this._bindColorMapAsset(asset2);
});
}
} else {
this.colorMap = null;
}
}
get colorMapAsset() {
return this._colorMapAsset;
}
set normalMapAsset(arg) {
const assets = this.system.app.assets;
if (this._normalMapAsset) {
const asset = assets.get(this._normalMapAsset);
if (asset) {
this._unbindNormalMapAsset(asset);
}
}
if (arg instanceof Asset) {
arg = arg.id;
}
this._normalMapAsset = arg;
if (arg) {
const asset = assets.get(arg);
if (asset) {
this._bindNormalMapAsset(asset);
} else {
assets.once(`add:${arg}`, (asset2) => {
this._bindNormalMapAsset(asset2);
});
}
} else {
this.normalMap = null;
}
}
get normalMapAsset() {
return this._normalMapAsset;
}
set mesh(arg) {
if (!arg || arg instanceof Asset || typeof arg === "number") {
this.meshAsset = arg;
} else {
this._onMeshChanged(arg);
}
}
get mesh() {
return this._mesh;
}
set meshAsset(arg) {
const assets = this.system.app.assets;
if (this._meshAsset) {
const asset = assets.get(this._meshAsset);
if (asset) {
this._unbindMeshAsset(asset);
}
}
if (arg instanceof Asset) {
arg = arg.id;
}
this._meshAsset = arg;
if (arg) {
const asset = assets.get(arg);
if (asset) {
this._bindMeshAsset(asset);
}
} else {
this._onMeshChanged(null);
}
}
get meshAsset() {
return this._meshAsset;
}
set renderAsset(arg) {
const assets = this.system.app.assets;
if (this._renderAsset) {
const asset = assets.get(this._renderAsset);
if (asset) {
this._unbindRenderAsset(asset);
}
}
if (arg instanceof Asset) {
arg = arg.id;
}
this._renderAsset = arg;
if (arg) {
const asset = assets.get(arg);
if (asset) {
this._bindRenderAsset(asset);
}
} else {
this._onRenderChanged(null);
}
}
get renderAsset() {
return this._renderAsset;
}
set orientation(arg) {
this._setComplexProperty("orientation", arg);
}
get orientation() {
return this._orientation;
}
set particleNormal(arg) {
this._setSimpleProperty("particleNormal", arg);
}
get particleNormal() {
return this._particleNormal;
}
set localVelocityGraph(arg) {
this._setGraphProperty("localVelocityGraph", arg);
}
get localVelocityGraph() {
return this._localVelocityGraph;
}
set localVelocityGraph2(arg) {
this._setGraphProperty("localVelocityGraph2", arg);
}
get localVelocityGraph2() {
return this._localVelocityGraph2;
}
set velocityGraph(arg) {
this._setGraphProperty("velocityGraph", arg);
}
get velocityGraph() {
return this._velocityGraph;
}
set velocityGraph2(arg) {
this._setGraphProperty("velocityGraph2", arg);
}
get velocityGraph2() {
return this._velocityGraph2;
}
set rotationSpeedGraph(arg) {
this._setGraphProperty("rotationSpeedGraph", arg);
}
get rotationSpeedGraph() {
return this._rotationSpeedGraph;
}
set rotationSpeedGraph2(arg) {
this._setGraphProperty("rotationSpeedGraph2", arg);
}
get rotationSpeedGraph2() {
return this._rotationSpeedGraph2;
}
set radialSpeedGraph(arg) {
this._setGraphProperty("radialSpeedGraph", arg);
}
get radialSpeedGraph() {
return this._radialSpeedGraph;
}
set radialSpeedGraph2(arg) {
this._setGraphProperty("radialSpeedGraph2", arg);
}
get radialSpeedGraph2() {
return this._radialSpeedGraph2;
}
set scaleGraph(arg) {
this._setGraphProperty("scaleGraph", arg);
}
get scaleGraph() {
return this._scaleGraph;
}
set scaleGraph2(arg) {
this._setGraphProperty("scaleGraph2", arg);
}
get scaleGraph2() {
return this._scaleGraph2;
}
set colorGraph(arg) {
this._setGraphProperty("colorGraph", arg);
}
get colorGraph() {
return this._colorGraph;
}
set colorGraph2(arg) {
this._setGraphProperty("colorGraph2", arg);
}
get colorGraph2() {
return this._colorGraph2;
}
set alphaGraph(arg) {
this._setGraphProperty("alphaGraph", arg);
}
get alphaGraph() {
return this._alphaGraph;
}
set alphaGraph2(arg) {
this._setGraphProperty("alphaGraph2", arg);
}
get alphaGraph2() {
return this._alphaGraph2;
}
set colorMap(arg) {
this._setComplexProperty("colorMap", arg);
}
get colorMap() {
return this._colorMap;
}
set normalMap(arg) {
this._setSimpleProperty("normalMap", arg);
}
get normalMap() {
return this._normalMap;
}
set animTilesX(arg) {
this._setComplexProperty("animTilesX", arg);
}
get animTilesX() {
return this._animTilesX;
}
set animTilesY(arg) {
this._setComplexProperty("animTilesY", arg);
}
get animTilesY() {
return this._animTilesY;
}
set animStartFrame(arg) {
this._setComplexProperty("animStartFrame", arg);
}
get animStartFrame() {
return this._animStartFrame;
}
set animNumFrames(arg) {
this._setComplexProperty("animNumFrames", arg);
}
get animNumFrames() {
return this._animNumFrames;
}
set animNumAnimations(arg) {
this._setComplexProperty("animNumAnimations", arg);
}
get animNumAnimations() {
return this._animNumAnimations;
}
set animIndex(arg) {
this._setComplexProperty("animIndex", arg);
}
get animIndex() {
return this._animIndex;
}
set randomizeAnimIndex(arg) {
this._setComplexProperty("randomizeAnimIndex", arg);
}
get randomizeAnimIndex() {
return this._randomizeAnimIndex;
}
set animSpeed(arg) {
this._setSimpleProperty("animSpeed", arg);
}
get animSpeed() {
return this._animSpeed;
}
set animLoop(arg) {
this._setComplexProperty("animLoop", arg);
}
get animLoop() {
return this._animLoop;
}
set layers(arg) {
const oldLayers = this._layers;
this._layers = arg;
if (!this.emitter) return;
for (let i = 0; i < oldLayers.length; i++) {
const layer = this.system.app.scene.layers.getLayerById(oldLayers[i]);
if (!layer) continue;
layer.removeMeshInstances([this.emitter.meshInstance]);
}
if (!this.enabled || !this.entity.enabled) return;
for (let i = 0; i < arg.length; i++) {
const layer = this.system.app.scene.layers.getLayerById(arg[i]);
if (!layer) continue;
layer.addMeshInstances([this.emitter.meshInstance]);
}
}
get layers() {
return this._layers;
}
set drawOrder(drawOrder) {
this._drawOrder = drawOrder;
if (this.emitter) {
this.emitter.drawOrder = drawOrder;
}
}
get drawOrder() {
return this._drawOrder;
}
_setSimpleProperty(name, arg) {
this[`_${name}`] = arg;
if (this.emitter) {
this.emitter[name] = arg;
this.emitter.resetMaterial();
}
}
_setComplexProperty(name, arg) {
this[`_${name}`] = arg;
if (this.emitter) {
this.emitter[name] = arg;
this.emitter.resetMaterial();
this.rebuild();
this.reset();
}
}
_setGraphProperty(name, arg) {
this[`_${name}`] = arg;
if (this.emitter) {
this.emitter[name] = arg;
this.emitter.rebuildGraphs();
this.emitter.resetMaterial();
}
}
addMeshInstanceToLayers() {
if (!this.emitter) return;
for (let i = 0; i < this._layers.length; i++) {
const layer = this.system.app.scene.layers.getLayerById(this._layers[i]);
if (!layer) continue;
layer.addMeshInstances([this.emitter.meshInstance]);
this.emitter._layer = layer;
}
}
removeMeshInstanceFromLayers() {
if (!this.emitter) return;
for (let i = 0; i < this._layers.length; i++) {
const layer = this.system.app.scene.layers.getLayerById(this._layers[i]);
if (!layer) continue;
layer.removeMeshInstances([this.emitter.meshInstance]);
}
}
onLayersChanged(oldComp, newComp) {
this.addMeshInstanceToLayers();
oldComp.off("add", this.onLayerAdded, this);
oldComp.off("remove", this.onLayerRemoved, this);
newComp.on("add", this.onLayerAdded, this);
newComp.on("remove", this.onLayerRemoved, this);
}
onLayerAdded(layer) {
if (!this.emitter) return;
const index = this._layers.indexOf(layer.id);
if (index < 0) return;
layer.addMeshInstances([this.emitter.meshInstance]);
}
onLayerRemoved(layer) {
if (!this.emitter) return;
const index = this._layers.indexOf(layer.id);
if (index < 0) return;
layer.removeMeshInstances([this.emitter.meshInstance]);
}
_bindColorMapAsset(asset) {
asset.on("load", this._onColorMapAssetLoad, this);
asset.on("unload", this._onColorMapAssetUnload, this);
asset.on("remove", this._onColorMapAssetRemove, this);
asset.on("change", this._onColorMapAssetChange, this);
if (asset.resource) {
this._onColorMapAssetLoad(asset);
} else {
if (!this.enabled || !this.entity.enabled) return;
this.system.app.assets.load(asset);
}
}
_unbindColorMapAsset(asset) {
asset.off("load", this._onColorMapAssetLoad, this);
asset.off("unload", this._onColorMapAssetUnload, this);
asset.off("remove", this._onColorMapAssetRemove, this);
asset.off("change", this._onColorMapAssetChange, this);
}
_onColorMapAssetLoad(asset) {
this.colorMap = asset.resource;
}
_onColorMapAssetUnload(asset) {
this.colorMap = null;
}
_onColorMapAssetRemove(asset) {
this._onColorMapAssetUnload(asset);
}
_onColorMapAssetChange(asset) {
}
_bindNormalMapAsset(asset) {
asset.on("load", this._onNormalMapAssetLoad, this);
asset.on("unload", this._onNormalMapAssetUnload, this);
asset.on("remove", this._onNormalMapAssetRemove, this);
asset.on("change", this._onNormalMapAssetChange, this);
if (asset.resource) {
this._onNormalMapAssetLoad(asset);
} else {
if (!this.enabled || !this.entity.enabled) return;
this.system.app.assets.load(asset);
}
}
_unbindNormalMapAsset(asset) {
asset.off("load", this._onNormalMapAssetLoad, this);
asset.off("unload", this._onNormalMapAssetUnload, this);
asset.off("remove", this._onNormalMapAssetRemove, this);
asset.off("change", this._onNormalMapAssetChange, this);
}
_onNormalMapAssetLoad(asset) {
this.normalMap = asset.resource;
}
_onNormalMapAssetUnload(asset) {
this.normalMap = null;
}
_onNormalMapAssetRemove(asset) {
this._onNormalMapAssetUnload(asset);
}
_onNormalMapAssetChange(asset) {
}
_bindMeshAsset(asset) {
asset.on("load", this._onMeshAssetLoad, this);
asset.on("unload", this._onMeshAssetUnload, this);
asset.on("remove", this._onMeshAssetRemove, this);
asset.on("change", this._onMeshAssetChange, this);
if (asset.resource) {
this._onMeshAssetLoad(asset);
} else {
if (!this.enabled || !this.entity.enabled) return;
this.system.app.assets.load(asset);
}
}
_unbindMeshAsset(asset) {
asset.off("load", this._onMeshAssetLoad, this);
asset.off("unload", this._onMeshAssetUnload, this);
asset.off("remove", this._onMeshAssetRemove, this);
asset.off("change", this._onMeshAssetChange, this);
}
_onMeshAssetLoad(asset) {
this._onMeshChanged(asset.resource);
}
_onMeshAssetUnload(asset) {
this.mesh = null;
}
_onMeshAssetRemove(asset) {
this._onMeshAssetUnload(asset);
}
_onMeshAssetChange(asset) {
}
_onMeshChanged(mesh) {
if (mesh && !(mesh instanceof Mesh)) {
if (mesh.meshInstances[0]) {
mesh = mesh.meshInstances[0].mesh;
} else {
mesh = null;
}
}
this._mesh = mesh;
if (this.emitter) {
this.emitter.mesh = mesh;
this.emitter.resetMaterial();
this.rebuild();
}
}
_bindRenderAsset(asset) {
asset.on("load", this._onRenderAssetLoad, this);
asset.on("unload", this._onRenderAssetUnload, this);
asset.on("remove", this._onRenderAssetRemove, this);
if (asset.resource) {
this._onRenderAssetLoad(asset);
} else {
if (!this.enabled || !this.entity.enabled) return;
this.system.app.assets.load(asset);
}
}
_unbindRenderAsset(asset) {
asset.off("load", this._onRenderAssetLoad, this);
asset.off("unload", this._onRenderAssetUnload, this);
asset.off("remove", this._onRenderAssetRemove, this);
this._evtSetMeshes?.off();
this._evtSetMeshes = null;
}
_onRenderAssetLoad(asset) {
this._onRenderChanged(asset.resource);
}
_onRenderAssetUnload(asset) {
this._onRenderChanged(null);
}
_onRenderAssetRemove(asset) {
this._onRenderAssetUnload(asset);
}
_onRenderChanged(render) {
if (!render) {
this._onMeshChanged(null);
return;
}
this._evtSetMeshes?.off();
this._evtSetMeshes = render.on("set:meshes", this._onRenderSetMeshes, this);
if (render.meshes) {
this._onRenderSetMeshes(render.meshes);
}
}
_onRenderSetMeshes(meshes) {
this._onMeshChanged(meshes && meshes[0]);
}
_requestDepth() {
if (this._requestedDepth) return;
if (!depthLayer) depthLayer = this.system.app.scene.layers.getLayerById(LAYERID_DEPTH);
if (depthLayer) {
depthLayer.incrementCounter();
this._requestedDepth = true;
}
}
_releaseDepth() {
if (!this._requestedDepth) return;
if (depthLayer) {
depthLayer.decrementCounter();
this._requestedDepth = false;
}
}
onEnable() {
const scene = this.system.app.scene;
const layers = scene.layers;
for (let i = 0, len = ASSET_PROPERTIES.length; i < len; i++) {
let asset = this[`_${ASSET_PROPERTIES[i]}`];
if (asset) {
if (!(asset instanceof Asset)) {
const id = parseInt(asset, 10);
if (id >= 0) {
asset = this.system.app.assets.get(asset);
} else {
continue;
}
}
if (asset && !asset.resource) {
this.system.app.assets.load(asset);
}
}
}
if (this.system.app.graphicsDevice.disableParticleSystem) {
return;
}
if (!this.emitter) {
this.emitter = new ParticleEmitter(this.system.app.graphicsDevice, {
numParticles: this._numParticles,
emitterExtents: this._emitterExtents,
emitterExtentsInner: this._emitterExtentsInner,
emitterRadius: this._emitterRadius,
emitterRadiusInner: this._emitterRadiusInner,
emitterShape: this._emitterShape,
initialVelocity: this._initialVelocity,
wrap: this._wrap,
localSpace: this._localSpace,
screenSpace: this._screenSpace,
wrapBounds: this._wrapBounds,
lifetime: this._lifetime,
rate: this._rate,
rate2: this._rate2,
orientation: this._orientation,
particleNormal: this._particleNormal,
animTilesX: this._animTilesX,
animTilesY: this._animTilesY,
animStartFrame: this._animStartFrame,
animNumFrames: this._animNumFrames,
animNumAnimations: this._animNumAnimations,
animIndex: this._animIndex,
randomizeAnimIndex: this._randomizeAnimIndex,
animSpeed: this._animSpeed,
animLoop: this._animLoop,
startAngle: this._startAngle,
startAngle2: this._startAngle2,
scaleGraph: this._scaleGraph,
scaleGraph2: this._scaleGraph2,
colorGraph: this._colorGraph,
colorGraph2: this._colorGraph2,
alphaGraph: this._alphaGraph,
alphaGraph2: this._alphaGraph2,
localVelocityGraph: this._localVelocityGraph,
localVelocityGraph2: this._localVelocityGraph2,
velocityGraph: this._velocityGraph,
velocityGraph2: this._velocityGraph2,
rotationSpeedGraph: this._rotationSpeedGraph,
rotationSpeedGraph2: this._rotationSpeedGraph2,
radialSpeedGraph: this._radialSpeedGraph,
radialSpeedGraph2: this._radialSpeedGraph2,
colorMap: this._colorMap,
normalMap: this._normalMap,
loop: this._loop,
preWarm: this._preWarm,
sort: this._sort,
stretch: this._stretch,
alignToMotion: this._alignToMotion,
lighting: this._lighting,
halfLambert: this._halfLambert,
intensity: this._intensity,
depthSoftening: this._depthSoftening,
scene: this.system.app.scene,
mesh: this._mesh,
depthWrite: this._depthWrite,
noFog: this._noFog,
node: this.entity,
blendType: this._blendType
});
this.emitter.meshInstance.node = this.entity;
this.emitter.drawOrder = this._drawOrder;
if (!this._autoPlay) {
this.pause();
this.emitter.meshInstance.visible = false;
}
}
if (this.emitter.colorMap) {
this.addMeshInstanceToLayers();
}
this._evtLayersChanged = scene.on("set:layers", this.onLayersChanged, this);
if (layers) {
this._evtLayerAdded = layers.on("add", this.onLayerAdded, this);
this._evtLayerRemoved = layers.on("remove", this.onLayerRemoved, this);
}
if (this.enabled && this.entity.enabled && this._depthSoftening) {
this._requestDepth();
}
}
onDisable() {
const scene = this.system.app.scene;
const layers = scene.layers;
this._evtLayersChanged?.off();
this._evtLayersChanged = null;
if (layers) {
this._evtLayerAdded?.off();
this._evtLayerAdded = null;
this._evtLayerRemoved?.off();
this._evtLayerRemoved = null;
}
if (this.emitter) {
this.removeMeshInstanceFromLayers();
if (this._depthSoftening) this._releaseDepth();
this.emitter.camera = null;
}
}
onBeforeRemove() {
if (this.enabled) {
this.enabled = false;
}
if (this.emitter) {
this.emitter.destroy();
this.emitter = null;
}
for (let i = 0; i < ASSET_PROPERTIES.length; i++) {
const prop = ASSET_PROPERTIES[i];
if (this[`_${prop}`]) {
this[prop] = null;
}
}
this.off();
}
reset() {
if (this.emitter) {
this.emitter.reset();
}
}
stop() {
if (this.emitter) {
this.emitter.loop = false;
this.emitter.resetTime(this.emitter.lifetime);
this.emitter.addTime(0, true);
}
}
pause() {
this._paused = true;
}
unpause() {
this._paused = false;
}
play() {
this._paused = false;
if (this.emitter) {
this.emitter.meshInstance.visible = true;
this.emitter.loop = this._loop;
this.emitter.resetTime();
}
}
isPlaying() {
if (this._paused || !this.emitter) {
return false;
}
if (this.emitter.loop) {
return true;
}
return this.emitter.simTimeTotal <= this.emitter.endTime;
}
setInTools() {
const { emitter } = this;
if (emitter && !emitter.inTools) {
emitter.inTools = true;
this.rebuild();
}
}
rebuild() {
const enabled = this.enabled;
this.enabled = false;
if (this.emitter) {
this.emitter.rebuild();
}
this.enabled = enabled;
}
}
export {
ParticleSystemComponent,
_properties
};