Counter Strike : Global Offensive Source Code
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Client side CTFTeam class
//
// $NoKeywords: $
//=============================================================================//
#ifndef PARTICLE_ITERATORS_H
#define PARTICLE_ITERATORS_H
#ifdef _WIN32
#pragma once
#endif
#include "materialsystem/imesh.h"
#include "particledraw.h"
#define NUM_PARTICLES_PER_BATCH 200
#define MAX_TOTAL_PARTICLES 2048 // Max particles in the world
//
// Iterate the particles like this:
//
// Particle *pCur = pIterator->GetFirst();
// while ( pCur )
// {
// ... render the particle here and figure out the sort key and position
// pCur = pIterator->GetNext( sortKey, pCur->m_Pos );
// }
//
class CParticleRenderIterator { friend class CParticleMgr; friend class CParticleEffectBinding; public: CParticleRenderIterator();
// The sort key is used to sort the particles incrementally as they're rendered.
// They only get sorted in the main rendered view (ie: not in reflections or monitors).
// These return const because you should only modify particles during their simulation.
const Particle* GetFirst(); const Particle* GetNext( float sortKey );
// Use this to render. This can return NULL, in which case you shouldn't render.
// This being NULL is a carryover from when particles rendered and simulated together and
// it should GO AWAY SOON!
ParticleDraw* GetParticleDraw() const;
private:
void TestFlushBatch();
private: // Set by CParticleMgr.
CParticleEffectBinding *m_pEffectBinding; CEffectMaterial *m_pMaterial; ParticleDraw *m_pParticleDraw; CMeshBuilder *m_pMeshBuilder; IMesh *m_pMesh; bool m_bBucketSort; IMaterialSystem *m_pMaterialSystem; // Needed when we have to break particles into multiple batches
// Output after rendering.
float m_MinZ; float m_MaxZ; float m_zCoords[MAX_TOTAL_PARTICLES]; int m_nZCoords; Particle *m_pCur; bool m_bGotFirst; float m_flPrevZ; int m_nParticlesInCurrentBatch; };
//
// Iterate the particles like this:
//
// Particle *pCur = pIterator->GetFirst();
// while ( pCur )
// {
// ... simulate here.. call pIterator->RemoveParticle if you want the particle to go away
// pCur = pIterator->GetNext();
// }
//
class CParticleSimulateIterator { friend class CParticleMgr; friend class CParticleEffectBinding; public: CParticleSimulateIterator(); // Iterate through the particles, simulate them, and remove them if necessary.
Particle* GetFirst(); Particle* GetNext(); float GetTimeDelta() const;
void RemoveParticle( Particle *pParticle ); void RemoveAllParticles();
private: CParticleEffectBinding *m_pEffectBinding; CEffectMaterial *m_pMaterial; float m_flTimeDelta;
bool m_bGotFirst; Particle *m_pNextParticle; };
// -------------------------------------------------------------------------------------------------------- //
// CParticleRenderIterator inlines
// -------------------------------------------------------------------------------------------------------- //
inline CParticleRenderIterator::CParticleRenderIterator() { m_pCur = NULL; m_bGotFirst = false; m_flPrevZ = 0; m_nParticlesInCurrentBatch = 0; m_MinZ = 1e24; m_MaxZ = -1e24; m_nZCoords = 0; }
inline const Particle* CParticleRenderIterator::GetFirst() { Assert( !m_bGotFirst ); m_bGotFirst = true;
m_pCur = m_pMaterial->m_Particles.m_pNext; if ( m_pCur == &m_pMaterial->m_Particles ) return NULL;
m_pParticleDraw->m_pSubTexture = m_pCur->m_pSubTexture; return m_pCur; }
inline void CParticleRenderIterator::TestFlushBatch() { ++m_nParticlesInCurrentBatch; if( m_nParticlesInCurrentBatch >= NUM_PARTICLES_PER_BATCH ) { m_pMeshBuilder->End( false, true );
if(m_pMaterialSystem) { CMatRenderContextPtr pRenderContext( m_pMaterialSystem ); m_pMesh = pRenderContext->GetDynamicMesh( true ); }
m_pMeshBuilder->Begin( m_pMesh, MATERIAL_QUADS, NUM_PARTICLES_PER_BATCH * 4 );
m_nParticlesInCurrentBatch = 0; } }
inline const Particle* CParticleRenderIterator::GetNext( float sortKey ) { Assert( m_bGotFirst ); Assert( m_pCur );
TestFlushBatch();
Particle *pNext = m_pCur->m_pNext;
// Update the incremental sort.
if( m_bBucketSort ) { m_MinZ = MIN( sortKey, m_MinZ ); m_MaxZ = MAX( sortKey, m_MaxZ ); m_zCoords[m_nZCoords] = sortKey; ++m_nZCoords; } else { // Swap with the previous particle (incremental sort)?
if( m_pCur != m_pMaterial->m_Particles.m_pNext && m_flPrevZ > sortKey ) { SwapParticles( m_pCur->m_pPrev, m_pCur ); } else { m_flPrevZ = sortKey; } }
m_pCur = pNext; if ( m_pCur == &m_pMaterial->m_Particles ) return NULL;
m_pParticleDraw->m_pSubTexture = m_pCur->m_pSubTexture; return m_pCur; }
inline ParticleDraw* CParticleRenderIterator::GetParticleDraw() const { return m_pParticleDraw; }
// -------------------------------------------------------------------------------------------------------- //
// CParticleSimulateIterator inlines
// -------------------------------------------------------------------------------------------------------- //
inline CParticleSimulateIterator::CParticleSimulateIterator() { m_pNextParticle = NULL; #ifdef _DEBUG
m_bGotFirst = false; #endif
}
inline Particle* CParticleSimulateIterator::GetFirst() { #ifdef _DEBUG
// Make sure they're either starting out fresh or that the previous guy iterated through all the particles.
if ( m_bGotFirst ) { Assert( m_pNextParticle == &m_pMaterial->m_Particles ); } #endif
Particle *pRet = m_pMaterial->m_Particles.m_pNext; if ( pRet == &m_pMaterial->m_Particles ) return NULL;
#ifdef _DEBUG
m_bGotFirst = true; #endif
m_pNextParticle = pRet->m_pNext; return pRet; }
inline Particle* CParticleSimulateIterator::GetNext() { Particle *pRet = m_pNextParticle;
if ( pRet == &m_pMaterial->m_Particles ) return NULL; m_pNextParticle = pRet->m_pNext; return pRet; }
inline void CParticleSimulateIterator::RemoveParticle( Particle *pParticle ) { m_pEffectBinding->RemoveParticle( pParticle ); }
inline void CParticleSimulateIterator::RemoveAllParticles() { Particle *pParticle = GetFirst(); while ( pParticle ) { RemoveParticle( pParticle ); pParticle = GetNext(); } }
inline float CParticleSimulateIterator::GetTimeDelta() const { return m_flTimeDelta; }
#endif // PARTICLE_ITERATORS_H
|