mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-16 13:43:00 +00:00
1
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user