diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /sp/src/game/client/particle_iterators.h | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'sp/src/game/client/particle_iterators.h')
| -rw-r--r-- | sp/src/game/client/particle_iterators.h | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/sp/src/game/client/particle_iterators.h b/sp/src/game/client/particle_iterators.h new file mode 100644 index 00000000..d7c4d3d6 --- /dev/null +++ b/sp/src/game/client/particle_iterators.h @@ -0,0 +1,270 @@ +//========= Copyright 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
+#ifndef _XBOX
+#define MAX_TOTAL_PARTICLES 2048 // Max particles in the world
+#else
+#define MAX_TOTAL_PARTICLES 1024
+#endif
+
+
+//
+// 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;
+
+ // 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 );
+ 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
+
|