//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // // $NoKeywords: $ //===========================================================================// #ifndef PARTICLES_SIMPLE_H #define PARTICLES_SIMPLE_H #ifdef _WIN32 #pragma once #endif #include "particlemgr.h" #include "ParticleSphereRenderer.h" #include "smartptr.h" // ------------------------------------------------------------------------------------------------ // // CParticleEffect is the base class that you can derive from to make a particle effect. // These can be used two ways: // // 1. Allocate a CParticleEffect-based object using the class's static Create() function. This gives // you back a smart pointer that handles the reference counting for you. // // 2. Contain a CParticleEffect object in your class. // ------------------------------------------------------------------------------------------------ // class CParticleEffect : public IParticleEffect { public: DECLARE_CLASS_NOBASE( CParticleEffect ); friend class CRefCountAccessor; // Call this before adding a bunch of particles to give it a rough estimate of where // your particles are for sorting amongst other translucent entities. void SetSortOrigin( const Vector &vSortOrigin ); PMaterialHandle GetPMaterial(const char *name); Particle* AddParticle( unsigned int particleSize, PMaterialHandle material, const Vector &origin ); CParticleEffectBinding& GetBinding() { return m_ParticleEffect; } const char *GetEffectName(); void AddFlags( int iFlags ) { m_Flags |= iFlags; } void RemoveFlags( int iFlags ) { m_Flags &= ~iFlags; } void SetDontRemove( bool bSet ) { if( bSet ) AddFlags( FLAG_DONT_REMOVE ); else RemoveFlags( FLAG_DONT_REMOVE ); } // IParticleEffect overrides public: virtual void SetParticleCullRadius( float radius ); virtual void NotifyRemove( void ); virtual const Vector & GetSortOrigin(); virtual void NotifyDestroyParticle( Particle* pParticle ); virtual void Update( float flTimeDelta ); // All Create() functions should call this so the effect deletes itself // when it is removed from the particle manager. void SetDynamicallyAllocated( bool bDynamic=true ); virtual bool ShouldSimulate() const { return m_bSimulate; } virtual void SetShouldSimulate( bool bSim ) { m_bSimulate = bSim; } int AllocateToolParticleEffectId(); int GetToolParticleEffectId() const; protected: CParticleEffect( const char *pDebugName ); virtual ~CParticleEffect(); // Returns nonzero if Release() has been called. int IsReleased(); enum { FLAG_ALLOCATED = (1<<1), // Most of the CParticleEffects are dynamically allocated but // some are member variables of a class. If they're member variables. FLAG_DONT_REMOVE = (1<<2), }; // Used to track down bugs. char const *m_pDebugName; CParticleEffectBinding m_ParticleEffect; Vector m_vSortOrigin; int m_Flags; // Combination of CParticleEffect::FLAG_ bool m_bSimulate; int m_nToolParticleEffectId; private: // Update the reference count. void AddRef(); void Release(); int m_RefCount; // When this goes to zero and the effect has no more active // particles, (and it's dynamically allocated), it will delete itself. CParticleEffect( const CParticleEffect & ); // not defined, not accessible }; inline int CParticleEffect::GetToolParticleEffectId() const { return m_nToolParticleEffectId; } inline int CParticleEffect::AllocateToolParticleEffectId() { m_nToolParticleEffectId = ParticleMgr()->AllocateToolParticleEffectId(); return m_nToolParticleEffectId; } //----------------------------------------------------------------------------- // Particle flags //----------------------------------------------------------------------------- enum SimpleParticleFlag_t { SIMPLE_PARTICLE_FLAG_WINDBLOWN = 0x1, SIMPLE_PARTICLE_FLAG_NO_VEL_DECAY = 0x2 // Used by the blood spray emitter. By default, it decays the // particle velocity. }; class SimpleParticle : public Particle { public: SimpleParticle() : m_iFlags(0) {} // AddSimpleParticle automatically initializes these fields. Vector m_vecVelocity; float m_flRoll; float m_flDieTime; // How long it lives for. float m_flLifetime; // How long it has been alive for so far. unsigned char m_uchColor[3]; unsigned char m_uchStartAlpha; unsigned char m_uchEndAlpha; unsigned char m_uchStartSize; unsigned char m_uchEndSize; unsigned char m_iFlags; // See SimpleParticleFlag_t above float m_flRollDelta; }; // CSimpleEmitter implements a common way to simulate and render particles. // // Effects can add particles to the particle manager and point at CSimpleEmitter // for the effect so they don't have to implement the simulation code. It simulates // velocity, and fades their alpha from invisible to solid and back to invisible over their lifetime. // // Particles you add using this effect must use the class CParticleSimple::Particle. class CSimpleEmitter : public CParticleEffect { // IParticleEffect overrides. public: DECLARE_CLASS( CSimpleEmitter, CParticleEffect ); static CSmartPtr Create( const char *pDebugName ); virtual void SimulateParticles( CParticleSimulateIterator *pIterator ); virtual void RenderParticles( CParticleRenderIterator *pIterator ); void SetNearClip( float nearClipMin, float nearClipMax ); void SetDrawBeforeViewModel( bool state = true ); SimpleParticle* AddSimpleParticle( PMaterialHandle hMaterial, const Vector &vOrigin, float flDieTime=3, unsigned char uchSize=10 ); void SetShouldDrawForSplitScreenUser( int nSlot ); // Overridables for variants like CEmberEffect. protected: CSimpleEmitter( const char *pDebugName = NULL ); virtual ~CSimpleEmitter(); virtual float UpdateAlpha( const SimpleParticle *pParticle ); virtual float UpdateScale( const SimpleParticle *pParticle ); virtual float UpdateRoll( SimpleParticle *pParticle, float timeDelta ); virtual void UpdateVelocity( SimpleParticle *pParticle, float timeDelta ); virtual Vector UpdateColor( const SimpleParticle *pParticle ); float m_flNearClipMin; float m_flNearClipMax; int m_nSplitScreenPlayerSlot; private: CSimpleEmitter( const CSimpleEmitter & ); // not defined, not accessible }; //================================================== // EmberEffect //================================================== class CEmberEffect : public CSimpleEmitter { public: CEmberEffect( const char *pDebugName ); static CSmartPtr Create( const char *pDebugName ); virtual void UpdateVelocity( SimpleParticle *pParticle, float timeDelta ); virtual Vector UpdateColor( const SimpleParticle *pParticle ); private: CEmberEffect( const CEmberEffect & ); // not defined, not accessible }; //================================================== // FireSmokeEffect //================================================== class CFireSmokeEffect : public CSimpleEmitter { public: CFireSmokeEffect( const char *pDebugName ); static CSmartPtr Create( const char *pDebugName ); virtual void UpdateVelocity( SimpleParticle *pParticle, float timeDelta ); virtual float UpdateAlpha( const SimpleParticle *pParticle ); protected: VPlane m_planeClip; private: CFireSmokeEffect( const CFireSmokeEffect & ); // not defined, not accessible }; //================================================== // CFireParticle //================================================== class CFireParticle : public CSimpleEmitter { public: CFireParticle( const char *pDebugName ); static CSmartPtr Create( const char *pDebugName ); virtual Vector UpdateColor( const SimpleParticle *pParticle ); private: CFireParticle( const CFireParticle & ); // not defined, not accessible }; #endif // PARTICLES_SIMPLE_H