//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // //===========================================================================// #include "cbase.h" #include "particles_ez.h" #include "IGameSystem.h" #include "model_types.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" // Singletons for each type of particle system. // 0 = world, 1 = skybox static CSmartPtr g_pSimpleSingleton[2]; static CSmartPtr g_pEmberSingleton[2]; static CSmartPtr g_pFireSmokeSingleton[2]; static CSmartPtr g_pFireSingleton[2]; class CEZParticleInit : public CAutoGameSystem { public: CEZParticleInit() : CAutoGameSystem( "CEZParticleInit" ) { } template< class T > CSmartPtr InitSingleton( CSmartPtr pEmitter ) { if ( !pEmitter ) { Error( "InitSingleton: pEmitter is NULL" ); } pEmitter->GetBinding().SetDrawThruLeafSystem( false ); // Draw in DrawSingletons instead. pEmitter->SetSortOrigin( Vector( 0, 0, 0 ) ); // Since we draw manually in DrawSingletons, we don't care about // the bbox, so don't waste cycles inserting it into the leaf system // when it's not going to draw through that anyway. // (TODO: SetDrawThruLeafSystem(false) should trigger this automatically // in CParticleMgr). pEmitter->GetBinding().SetBBox( Vector( 0, 0, 0 ), Vector( 0, 0, 0 ) ); return pEmitter; } virtual void LevelInitPreEntity() { g_pSimpleSingleton[0] = InitSingleton( CSimpleEmitter::Create( "Simple Particle Singleton" ) ); g_pSimpleSingleton[1] = InitSingleton( CSimpleEmitter::Create( "Simple Particle Singleton [sky]" ) ); g_pEmberSingleton[0] = InitSingleton( CEmberEffect::Create( "Ember Particle Singleton" ) ); g_pEmberSingleton[1] = InitSingleton( CEmberEffect::Create( "Ember Particle Singleton [sky]" ) ); g_pFireSmokeSingleton[0] = InitSingleton( CFireSmokeEffect::Create( "Fire Smoke Particle Singleton" ) ); g_pFireSmokeSingleton[1] = InitSingleton( CFireSmokeEffect::Create( "Fire Smoke Particle Singleton [sky]" ) ); g_pFireSingleton[0] = InitSingleton( CFireParticle::Create( "Fire Particle Singleton" ) ); g_pFireSingleton[1] = InitSingleton( CFireParticle::Create( "Fire Particle Singleton [sky]" ) ); } virtual void LevelShutdownPreEntity() { g_pSimpleSingleton[0] = g_pSimpleSingleton[1] = NULL; g_pEmberSingleton[0] = g_pEmberSingleton[1] = NULL; g_pFireSmokeSingleton[0] = g_pFireSmokeSingleton[1] = NULL; g_pFireSingleton[0] = g_pFireSingleton[1] = NULL; } }; static CEZParticleInit g_EZParticleInit; template inline void CopyParticle( const T *pSrc, T *pDest ) { if ( pDest ) { // Copy the particle, but don't screw up the linked list it's in. Particle *pPrev = pDest->m_pPrev; Particle *pNext = pDest->m_pNext; PMaterialHandle pSubTexture = pDest->m_pSubTexture; *pDest = *pSrc; pDest->m_pPrev = pPrev; pDest->m_pNext = pNext; pDest->m_pSubTexture = pSubTexture; } } void AddSimpleParticle( const SimpleParticle *pParticle, PMaterialHandle hMaterial, bool bInSkybox ) { if ( g_pSimpleSingleton[bInSkybox].IsValid() ) { SimpleParticle *pNew = g_pSimpleSingleton[bInSkybox]->AddSimpleParticle( hMaterial, pParticle->m_Pos ); CopyParticle( pParticle, pNew ); } } void AddEmberParticle( const SimpleParticle *pParticle, PMaterialHandle hMaterial, bool bInSkybox ) { if ( g_pEmberSingleton[bInSkybox].IsValid() ) { SimpleParticle *pNew = g_pEmberSingleton[bInSkybox]->AddSimpleParticle( hMaterial, pParticle->m_Pos ); CopyParticle( pParticle, pNew ); } } void AddFireSmokeParticle( const SimpleParticle *pParticle, PMaterialHandle hMaterial, bool bInSkybox ) { if ( g_pFireSmokeSingleton[bInSkybox].IsValid() ) { SimpleParticle *pNew = g_pFireSmokeSingleton[bInSkybox]->AddSimpleParticle( hMaterial, pParticle->m_Pos ); CopyParticle( pParticle, pNew ); } } void AddFireParticle( const SimpleParticle *pParticle, PMaterialHandle hMaterial, bool bInSkybox ) { if ( g_pFireSingleton[bInSkybox].IsValid() ) { SimpleParticle *pNew = g_pFireSingleton[bInSkybox]->AddSimpleParticle( hMaterial, pParticle->m_Pos ); CopyParticle( pParticle, pNew ); } } void DrawParticleSingletons( bool bInSkybox ) { RenderableInstance_t instance; instance.m_nAlpha = 255; if ( g_pSimpleSingleton[bInSkybox].IsValid() ) { g_pSimpleSingleton[bInSkybox]->GetBinding().DrawModel( STUDIO_RENDER, instance ); } if ( g_pEmberSingleton[bInSkybox].IsValid() ) { g_pEmberSingleton[bInSkybox]->GetBinding().DrawModel( STUDIO_RENDER, instance ); } if ( g_pFireSmokeSingleton[bInSkybox].IsValid() ) { g_pFireSmokeSingleton[bInSkybox]->GetBinding().DrawModel( STUDIO_RENDER, instance ); } if ( g_pFireSingleton[bInSkybox].IsValid() ) { g_pFireSingleton[bInSkybox]->GetBinding().DrawModel( STUDIO_RENDER, instance ); } }