Seaside/SpyCustom/sdk/particle_iterators.h
2021-06-16 18:48:15 +03:00

222 lines
4.1 KiB
C++

#ifndef PARTICLE_ITERATORS_H
#define PARTICLE_ITERATORS_H
#ifdef _WIN32
#pragma once
#endif
#include "imesh.h"
#include "particledraw.h"
#define NUM_PARTICLES_PER_BATCH 200
#ifndef _XBOX
#define MAX_TOTAL_PARTICLES 2048
#else
#define MAX_TOTAL_PARTICLES 1024
#endif
class CParticleRenderIterator
{
friend class CParticleMgr;
friend class CParticleEffectBinding;
public:
CParticleRenderIterator();
const Particle* GetFirst();
const Particle* GetNext(float sortKey);
ParticleDraw* GetParticleDraw() const;
private:
void TestFlushBatch();
private:
CParticleEffectBinding* m_pEffectBinding;
CEffectMaterial* m_pMaterial;
ParticleDraw* m_pParticleDraw;
CMeshBuilder* m_pMeshBuilder;
IMesh* m_pMesh;
bool m_bBucketSort;
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;
};
class CParticleSimulateIterator
{
friend class CParticleMgr;
friend class CParticleEffectBinding;
public:
CParticleSimulateIterator();
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;
};
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;
if (m_bBucketSort)
{
m_MinZ = MIN(sortKey, m_MinZ);
m_MaxZ = MAX(sortKey, m_MaxZ);
m_zCoords[m_nZCoords] = sortKey;
++m_nZCoords;
}
else
{
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;
}
inline CParticleSimulateIterator::CParticleSimulateIterator()
{
m_pNextParticle = NULL;
#ifdef _DEBUG
m_bGotFirst = false;
#endif
}
inline Particle* CParticleSimulateIterator::GetFirst()
{
#ifdef _DEBUG
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