$ParticleEmitter::deleteParticlesOnRemove
by Orion Elenzil · 03/23/2009 (7:16 pm) · 4 comments
introduces a new global script variable, $ParticleEmitter::deleteParticlesOnRemove, which when true means that when a ParticleEmitterNode is removed from the scene, any outstanding particles it may have whelped will be deleted on the spot. see this thread for my motivation.
this is a fairly no-frills resource, assumes familiarity w/ C++ and the TG* engine.
this was written on top of a TGE 1.3.5 codebase with AFX integrated in, but i don't think it depends on AFX.
i'm totally unfamiliar with TGEA (& T3D), but if they have a the same particle system as TGE, this should work for them as well.
one could argue that a setting like this is more appropriate as a member of the ParticleEmitterNode or the ParticleEmitterData,
but for my purposes the global variable was quicker & simpler. It would be easy to repurpose that way if anyone feels like it.
not yet extensively tested, but seems fairly correct.
particleEmitter.h
right after this line: F32 mVelocity; add this:
right before this line: ParticleEmitterNode::ParticleEmitterNode() insert this:
in ParticleEmitterNode::initPersistFields(), add this:
in ParticleEmitterNode::onRemove(), right after if (isClientObject()) {, add this:
particleEngine.h
in a public section of the ParticleEmitter declaration, for example just after the three emitParticles variations, add:
particleEngine.cc
after the routine ParticleEmitter::advanceTime(), add this method:
.. it's THAT easy !
this is a fairly no-frills resource, assumes familiarity w/ C++ and the TG* engine.
this was written on top of a TGE 1.3.5 codebase with AFX integrated in, but i don't think it depends on AFX.
i'm totally unfamiliar with TGEA (& T3D), but if they have a the same particle system as TGE, this should work for them as well.
one could argue that a setting like this is more appropriate as a member of the ParticleEmitterNode or the ParticleEmitterData,
but for my purposes the global variable was quicker & simpler. It would be easy to repurpose that way if anyone feels like it.
not yet extensively tested, but seems fairly correct.
particleEmitter.h
right after this line: F32 mVelocity; add this:
static bool smDeleteParticlesOnRemove; // when i am removed, delete the outstanding particles i have emitted.
right before this line: ParticleEmitterNode::ParticleEmitterNode() insert this:
bool ParticleEmitterNode::smDeleteParticlesOnRemove = false;
in ParticleEmitterNode::initPersistFields(), add this:
Con::addVariable("ParticleEmitter::deleteParticlesOnRemove", TypeBool, &(ParticleEmitterNode::smDeleteParticlesOnRemove));in ParticleEmitterNode::onRemove(), right after if (isClientObject()) {, add this:
if (smDeleteParticlesOnRemove)
{
mEmitter->deleteParticles();
}particleEngine.h
in a public section of the ParticleEmitter declaration, for example just after the three emitParticles variations, add:
void deleteParticles();
particleEngine.cc
after the routine ParticleEmitter::advanceTime(), add this method:
void ParticleEmitter::deleteParticles()
{
Particle** ppProbe = &mParticleListHead;
while (*ppProbe != NULL)
{
// Remove this particle
Particle* remove = *ppProbe;
*ppProbe = remove->nextInList;
remove->nextInList = NULL;
sgParticleEngine->releaseParticle(remove);
}
}.. it's THAT easy !
About the author
#2
thanks for looking at this.
ah, i see, so conditionally have the EmitterNode directly remove the Emitter, and then let ParticleEmitter::onRemove() release all the particles ?
yes, that would be less intrusive, thanks.
is there somewhere to read an overview of the particle system architecture ? eg, i don't know the relationship between ParticleEmitter and ParticleEmitterNode.
03/26/2009 (10:41 am)
hey Wes,thanks for looking at this.
ah, i see, so conditionally have the EmitterNode directly remove the Emitter, and then let ParticleEmitter::onRemove() release all the particles ?
yes, that would be less intrusive, thanks.
is there somewhere to read an overview of the particle system architecture ? eg, i don't know the relationship between ParticleEmitter and ParticleEmitterNode.
#3
The particles are an odd object but for a good reason. The "ParticleEmitter" is the object that actually handle all the particles but it's not built to be created directly. It's used for example in the player.cc for the footpuff. Every step the player object creates a new ParticleEmitter and sets it to deleteWhenEmpty. Then the player object can just ignore it and let it die on its own. The same goes for many other Torque objects, basically anything that emits particles as one single shot of a number of particles.
In the case of an object that emits particles as a loop then the ParticleEmitter can be told to emit particles over time. That is what the ParticleEmitterNode does and encapsulates it in a nice scene object.
In our world a user can place objects that emit particles. To handle this instead of creating a particleEmitterNode with every object. The object itself creates a ParticleEmitter and manages it. I just copied code from the ParticleEmitterNode class to do it. This also allows us to toggle the particles on and off as a variable for the object. Much like what you're doing.
03/26/2009 (1:43 pm)
I really didn't find any good documentation about it. Mostly took a lot of trial and error to figure it all out. The particles are an odd object but for a good reason. The "ParticleEmitter" is the object that actually handle all the particles but it's not built to be created directly. It's used for example in the player.cc for the footpuff. Every step the player object creates a new ParticleEmitter and sets it to deleteWhenEmpty. Then the player object can just ignore it and let it die on its own. The same goes for many other Torque objects, basically anything that emits particles as one single shot of a number of particles.
In the case of an object that emits particles as a loop then the ParticleEmitter can be told to emit particles over time. That is what the ParticleEmitterNode does and encapsulates it in a nice scene object.
In our world a user can place objects that emit particles. To handle this instead of creating a particleEmitterNode with every object. The object itself creates a ParticleEmitter and manages it. I just copied code from the ParticleEmitterNode class to do it. This also allows us to toggle the particles on and off as a variable for the object. Much like what you're doing.
#4
03/26/2009 (1:56 pm)
i see. that clears things up a bit, thanks. 
Torque Owner Wes Macdonald
The onRemove for the particle emitter already has the code you used for deleteParticles. It's the deleteWhenEmpty that is causing your problem.