Skip to content

Commit

Permalink
Merge 66996ff into d908ca5
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewleek-droplab committed Apr 27, 2022
2 parents d908ca5 + 66996ff commit e35afe3
Show file tree
Hide file tree
Showing 8 changed files with 246 additions and 8 deletions.
1 change: 0 additions & 1 deletion sandbox/common/Visualization.js
Expand Up @@ -106,7 +106,6 @@ window.Visualization = class {
canvas: { clientWidth, clientHeight },
} = this;

console.log(this);

camera.aspect = clientWidth / clientHeight;
camera.updateProjectionMatrix();
Expand Down
146 changes: 146 additions & 0 deletions sandbox/experiments/start-stop/data.js
@@ -0,0 +1,146 @@
window.SYSTEM = {
headerState: {
projectName: 'data',
version: { loading: false, error: null, data: null },
release: { loading: false, error: null, data: null },
shouldShowReleaseDownloadDialog: false,
},
particleSystemState: {
preParticles: 500,
integrationType: 'EULER',
emitters: [
{
id: '51ca9450-3d8b-11e9-a1e8-4785d9606b75',
totalEmitTimes: null,
life: null,
cache: { totalEmitTimes: 2, life: 0.5 },
rate: {
particlesMin: 1,
particlesMax: 4,
perSecondMin: 0.01,
perSecondMax: 0.02,
},
position: { x: 0, y: 0, z: 0 },
rotation: { x: 0, y: 0, z: 0 },
initializers: [
{
id: '51ca9451-3d8b-11e9-a1e8-4785d9606b75',
type: 'Mass',
properties: { min: 30, max: 10, isEnabled: true },
},
{
id: '51ca9452-3d8b-11e9-a1e8-4785d9606b75',
type: 'Life',
properties: { min: 2, max: 4, isEnabled: true },
},
{
id: '51ca9453-3d8b-11e9-a1e8-4785d9606b75',
type: 'BodySprite',
properties: {
texture:
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJkSURBVHjaxJeJbusgEEW94S1L//83X18M2MSuLd2pbqc4wZGqRLrKBsyZhQHny7Jk73xVL8xpVhWrcmiB5lX+6GJ5YgQ2owbAm8oIwH1VgKZUmGcRqKGGPgtEQQAzGR8hQ59fAmhJHSAagigJ4E7GPWRXOYC6owAd1JM6wDQPADyMWUqZRMqmAojHp1Vn6EQQEgUNMJLnUjMyJsM49wygBkAPw9dVFwXRkncCIIW3GRgoTQUZn6HxCMAFEFd8TwEQ78X4rHbILoAUmeT+RFG4UhQ6MiIAE4W/UsYFjuVjAIa2nIY4q1R0GFtQWG3E84lqw2GO2QOoCKBVu0BAPgDSU0eUDjjQenNkV/AW/pWChhpMTelo1a64AOKM30vk18GzTHXCNtI/Knz3DFBgsUqBGIjTInXRY1yA9xkVoqW5tVq3pDR9A0hfF5BSARmVnh7RMDCaIdcNgbPBkgzn1Bu+SfIEFSpSBmkxyrMicb0fAEuCZrWnN89veA/4XcakrPcjBWzkTuLjlbfTQPOlBhz+HwkqqPXmPQDdrQItxE1moGof1S74j/8txk8EHhTQrAE8qlwfqS5yukm1x/rAJ9Jiaa6nyATqD78aUVBhFo8b1V4DdTXdCW+IxA1zB4JhiOhZMEWO1HqnvdoHZ4FAMIhV9REF8FiUm0jsYPEJx/Fm/N8OhH90HI9YRHesWbXXZwAShU8qThe7H8YAuJmw5yOd989uRINKRTJAhoF8jbqrHKfeCYdIISZfSq26bk/K+yO3YvfKrVgiwQBHnwt8ynPB25+M8hceTt/ybPhnryJ78+tLgAEAuCFyiQgQB30AAAAASUVORK5CYII=',
isEnabled: true,
},
},
{
id: '51ca9454-3d8b-11e9-a1e8-4785d9606b75',
type: 'Radius',
properties: { width: 12, height: 4, isEnabled: true },
},
{
id: '51ca9455-3d8b-11e9-a1e8-4785d9606b75',
type: 'RadialVelocity',
properties: {
radius: 10,
x: 0,
y: 5,
z: 0,
theta: 900,
isEnabled: true,
},
},
],
behaviours: [
{
id: '51ca9456-3d8b-11e9-a1e8-4785d9606b75',
type: 'Alpha',
properties: {
alphaA: 1,
alphaB: 0,
life: null,
easing: 'easeLinear',
},
},
{
id: '51ca9457-3d8b-11e9-a1e8-4785d9606b75',
type: 'Color',
properties: {
colorA: '#002a4f',
colorB: '#0029FF',
life: null,
easing: 'easeOutCubic',
},
},
{
id: '51ca9458-3d8b-11e9-a1e8-4785d9606b75',
type: 'Scale',
properties: {
scaleA: 1,
scaleB: 0.5,
life: null,
easing: 'easeLinear',
},
},
{
id: '51ca9459-3d8b-11e9-a1e8-4785d9606b75',
type: 'Force',
properties: {
fx: 0,
fy: 5,
fz: 0,
life: null,
easing: 'easeLinear',
},
},
{
id: '51ca945a-3d8b-11e9-a1e8-4785d9606b75',
type: 'Rotate',
properties: {
x: 1,
y: 0,
z: 0,
life: null,
easing: 'easeLinear',
},
},
{
id: '51ca945b-3d8b-11e9-a1e8-4785d9606b75',
type: 'RandomDrift',
properties: {
driftX: 1,
driftY: 23,
driftZ: 4,
delay: 1,
life: null,
easing: 'easeLinear',
},
},
{
id: '51ca945c-3d8b-11e9-a1e8-4785d9606b75',
type: 'Spring',
properties: {
x: 1,
y: 5,
z: 0,
spring: 0.01,
friction: 1,
life: null,
easing: 'easeLinear',
},
},
],
emitterBehaviours: [],
},
],
},
};
32 changes: 32 additions & 0 deletions sandbox/experiments/start-stop/index.html
@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head>
<title>Emitter Start Stop</title>
<meta charset="UTF-8" />
<link rel="stylesheet" type="text/css" href="/style/reset.css" />
<link rel="stylesheet" type="text/css" href="/style/app.css" />
</head>

