diff --git a/README.md b/README.md index 4e36aad..9dfb8f1 100644 --- a/README.md +++ b/README.md @@ -142,15 +142,7 @@ loader.setCrossOrigin(""); loader.load(jsonURL, (obj) => { // the API uses manuel loading because users may need to // store the VFX somewhere to reuse it later. - obj.traverse((child) => { - if (child.type === "ParticleEmitter") { - // only if want to display the VFX - batchRenderer.addSystem(child.system); - } - }); - if (obj.type === "ParticleEmitter") { - batchRenderer.addSystem(obj.system); - } + QuarksUtil.addToBatchRenderer(obj, batchRenderer); scene.add(obj); }, () => { }, () => { diff --git a/packages/three.quarks/examples/explosionDemo.js b/packages/three.quarks/examples/explosionDemo.js index 36a14e5..e9a16b1 100644 --- a/packages/three.quarks/examples/explosionDemo.js +++ b/packages/three.quarks/examples/explosionDemo.js @@ -1,6 +1,7 @@ import { BatchedParticleRenderer, QuarksLoader, + QuarksUtil, } from 'three.quarks'; import {Demo} from './demo.js'; @@ -14,14 +15,7 @@ export class ExplosionDemo extends Demo { this.scene.add(this.batchRenderer); new QuarksLoader().load('ps.json', (obj) => { - obj.traverse((child) => { - if (child.type === 'ParticleEmitter') { - this.batchRenderer.addSystem(child.system); - } - }); - if (obj.type === 'ParticleEmitter') { - this.batchRenderer.addSystem(obj.system); - } + QuarksUtil.addToBatchRenderer(obj, this.batchRenderer); this.scene.add(obj); this.groups.push(obj); }); diff --git a/packages/three.quarks/package.json b/packages/three.quarks/package.json index 8d8872a..34b5360 100644 --- a/packages/three.quarks/package.json +++ b/packages/three.quarks/package.json @@ -1,6 +1,6 @@ { "name": "three.quarks", - "version": "0.15.0", + "version": "0.15.1", "description": "A General-Purpose Particle System for three.js", "type": "module", "types": "./dist/types/index.d.ts", diff --git a/packages/three.quarks/src/QuarksUtil.ts b/packages/three.quarks/src/QuarksUtil.ts new file mode 100644 index 0000000..9a71d43 --- /dev/null +++ b/packages/three.quarks/src/QuarksUtil.ts @@ -0,0 +1,85 @@ +import {Object3D} from 'three'; +import {ParticleEmitter} from './ParticleEmitter'; +import {BatchedRenderer} from './BatchedRenderer'; + + +export class QuarksUtil { + /** + * Run a function on all particle emitters in the object and the object's children. + * @param obj + * @param func + */ + static runOnAllParticleEmitters(obj: Object3D, func: (ps: ParticleEmitter) => void) { + obj.traverse((child) => { + if (child.type === 'ParticleEmitter') { + func(child as ParticleEmitter); + } + }); + if (obj.type === 'ParticleEmitter') { + func(obj as ParticleEmitter); + } + } + + /** + * Add all particle systems in the object and the object's children to the batch renderer. + * @param obj + * @param batchRenderer + */ + static addToBatchRenderer(obj: Object3D, batchRenderer: BatchedRenderer) { + QuarksUtil.runOnAllParticleEmitters(obj, (ps) => { + batchRenderer.addSystem(ps.system); + }); + } + + /** + * Start playing all particle systems in the object and the object's children. + * @param obj + */ + static play(obj: Object3D) { + QuarksUtil.runOnAllParticleEmitters(obj, (ps) => { + ps.system.play(); + }); + } + + /** + * Stop all particle systems in the object and the object's children. + * this call will clear all existing particles. + * @param obj + */ + static stop(obj: Object3D) { + QuarksUtil.runOnAllParticleEmitters(obj, (ps) => { + ps.system.stop(); + }); + } + + /** + * Stop emit new particles from all particle systems and + * keep simulating the existing particles in the object and the object's children. + * @param obj + */ + static endEmit(obj: Object3D) { + QuarksUtil.runOnAllParticleEmitters(obj, (ps) => { + ps.system.endEmit(); + }); + } + + /** + * Restart all particle systems in the object and the object's children. + * @param obj + */ + static restart(obj: Object3D) { + QuarksUtil.runOnAllParticleEmitters(obj, (ps) => { + ps.system.restart(); + }); + } + + /** + * Pause the simulation of all particle systems in the object and the object's children. + * @param obj + */ + static pause(obj: Object3D) { + QuarksUtil.runOnAllParticleEmitters(obj, (ps) => { + ps.system.restart(); + }); + } +} \ No newline at end of file diff --git a/packages/three.quarks/src/index.ts b/packages/three.quarks/src/index.ts index 2668384..5084335 100644 --- a/packages/three.quarks/src/index.ts +++ b/packages/three.quarks/src/index.ts @@ -9,6 +9,7 @@ export * from './MeshSurfaceEmitter'; export * from './BatchedRenderer'; export * from './BatchedParticleRenderer'; export * from './QuarksLoader'; +export * from './QuarksUtil'; export * from './shaders/'; export * from './materials/'; export * from 'quarks.core';