void CParticleManager::Update( float deltaTime ) { for (uint32_t i = 0; i < m_particle.size(); ++i) { CParticle* pParticle = m_particle[i]; if (pParticle != NULL) { if (pParticle->IsAlive()) { pParticle->Update(deltaTime); if (pParticle->GetType() == ePT_Visual) { Function<void(void)> func = Bind(*pParticle, &CParticle::PreRender); CRenderManager::GetInstance()->SendQuadToCache(pParticle->GetPhysics()->GetWorldPos(), pParticle->GetRadius(), pParticle->GetRadius(), pParticle->GetColor(), &func); } } else { UnRegister(pParticle); } } } }
//----------------------------------------------------------------------------- void CParticleSystem::Update(long _lTime) { if (ARXPausedTimer) return; ulTime += _lTime; int nbtotal = 0; int iNb; float fTimeSec = _lTime * DIV1000; CParticle * pP; list<CParticle *>::iterator i; iParticleNbAlive = 0; i = listParticle.begin(); while (i != listParticle.end()) { pP = *i; ++i; nbtotal++; if (pP->isAlive()) { pP->Update(_lTime); pP->p3Velocity.x += p3ParticleGravity.x * fTimeSec; pP->p3Velocity.y += p3ParticleGravity.y * fTimeSec; pP->p3Velocity.z += p3ParticleGravity.z * fTimeSec; iParticleNbAlive ++; } else { if (iParticleNbAlive >= iParticleNbMax) { delete pP; listParticle.remove(pP); } else { pP->Regen(); SetParticleParams(pP); pP->Validate(); pP->Update(0); ulNbParticleGen++; iParticleNbAlive++; } } } // cr�ation de particules en fct de la fr�quence if (iParticleNbAlive < iParticleNbMax) { long t = iParticleNbMax - iParticleNbAlive; if (fParticleFreq != -1) { ARX_CHECK_LONG(fTimeSec * fParticleFreq); t = min(ARX_CLEAN_WARN_CAST_LONG(fTimeSec * fParticleFreq), t); if (t < 1) t = 1; } for (iNb = 0; iNb < t; iNb++) { CParticle * pP = new CParticle(); SetParticleParams(pP); pP->Validate(); pP->Update(0); listParticle.insert(listParticle.end(), pP); ulNbParticleGen ++; iParticleNbAlive++; } } }
// updates all systems void CParticleSystemManager::UpdateSystems( void ) { CParticleSystem *pSystem = NULL; signed int i = 0; signed int iSystems = (signed)m_pParticleSystems.size(); // iterate through all the particle systems, drawing each for (; i < iSystems; i++) { pSystem = m_pParticleSystems[i]; // remove the system if the system requests it if( pSystem && pSystem->DrawSystem() == false) { delete pSystem; m_pParticleSystems.erase((m_pParticleSystems.begin() + i)); i--; iSystems--; } } // we couldn't return earlier as we need to have the sorting before the ps updating // however no sorting when we can't see the particles if(CheckDrawSystem() == false) return; int iParticles = m_pParticles.size(); if(iParticles > 1) { // calculate the fraction of a second between sorts float flTimeSinceLastSort = (gEngfuncs.GetClientTime() - m_flLastSort); // 1 / time between sorts will give us a number like 5 // if it is less than the particlesorts cvar then it is a small value // and therefore a long time since last sort if((((int)(1 / flTimeSinceLastSort)) < g_ParticleSorts->value)) { m_flLastSort = gEngfuncs.GetClientTime(); std::sort(m_pParticles.begin(), m_pParticles.end(), less_than); } } if(iParticles > 0) { // prepare opengl Particle_InitOpenGL(); float flTimeSinceLastDraw = TimeSinceLastDraw(); // loop through all particles drawing them // they have already been tested and updated in their pss' draw sys func // we've reversed the greater than order, so that oldest particles are at 0 // further away particles and recently added particles get drawn first CParticle *pParticle = NULL; for(i = 0; i < iParticles ; i++) { if(m_pParticles[i]) { pParticle = m_pParticles[i]; if(pParticle && pParticle->Test()) { pParticle->Update(flTimeSinceLastDraw); if(g_iUser1 != OBS_MAP_FREE && g_iUser1 != OBS_MAP_CHASE) { // unfortunately we have to prepare every particle now // as we can't prepare for a batch of the same type anymore pParticle->Prepare(); pParticle->Draw(); } } else { RemoveParticle(pParticle); i--; iParticles--; } } } Particle_FinishOpenGL(); } // print out how fast we've been drawing the systems in debug mode if (g_ParticleDebug->value != 0 && ((m_flLastSort + 0.5) <= gEngfuncs.GetClientTime())) { gEngfuncs.Con_Printf("%i Particles Drawn this pass in %i systems ", m_pParticles.size(), m_pParticleSystems.size()); gEngfuncs.Con_Printf("%i Textures in Cache\n\0", m_pTextures.size()); } m_flLastDraw = gEngfuncs.GetClientTime(); }