Example #1
0
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();
}