Game Development Community

dev|Pro Game Development Curriculum

Debris Emitter Nodes

by James Laker (BurNinG) · 05/22/2008 (7:13 am) · 3 comments

Download Code File

While working on Explosions for Solar Battles, I found that the Emitters in the Debris Datablock emit their Particles from the centre of the debris shape. As a default it is probably sufficient, but I wanted it to be a little more realistic.

What I had in mind was to use the Sub explosions and have each one (up to 5) have a different piece of the ship - and I want it burning. The Debris would not look that good if it is spinning and emitting the Fire from the middle of the DTS shape. So I decided to add nodes. This allows me to add 2 nodes (default) into the model and have it burn at only certain parts. This gives it a much more realistic effect when debris comes flying past your ship.

This is backward compatible, so if you dont have those nodes, it will use the Particle Emitter as per default from the centre.

Lets get to the coding which is reallly simple and easy.

In Debris.h we need to add the array of the Nodes we are going to use. So find the following:
F32               mXRotSpeed;
   F32               mZRotSpeed;
   Point3F           mRotAngles;
   F32               mRadius;
   bool              mStatic;
   F32               mElasticity;
   F32               mFriction;

And add the following below it:
//JLAKER - Debris Particle Nodes
	S32					mEmitterNode[ DebrisData::DDC_NUM_EMITTERS ];
	//JLAKER - Debris Particle Nodes

On to Debris.cpp. Find the following code in the Constructor (Debris::Debris())
mPart = NULL;
   mXRotSpeed = 0.0f;
   mZRotSpeed = 0.0f;
   mInitialTrans.identity();
   mRadius = 0.2f;
   mStatic = false;

And add the following to just make sure we have default values:
//JLAKER - Debris Particle Nodes
	for (int j=0; j<DebrisData::DDC_NUM_EMITTERS; j++)
	{
		mEmitterNode[j] = -1;
	}
	//JLAKER - Debris Particle Nodes

Going down further in the file find the following bit in the onAdd() method:
// create emitters
   for( int j=0; j<DebrisData::DDC_NUM_EMITTERS; j++ )
   {
      if( mDataBlock->emitterList[j] != NULL )
      {
         ParticleEmitter * pEmitter = new ParticleEmitter;
         pEmitter->onNewDataBlock( mDataBlock->emitterList[j] );
         if( !pEmitter->registerObject() )
         {
            Con::warnf( ConsoleLogEntry::General, "Could not register emitter for particle of class: %s", mDataBlock->getName() );
            delete pEmitter;
            pEmitter = NULL;
         }
         mEmitterList[j] = pEmitter;

And add this section in there (under the above).
This is to find the Node (called enodeN) in the Debris Shape:
//JLAKER - Debris Particle Nodes
			char buff[10];
			dSprintf(buff,sizeof(buff),"enode%d",j);
			mEmitterNode[j] = mDataBlock->shape->findNode(buff);
			//JLAKER - Debris Particle Nodes

Go waaaay down the file (around line 800) in the Debris::UpdateEmitters method and change things to look like this:
for( int j=0; j<DebrisData::DDC_NUM_EMITTERS; i++ )
   {
      if( mEmitterList[j] )
      {

			//JLAKER - Node Emitter
			if (!mEmitterNode[j])
			{
				//Get the position relative to the shape
				mShape->mNodeTransforms[mEmitterNode[j]].getColumn(3, &pos);

				//Get the position in the World
				MatrixF trans = getTransform();

				//Multiply the 2
				trans.mulP( pos );
			}
			//JLAKER - Node Emitter

         mEmitterList[j]->emitParticles( lastPos, pos, axis, vel, ms );
      }
   }

Recompile your project. Now before you rush off, you might have noticed that the nodes are called enodeN, which is short for emitternode. So you add enode0 and enode1 somewhere to your 3d Model and export.

Have fun!
EDIT: Changed all i variables to j so the post doesnt get confused with italic.

#1
05/22/2008 (8:19 am)
This is very cool.
#2
06/22/2008 (7:23 am)
if this a bug?
for (int i=0; i {
mEmitterNode = -1;
}

should this be:
for (int i=0; i {
mEmitterNode[i] = -1;
}
#3
06/23/2008 (3:36 am)
Yep... that was a minor bug, that wouldn't have any implecations anyway. Thanx for spotting it ;)

Edit:
Hehe... It's there alright... the problem is that [ i ] is seen as italic when posting. So I guess I should change it to [j]