Jump to content

JumpStart First Particle Override ejectionPeriodMS


Steve_Yorkshire

Recommended Posts

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

Link to comment
Share on other sites

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...