Emitter does not like being paused

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
Auria
Competition winner
Posts: 120
Joined: Wed Feb 18, 2009 1:11 am
Contact:

Emitter does not like being paused

Post by Auria »

In SuperTuxKart, we have an emitter attached to each kart to produce nitro. When the user is not using nitro, we 'pause' the emitter by calling

Code: Select all

    m_emitter->setMinParticlesPerSecond(0);
    m_emitter->setMaxParticlesPerSecond(0);
and later when we need it again, we make similar calls, but wit non-zero values.

However, there is a bug when doing this : if the particle emitter was paused during 10 seconds, when you resume it, it suddenly fires 10 seconds' worth of particles all at once, producing a dense cloud of particles. (This is because the current implementation tracks the elapsed time between two calls to "emitt", but "emitt" does not seem to be called when the emitter is paused.

Find below a patch that corrects this issue :

Code: Select all

Index: Irrlicht/CParticleBoxEmitter.h
===================================================================
--- Irrlicht/CParticleBoxEmitter.h	(revision 3516)
+++ Irrlicht/CParticleBoxEmitter.h	(working copy)
@@ -42,11 +42,26 @@
 	virtual void setDirection( const core::vector3df& newDirection ) { Direction = newDirection; }
 
 	//! Set minimum number of particles emitted per second.
-	virtual void setMinParticlesPerSecond( u32 minPPS ) { MinParticlesPerSecond = minPPS; }
+	virtual void setMinParticlesPerSecond( u32 minPPS )
+    {
+        MinParticlesPerSecond = minPPS;
+        
+        // if 0, "emitt" will no longer be called, so stop counting time since last call
+        if (minPPS == 0)
+            Time = 0;
+    }
 
 	//! Set maximum number of particles emitted per second.
-	virtual void setMaxParticlesPerSecond( u32 maxPPS ) { MaxParticlesPerSecond = maxPPS; }
+	virtual void setMaxParticlesPerSecond( u32 maxPPS )
+    {
+        MaxParticlesPerSecond = maxPPS;
+        
+        // if 0, "emitt" will no longer be called, so stop counting time since last call
+        if (maxPPS == 0)
+            Time = 0;
 
+    }
+
 	//! Set minimum start color.
 	virtual void setMinStartColor( const video::SColor& color ) { MinStartColor = color; }
 
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Shouldn't the emitter still run when only setMinParticlesPerSecond is set to 0?
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Why not use the clearAllParticles() method which kind of restarts the particle system? It's a new method introduced a few weeks ago, IIRC exactly to cope with this situation.
Auria
Competition winner
Posts: 120
Joined: Wed Feb 18, 2009 1:11 am
Contact:

Post by Auria »

hybrid wrote:Why not use the clearAllParticles() method which kind of restarts the particle system? It's a new method introduced a few weeks ago, IIRC exactly to cope with this situation.
Interesting, didn't know about it.
Sadly we're still on 1.7.2 so I cannot modify the code to use this solution until a new release with this method is out
sudi
Posts: 1686
Joined: Fri Aug 26, 2005 8:38 pm

Post by sudi »

@Auria
i actually pause my particle system by calling setEmitter(0) and then when activating it setting it back to my emitter. works pretty good.
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
Post Reply