ParticleEmitter particlesPerSecond set to 0 accumulates timeDiff

Problem reported here: http://hub.jmonkeyengine.org/groups/effects/forum/topic/changing-particlessec-ingame/

I think this patch solves the problem but would really like someone else to look also.

Attached a slightly modified test case based on the one @nagper wrote.



[patch]

Index: ParticleEmitter.java

— ParticleEmitter.java Base (BASE)

+++ ParticleEmitter.java Locally Modified (Based On LOCAL)

@@ -1000,6 +1000,7 @@

}



// Spawns particles within the tpf timeslot with proper age

  •    if (particlesPerSec &gt; 0f) {<br />
    

float interval = 1f / particlesPerSec;

tpf += timeDifference;

while (tpf > interval){

@@ -1015,6 +1016,7 @@

}

}

timeDifference = tpf;

  •    }<br />
    

BoundingBox bbox = (BoundingBox) this.getMesh().getBound();
bbox.setMinMax(min, max);[/patch]





[java]
package jme3test.effect;

import com.jme3.app.SimpleApplication;
import com.jme3.app.StatsAppState;
import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh.Type;
import com.jme3.material.Material;

/**
* Test for the case where particles per second is set to X, then to 0 and then back to X.
*
* The problem was reported
* <a href="http://hub.jmonkeyengine.org/groups/effects/forum/topic/changing-particlessec-ingame">here</a>.
*
* It seemed that when going back to X from 0 the particles that had not yet died were reused and
* had their lifespan extended a bit before dying.
*/
public class TestChangingParticlePerSecond extends SimpleApplication {

private ParticleEmitter emit;
private boolean on = true;
private float time = 0;

public static void main(String[] args) {
TestChangingParticlePerSecond app = new TestChangingParticlePerSecond();
app.start();
}

public TestChangingParticlePerSecond() {
super(new StatsAppState());
}

@Override
public void simpleInitApp() {
emit = new ParticleEmitter("Emitter", Type.Triangle, 3000);
emit.setGravity(0, 1, 0);
emit.setParticlesPerSec(2);
emit.setLowLife(2);
emit.setHighLife(4);
emit.getParticleInfluencer().setVelocityVariation(0.5f);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
emit.setMaterial(mat);
rootNode.attachChild(emit);
}

@Override
public void simpleUpdate(float tpf) {
time += tpf;
//increase the number of emitted particles once / 5 seconds
if (time > 2) {
on = !on;
if (on) {
emit.setParticlesPerSec(0);
} else {
emit.setParticlesPerSec(2);
}

time = 0;
}

fpsText.setText("getNumVisibleParticles: " + emit.getNumVisibleParticles());
}
}
[/java]
1 Like

Lol, @Momoko_Fan’s infamous continuous flow code xD Yeah… He’ll have to decide :wink:

1 Like

That was quick jmaasing :).



Although I not sure that it would fix the issue. The problem can be easily reproduced, and exist when I simply increase the particlesPerSec for example from 6 to 10. It is just much more obvious and visible if you switch from 0 to 10 for example.

If you simply check whether particlesPerSec is 0 or not it won’t affect anything but this special case.



The problem must reside a bit deeper in the code… maybe.

But thanks for the efforts… I am sure you would find it sooner or later.

@nagper said:
That was quick jmaasing :).

Although I not sure that it would fix the issue. The problem can be easily reproduced, and exist when I simply increase the particlesPerSec for example from 6 to 10. It is just much more obvious and visible if you switch from 0 to 10 for example.
If you simply check whether particlesPerSec is 0 or not it won't affect anything but this special case.


Yeah, if that is the case then yes, this patch will not fix it, oh well, it was worth a shot :)

At least for me it was always much more diffucult to dive into and understand someone else’s code. Momoko_Fan will know how to fix it and if he wants he will do it :slight_smile:

To be honest, I don’t see it unless I go to 0 and back, but now I have so many test cases I feel confused :slight_smile:



The reason 0 was special was that even if no particles should be generated it accumulated the tpf

tpf += timeDifference

when the particlesPerSecond was again set back to non-zero there was a pretty large tpf to “catch up” - at least I think that is what happens.

@nagper said:
At least for me it was always much more diffucult to dive into and understand someone else's code


better get used to it ;)
@jmaasing said:
To be honest, I don't see it unless I go to 0 and back, but now I have so many test cases I feel confused :)

The reason 0 was special was that even if no particles should be generated it accumulated the tpf
tpf += timeDifference
when the particlesPerSecond was again set back to non-zero there was a pretty large tpf to "catch up" - at least I think that is what happens.



You don't really need to write test cases... open the scene explorer, add an emitter and you can play with the settings and see the result real time. This issue can be easily reproduced with this method. I just guess that it is the same like if you would do it from yout test case.

Just a guess, since timeDifference depends on particlesPerSec, I would assume resetting it to 0 would help.

Resetting timeDifference to zero did help, whadd’ya know. Anyway, the fix was committed, thanks for all the help guys.

1 Like