<body>
<div id="app">
<div id="ui">
<button id="start">start emitter</button>
<button id="stop">stop emitter</button>
</div>
<canvas id="canvas"></canvas>
</div>

<script src="https://unpkg.com/three@0.122.0/build/three.js"></script>
<script src="https://unpkg.com/three@0.122.0/examples/js/controls/OrbitControls.js"></script>
<script src="https://unpkg.com/stats-js@1.0.1/build/stats.min.js"></script>
<script src="/common/three-nebula.js"></script>
<script src="/common/Visualization.js"></script>
<script src="/common/safeLog.js"></script>
<script src="/common/run.js"></script>
<script src="/experiments/start-stop/data.js"></script>
<script src="/experiments/start-stop/index.js"></script>
<script>
run(init).then(() => console.log(`APP LOADED`));
</script>
</body>
</html>
25 changes: 25 additions & 0 deletions sandbox/experiments/start-stop/index.js
@@ -0,0 +1,25 @@
const { System, SpriteRenderer, GPURenderer } = window.Nebula;

const button = id => document.getElementById(id);
const { start, stop } = {
start: button('start'),
stop: button('stop'),
};

window.init = async ({ scene, camera, renderer }) => {
const { particleSystemState } = window.SYSTEM;
const spriteRenderer = new SpriteRenderer(scene, THREE);
const pointsRenderer = new GPURenderer(scene, THREE);
const systemRenderer = pointsRenderer;
const system = await System.fromJSONAsync(particleSystemState, THREE, { shouldAutoEmit: false });

start.addEventListener('click', () => {
system.emitters[0].emit();
});

stop.addEventListener('click', () => {
system.emitters[0].stopEmit();
});

return system.addRenderer(systemRenderer);
};
5 changes: 5 additions & 0 deletions sandbox/index.html
Expand Up @@ -15,6 +15,11 @@
Multiple Emitters
</a>
</li>
<li>
<a href="experiments/start-stop/index.html">
Start-Stop
</a>
</li>
<li>
<a href="experiments/gpu-renderer/index.html">
GPU Renderer
Expand Down
2 changes: 1 addition & 1 deletion src/core/System.js
Expand Up @@ -263,7 +263,7 @@ export default class System {
const emitter = this.emitters[i];

emitter.update(d);
emitter.isEmitting && this.dispatch(SYSTEM_UPDATE);
emitter.particles.length && this.dispatch(SYSTEM_UPDATE);
}
}

