Jump to content

Recommended Posts

Posted

Updated: Now (looping) emitters can be turned on/off via script with %emitter.setActive(%bool); and they'll immediately restart. 8-)


I use some animated particles which generally have a high ejectionPeriodMS eg: 1000 = 1 particle per second. I didn't like waiting till the end of the time for the emitter to start up so I modded the code to "JumpStart" the process. It's especially useful when you've got an animated sprite sheet with a long ejectionPeriodMS that loops.


New code:

QuickStart var for emitterData so you can pick and choose the emitters for this to work on.

mJumpStart bool to determine whether the emitter has already launched it's quickStarted.


particleEmitter.h

//...
class ParticleEmitterData : public GameBaseData
{
//...
  public:
  //...
   bool glow;                                ///< Renders this emitter into the glow buffer.
 
   bool reload();
 
   bool QuickStart;//yorks new ~line 120
};
 
//... 
   bool mDead;
 
   bool mJumpStart;//yorks new ~line 193
 
  protected:
//...

 

particleEmitter.cpp

//...
 
void ParticleEmitterData::initPersistFields()
{
//...
 
ParticleEmitterData::ParticleEmitterData()
{
   VECTOR_SET_ASSOCIATION(particleDataBlocks);
//...
   alignDirection = Point3F(0.0f, 1.0f, 0.0f);
 
   QuickStart = false;//yorks ~line 157
}
 
// Enum tables used for fields blendStyle, srcBlendFactor, dstBlendFactor.
 
//...
   addGroup( "ParticleEmitterData" );
//...
      addField("glow", TYPEID< bool >(), Offset(glow, ParticleEmitterData),
         "If true, the particles are rendered to the glow buffer as well.");
 
	  //yorks new ~line 298
	  addField("quickStart", TYPEID< bool >(), Offset(QuickStart, ParticleEmitterData),
		  "If true, the first particle spawns immediately. " 
		  "This overrides ejectionPeriodMS for the first particle only.");
 
      //@}
 
   endGroup( "ParticleEmitterData" );
 
   Parent::initPersistFields();
}
 
//... 
 
ParticleEmitter::ParticleEmitter()
{
   //...
   mDead = false;
   mDataBlock = NULL;
 
   mJumpStart = true;//yorks new ~line 755
 
   // ParticleEmitter should be allocated on the client only.
   mNetFlags.set( IsGhost );
}
 
//...
 
void ParticleEmitter::emitParticles(const Point3F& start,
                                    const Point3F& end,
                                    const Point3F& axis,
                                    const Point3F& velocity,
                                    const U32      numMilliseconds)
{
//...
 
   U32 currTime = 0;
   bool particlesAdded = false;
 
   bool mQuick = mDataBlock->QuickStart;//yorks ~line 1050
 
   if (mQuick == true)
   {
	   if (mJumpStart == true)//yorks new start
	   {
			//Con::printf("jumpstart");
			mJumpStart = false;//let's not repeat when we don't need to jumpStart
			mNextParticleTime = numMilliseconds;
	   }//yorks new end
   }
 
   Point3F axisx;
   if( mFabs(axis.z) < 0.9f )
//...
}

 

Next up we need to head over and make sure that mJumpStart resets when the emitter starts to replay.


particleEmitterNode.cpp

//...
void ParticleEmitterNode::advanceTime(F32 dt)
{
   Parent::advanceTime(dt);
 
   //yorks start ~line 289
   /*
   if (!mActive || mEmitter.isNull() || !mDataBlock)//yorks this out and changed below
      return;
	 */
   if (mEmitter.isNull() || !mDataBlock)
	   return;
 
   if (!mActive)
   {
	   bool mEarly = mEmitterDatablock->QuickStart;
 
	   if (mEarly == true)
	   {
		   bool mJump = mEmitter->mJumpStart;
		   if (mJump == false)
			   mEmitter->mJumpStart = true;
	   }
	   return;
   }//yorks end ~line 308
 
   Point3F emitPoint, emitVelocity;
   Point3F emitAxis(0, 0, 1);
   getTransform().mulV(emitAxis);
   getTransform().getColumn(3, &emitPoint);
   emitVelocity = emitAxis * mVelocity;
 
   mEmitter->emitParticles(emitPoint, emitPoint,
                           emitAxis,
						   emitVelocity, (U32)(dt * mDataBlock->timeMultiple * 1000.0f));
}
//...

 

Now to get it to go you just have to add "QuickStart = true" into your scripted ParticleEmitterData datablock.

datablock ParticleEmitterData(circlesInLoopEmitter)
{
   ejectionPeriodMS = "800";
   periodVarianceMS = "0";
 
   ejectionVelocity = "0";
   velocityVariance = "0";
   ejectionOffset   = "1";
 
   thetaMin         = "0";
   thetaMax         = "0";
 
   particles        = "circlesInLoopParticle";
   ejectionOffsetVariance = "0";
   blendStyle = "ADDITIVE";
   glow = "0";
   lifetimeMS = "0";
   alignParticles = "1";
   alignDirection = "0 0 1";
   phiVariance = "0";
 
   QuickStart = true;//yorks
};

 

And voila, maybe not the prettiest code 'cos mine never is, but it does seem to work nicely. ;)

As ever, If anyone has a better way, feel free to pipe up. :D

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...