void CParticleEventSequence::Update(float fElapsedTime, float fDeltaTime, D3DXVECTOR3 m_vPtPos)
{
	if (!m_pParticles) return;

	// update existing particles
	{
		for (int q=0; q < m_pParticles->GetTotalElements(); q++) {
			if (m_pParticles->IsAlive(q)) {
				CParticle &pt = m_pParticles->GetAt(q);

				if (!pt.Update(fDeltaTime)) {
					m_pParticles->Delete(&pt);
				}
				else {
					pt.m_vDir += fDeltaTime * m_vGravity.GetRandomNumInRange();
					// run all the particle's events
					RunEvents(pt);
				}
			} // is alive
		} // next particle
	}

	float fEmitRateThisFrame = m_EmitRate.GetRandomNumInRange();
	int iNumNewPts = fEmitRateThisFrame * fDeltaTime;
	m_fNumNewPtsExces += (float)(fEmitRateThisFrame * fDeltaTime) - iNumNewPts;

	if (m_fNumNewPtsExces > 1.0f) {
		iNumNewPts += (int)m_fNumNewPtsExces;
		m_fNumNewPtsExces -= (int)m_fNumNewPtsExces;
	}

	if (m_Loops > 0 && m_iTotalParticleLives * iNumNewPts > m_Loops * m_iNumParticles) {
		iNumNewPts = (m_Loops * m_iNumParticles) - m_iTotalParticleLives;
		if (iNumNewPts <= 0) {
			iNumNewPts = 0;
		}
	}

	for (int q=0; q < iNumNewPts && m_pParticles->GetNumFreeElements(); q++) {
		try {
			CreateNewParticle(m_vPtPos);
		} catch(...) { q = iNumNewPts; } 
	}
}
Exemple #2
0
//------------------------------------------------------------------------------
//
bool gosFX::ParticleCloud::Execute(ExecuteInfo *info)
{
	Check_Object(this);
	Check_Object(info);
	Verify(IsExecuted());

	//
	//--------------------------------------------------------------------
	// If we were given a new matrix, see if we have a parent.  If so,
	// concatenate the two and figure out its inverse.  If no parent, then
	// just invert the new matrix, otherwise just use the existing one
	//--------------------------------------------------------------------
	//
	Stuff::LinearMatrix4D new_world_to_local;
	Stuff::LinearMatrix4D *matrix = NULL;
	int sim_mode = GetSimulationMode();
	if (sim_mode == DynamicWorldSpaceSimulationMode)
	{
		Stuff::LinearMatrix4D local_to_world;
		local_to_world.Multiply(m_localToParent, *info->m_parentToWorld);
		new_world_to_local.Invert(local_to_world);
		matrix = &new_world_to_local;
	}

	//
	//--------------------------------------------------------
	// Figure out the birth rate and request the new particles
	//--------------------------------------------------------
	//
	Specification *spec = GetSpecification();
	Check_Object(spec);
	Stuff::Scalar dT =
		static_cast<Stuff::Scalar>(info->m_time - m_lastRan);
	Verify(dT >= 0.0f);
	Stuff::Scalar prev_age = m_age;
	m_age += dT * m_ageRate;
	if (m_age >= 1.0f)
		m_birthAccumulator = 0.0f;
	else
	{
		Stuff::Scalar new_life =
			spec->m_particlesPerSecond.ComputeValue(m_age, m_seed);
		Min_Clamp(new_life, 0.0f);
		m_birthAccumulator += dT * new_life;
	}

	//
	//-----------------------------------
	// Deal with all the active particles
	//-----------------------------------
	//
	int i;
	int last_real = -1;
	for (i = 0; i < m_activeParticleCount; i++)
	{
		//
		//--------------------------------------------------------------------
		// If the particle is active, age it and if it is not yet time to die,
		// go to the next particle, otherwise kill it
		//--------------------------------------------------------------------
		//
		Particle *particle = GetParticle(i);
		Check_Object(particle);
		if (particle->m_age < 1.0f)
		{
			particle->m_age += dT*particle->m_ageRate;
			if (AnimateParticle(i, matrix, info->m_time))
			{
				last_real = i;
				continue;
			}
			DestroyParticle(i);
		}

		//
		//--------------------------------------------------------------------
		// If there are new particles to be born, go ahead and create them now
		//--------------------------------------------------------------------
		//
		if (m_birthAccumulator >= 1.0f)
		{
			Stuff::Point3D translation;
			CreateNewParticle(i, &translation);
			if (AnimateParticle(i, matrix, info->m_time))
				last_real = i;
			else
				DestroyParticle(i);
			m_birthAccumulator -= 1.0f;
		}
	}
	m_activeParticleCount = last_real + 1;

	//
	//----------------------------------------------------------------------
	// If there are still new particles to be born, then we must try to grow
	// the active particle count
	//----------------------------------------------------------------------
	//
	while (
		m_birthAccumulator >= 1.0f
		 && m_activeParticleCount < spec->m_maxParticleCount
	)
	{
		i = m_activeParticleCount++;
		Stuff::Point3D translation;
		CreateNewParticle(i, &translation);
		if (!AnimateParticle(i, matrix, info->m_time))
		{
			DestroyParticle(i);
			--m_activeParticleCount;
		}
		m_birthAccumulator -= 1.0f;
	}

	//
	//---------------------------------------------------------
	// Only allow fractional births to carry over to next frame
	//---------------------------------------------------------
	//
	m_birthAccumulator -= static_cast<Stuff::Scalar>(floor(m_birthAccumulator));

	//
	//----------------------------
	// Now let effect do its thing
	//----------------------------
	//
	m_age = prev_age;
	return Effect::Execute(info);
}