Expand Down
13 changes: 11 additions & 2 deletions src/emitter/Emitter.js
Expand Up @@ -10,6 +10,7 @@ import EventDispatcher, {
PARTICLE_CREATED,
PARTICLE_DEAD,
PARTICLE_UPDATE,
SYSTEM_UPDATE,
} from '../events';
import { INTEGRATION_TYPE_EULER, integrate } from '../math';
import { Util, uid } from '../utils';
Expand Down Expand Up @@ -558,7 +559,7 @@ export default class Emitter extends Particle {
* @return void
*/
update(time) {
if (!this.isEmitting) {
if (!this.isEmitting && this.particles.length === 0) {
return;
}

Expand All @@ -568,7 +569,11 @@ export default class Emitter extends Particle {
this.destroy();
}

this.generate(time);
if (this.isEmitting)
{
this.generate(time);
}

this.integrate(time);

let i = this.particles.length;
Expand All @@ -581,6 +586,10 @@ export default class Emitter extends Particle {
this.bindEmitterEvent && this.dispatch(PARTICLE_DEAD, particle);
this.parent.pool.expire(particle.reset());
this.particles.splice(i, 1);
if(this.particles.length === 0)
{
this.parent && this.parent.dispatch(SYSTEM_UPDATE);
}
}
}

Expand Down
30 changes: 26 additions & 4 deletions test/core/System.spec.js
Expand Up @@ -128,10 +128,9 @@ describe('core -> System', () => {
system.update();

assert(emitterSpy.calledOnce);
// system.addEmitter x1 + system.update x2
assert(dispatchSpy.calledThrice);
assert(dispatchSpy.secondCall.calledWith(SYSTEM_UPDATE));
assert(dispatchSpy.thirdCall.calledWith(SYSTEM_UPDATE_AFTER));
// system.addEmitter x1 + system.update x1
assert(dispatchSpy.calledTwice);
assert(dispatchSpy.secondCall.calledWith(SYSTEM_UPDATE_AFTER));

emitterSpy.restore();
dispatchSpy.restore();
Expand Down Expand Up @@ -161,6 +160,29 @@ describe('core -> System', () => {
done();
});

it('should ensure all particles live out their lives after stopEmit is called', done => {
const system = getSystem();
const emitter = new Nebula.Emitter();
const rate = new Nebula.Rate(500, 0.01);
const life = new Nebula.Life(0.2);
const renderer = getSpriteRenderer(new Scene());

system
.addRenderer(renderer)
.addEmitter(emitter.setRate(rate).addInitializer(life).emit())
.update()
.then(() => {
setTimeout(() => {
emitter.stopEmit();
system.update(.1);
assert.notEqual(system.getCount(), 0);
system.update(.1);
assert.equal(system.getCount(), 0);
done();
}, 1500);
});
});

it('should get the count of particles in the system', done => {
const system = getSystem();
const emitter = new Nebula.Emitter();
Expand Down

0 comments on commit e35afe3

Please sign in to comment.