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.

273 lines
6.2 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Client side CTFTeam class
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef PARTICLE_ITERATORS_H
  8. #define PARTICLE_ITERATORS_H
  9. #ifdef _WIN32
  10. #pragma once
  11. #endif
  12. #include "materialsystem/imesh.h"
  13. #include "particledraw.h"
  14. #define NUM_PARTICLES_PER_BATCH 200
  15. #define MAX_TOTAL_PARTICLES 2048 // Max particles in the world
  16. //
  17. // Iterate the particles like this:
  18. //
  19. // Particle *pCur = pIterator->GetFirst();
  20. // while ( pCur )
  21. // {
  22. // ... render the particle here and figure out the sort key and position
  23. // pCur = pIterator->GetNext( sortKey, pCur->m_Pos );
  24. // }
  25. //
  26. class CParticleRenderIterator
  27. {
  28. friend class CParticleMgr;
  29. friend class CParticleEffectBinding;
  30. public:
  31. CParticleRenderIterator();
  32. // The sort key is used to sort the particles incrementally as they're rendered.
  33. // They only get sorted in the main rendered view (ie: not in reflections or monitors).
  34. // These return const because you should only modify particles during their simulation.
  35. const Particle* GetFirst();
  36. const Particle* GetNext( float sortKey );
  37. // Use this to render. This can return NULL, in which case you shouldn't render.
  38. // This being NULL is a carryover from when particles rendered and simulated together and
  39. // it should GO AWAY SOON!
  40. ParticleDraw* GetParticleDraw() const;
  41. private:
  42. void TestFlushBatch();
  43. private:
  44. // Set by CParticleMgr.
  45. CParticleEffectBinding *m_pEffectBinding;
  46. CEffectMaterial *m_pMaterial;
  47. ParticleDraw *m_pParticleDraw;
  48. CMeshBuilder *m_pMeshBuilder;
  49. IMesh *m_pMesh;
  50. bool m_bBucketSort;
  51. IMaterialSystem *m_pMaterialSystem; // Needed when we have to break particles into multiple batches
  52. // Output after rendering.
  53. float m_MinZ;
  54. float m_MaxZ;
  55. float m_zCoords[MAX_TOTAL_PARTICLES];
  56. int m_nZCoords;
  57. Particle *m_pCur;
  58. bool m_bGotFirst;
  59. float m_flPrevZ;
  60. int m_nParticlesInCurrentBatch;
  61. };
  62. //
  63. // Iterate the particles like this:
  64. //
  65. // Particle *pCur = pIterator->GetFirst();
  66. // while ( pCur )
  67. // {
  68. // ... simulate here.. call pIterator->RemoveParticle if you want the particle to go away
  69. // pCur = pIterator->GetNext();
  70. // }
  71. //
  72. class CParticleSimulateIterator
  73. {
  74. friend class CParticleMgr;
  75. friend class CParticleEffectBinding;
  76. public:
  77. CParticleSimulateIterator();
  78. // Iterate through the particles, simulate them, and remove them if necessary.
  79. Particle* GetFirst();
  80. Particle* GetNext();
  81. float GetTimeDelta() const;
  82. void RemoveParticle( Particle *pParticle );
  83. void RemoveAllParticles();
  84. private:
  85. CParticleEffectBinding *m_pEffectBinding;
  86. CEffectMaterial *m_pMaterial;
  87. float m_flTimeDelta;
  88. bool m_bGotFirst;
  89. Particle *m_pNextParticle;
  90. };
  91. // -------------------------------------------------------------------------------------------------------- //
  92. // CParticleRenderIterator inlines
  93. // -------------------------------------------------------------------------------------------------------- //
  94. inline CParticleRenderIterator::CParticleRenderIterator()
  95. {
  96. m_pCur = NULL;
  97. m_bGotFirst = false;
  98. m_flPrevZ = 0;
  99. m_nParticlesInCurrentBatch = 0;
  100. m_MinZ = 1e24;
  101. m_MaxZ = -1e24;
  102. m_nZCoords = 0;
  103. }
  104. inline const Particle* CParticleRenderIterator::GetFirst()
  105. {
  106. Assert( !m_bGotFirst );
  107. m_bGotFirst = true;
  108. m_pCur = m_pMaterial->m_Particles.m_pNext;
  109. if ( m_pCur == &m_pMaterial->m_Particles )
  110. return NULL;
  111. m_pParticleDraw->m_pSubTexture = m_pCur->m_pSubTexture;
  112. return m_pCur;
  113. }
  114. inline void CParticleRenderIterator::TestFlushBatch()
  115. {
  116. ++m_nParticlesInCurrentBatch;
  117. if( m_nParticlesInCurrentBatch >= NUM_PARTICLES_PER_BATCH )
  118. {
  119. m_pMeshBuilder->End( false, true );
  120. if(m_pMaterialSystem)
  121. {
  122. CMatRenderContextPtr pRenderContext( m_pMaterialSystem );
  123. m_pMesh = pRenderContext->GetDynamicMesh( true );
  124. }
  125. m_pMeshBuilder->Begin( m_pMesh, MATERIAL_QUADS, NUM_PARTICLES_PER_BATCH * 4 );
  126. m_nParticlesInCurrentBatch = 0;
  127. }
  128. }
  129. inline const Particle* CParticleRenderIterator::GetNext( float sortKey )
  130. {
  131. Assert( m_bGotFirst );
  132. Assert( m_pCur );
  133. TestFlushBatch();
  134. Particle *pNext = m_pCur->m_pNext;
  135. // Update the incremental sort.
  136. if( m_bBucketSort )
  137. {
  138. m_MinZ = MIN( sortKey, m_MinZ );
  139. m_MaxZ = MAX( sortKey, m_MaxZ );
  140. m_zCoords[m_nZCoords] = sortKey;
  141. ++m_nZCoords;
  142. }
  143. else
  144. {
  145. // Swap with the previous particle (incremental sort)?
  146. if( m_pCur != m_pMaterial->m_Particles.m_pNext && m_flPrevZ > sortKey )
  147. {
  148. SwapParticles( m_pCur->m_pPrev, m_pCur );
  149. }
  150. else
  151. {
  152. m_flPrevZ = sortKey;
  153. }
  154. }
  155. m_pCur = pNext;
  156. if ( m_pCur == &m_pMaterial->m_Particles )
  157. return NULL;
  158. m_pParticleDraw->m_pSubTexture = m_pCur->m_pSubTexture;
  159. return m_pCur;
  160. }
  161. inline ParticleDraw* CParticleRenderIterator::GetParticleDraw() const
  162. {
  163. return m_pParticleDraw;
  164. }
  165. // -------------------------------------------------------------------------------------------------------- //
  166. // CParticleSimulateIterator inlines
  167. // -------------------------------------------------------------------------------------------------------- //
  168. inline CParticleSimulateIterator::CParticleSimulateIterator()
  169. {
  170. m_pNextParticle = NULL;
  171. #ifdef _DEBUG
  172. m_bGotFirst = false;
  173. #endif
  174. }
  175. inline Particle* CParticleSimulateIterator::GetFirst()
  176. {
  177. #ifdef _DEBUG
  178. // Make sure they're either starting out fresh or that the previous guy iterated through all the particles.
  179. if ( m_bGotFirst )
  180. {
  181. Assert( m_pNextParticle == &m_pMaterial->m_Particles );
  182. }
  183. #endif
  184. Particle *pRet = m_pMaterial->m_Particles.m_pNext;
  185. if ( pRet == &m_pMaterial->m_Particles )
  186. return NULL;
  187. #ifdef _DEBUG
  188. m_bGotFirst = true;
  189. #endif
  190. m_pNextParticle = pRet->m_pNext;
  191. return pRet;
  192. }
  193. inline Particle* CParticleSimulateIterator::GetNext()
  194. {
  195. Particle *pRet = m_pNextParticle;
  196. if ( pRet == &m_pMaterial->m_Particles )
  197. return NULL;
  198. m_pNextParticle = pRet->m_pNext;
  199. return pRet;
  200. }
  201. inline void CParticleSimulateIterator::RemoveParticle( Particle *pParticle )
  202. {
  203. m_pEffectBinding->RemoveParticle( pParticle );
  204. }
  205. inline void CParticleSimulateIterator::RemoveAllParticles()
  206. {
  207. Particle *pParticle = GetFirst();
  208. while ( pParticle )
  209. {
  210. RemoveParticle( pParticle );
  211. pParticle = GetNext();
  212. }
  213. }
  214. inline float CParticleSimulateIterator::GetTimeDelta() const
  215. {
  216. return m_flTimeDelta;
  217. }
  218. #endif // PARTICLE_ITERATORS_H