Game Development Community

dev|Pro Game Development Curriculum

ParticleEmitterNode::setActive() - dynamically turn particle emitters on & off

by Orion Elenzil · 04/07/2009 (10:18 am) · 8 comments

This resource enables you to dynamically turn a particle emitter node on or off.
It is networked.

usage: %myParticleEmitterNode.setActive(TRUE | FALSE)

All the code needed to implement this are here,
but familiarity with C++ and TGE networking is assumed.
This is built on top of a TGE 1.3.5 codebase, but may work in TGE 1.5 and possibly TGEA, assuming the particle system is unchanged.


particleEmitter.h
add a protected boolean "mActive", perhaps just after mVelocity:
bool             mActive;

add a netmask.
since we're only ghosting one bit this is not strictly necessary, but it's good form.
just after the declaration of the constructor & destructor, add:
enum ParticleEmitterNodeMasks {
      StateMask         =     Parent::NextFreeMask << 0,
      HighestNetMask    =     Parent::NextFreeMask << 0,
      NextFreeMask      =     HighestNetMask       << 1
   };

add a setter and getter.
down at the bottom, in the public section, add:
void setActive(bool value);
   bool getActive(          );

particleEmitter.cc
in the constructor, initialize mActive to true:
mActive             = true;

in ParticleEmitterNode::advanceTime(), bracket emitParticles() in a test on mActive:
if (mActive)
   {
      mEmitter->emitParticles(emitPoint, emitPoint,
                              emitAxis,
                              emitVelocity, (U32)(dt * mDataBlock->timeMultiple * 1000.0f));
   }

in packUpdate(), test for our stateMask and if it's set, ghost down our custom state bidness.
right before return retMask;, insert:
if (stream->writeFlag(mask & StateMask))
   {
      stream->writeFlag(mActive);
   }

in unpackUpdate(), read the bits we wrote above.
right before the call to setScale(tempScale);, insert:
if (stream->readFlag()) // stateMask
   {
      mActive = stream->readFlag();
   }

and finally implement our setters and getters and expose them to script.
down at the bottom of the file, add:
void ParticleEmitterNode::setActive(bool value)
{
   mActive = value;
   setMaskBits(StateMask);
}

bool ParticleEmitterNode::getActive()
{
   return mActive;
}

ConsoleMethod(ParticleEmitterNode, setActive, void, 3, 3, "(bool)")
{
   object->setActive(dAtob(argv[2]));
}

ConsoleMethod(ParticleEmitterNode, getActive, bool, 2, 2, "")
{
   return object->getActive();
}

shazam!

note, not extensively tested yet, but it will be and if problems arise i'll post here.


#1
04/07/2009 (10:58 am)
Good stuff.
#2
04/07/2009 (11:54 am)
That's problem-solving. Thanks!
#3
04/07/2009 (11:57 am)
Oooo... good one!

Much better than add -> delete -> add -> delete silliness, and using triggers was so gimmicky.
#4
04/07/2009 (12:02 pm)
yeah, kinda surprising nobody did this earlier, that add -> delete stuff is so nuts.
#5
04/07/2009 (12:55 pm)
Very nice, I think I'll give this a try.
#6
04/07/2009 (2:04 pm)
I guess it's not only nicer, but also a lot faster than add / delete. Thanks.
#7
04/08/2009 (5:03 am)
Another great one Orion, thanks.
#8
04/10/2009 (1:13 pm)
This resource would be INCREDIBLY helpful in my project. Might someone be willing to be give me some hints on how to implement in TGEA 1.7.1? I'm no C++ coder, and not sure where I can/should/ought to place things as they relate to the resource.