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; } } }
//------------------------------------------------------------------------------ // 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); }