//=========================================================================== // Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. // // Component: ParticleManager // // Description: Singleton class that encapsulates handles free floating particle systems // e.g. particles generated from collisions and other one-off entries // Particle Systems are added into the DSG // // // Authors: Michael Riegger // //=========================================================================== // Recompilation protection flag. #ifndef PARTICLEMANAGER_H #define PARTICLEMANAGER_H //=========================================================================== // Nested Includes //=========================================================================== #include #include // Needed for my STL allocations to go on the right heap #include #include #include #include #include #include #include #include #include //=========================================================================== // Forward References //=========================================================================== class tParticleSystemFactory; class tEffectController; //=========================================================================== // Constants, Typedefs, and Macro Definitions (needed by external clients) //=========================================================================== typedef int ParticlePlayerID; //=========================================================================== // Interface Definitions //=========================================================================== // Structure passed to ParticleManager::Add that describes what type of // particle system to create struct ParticleAttributes { ParticleAttributes() : mEmissionBias ( 1.0f ), mVelocity( 0, 0, 0) { } ParticleEnum::ParticleID mType; // only one bias so far, the emission bias // other biases would be simple to put in // NumParticles/Life/Speed/Weight/Gravity/Drag/Size/Spin float mEmissionBias; rmt::Vector mVelocity; }; //=========================================================================== // // Description: // ParticleManager provides a way to centalize adding/updating/rendering // of particle systems. Particles are inserted into the scene graph at the // specified layer and rendered when that specific layer is rendered. // // Constraints: // //=========================================================================== class ParticleManager { public: // Static Methods (for creating, destroying and acquiring an instance // of the ParticleManager) static ParticleManager* CreateInstance(); static ParticleManager* GetInstance(); static void DestroyInstance(); // Removes all particles from the DSG. Doesn't free any of them void DeactiveateAll(); // Systems are allocated into the ParticleManager via the InitializeSystem functions // These should be called from inside the particle system and breakable object loaders void InitializeSystem( ParticleEnum::ParticleID type, tParticleSystemFactory* factory, tEffectController* controller, int maxInstances, bool isDynamic = false); // Deletes a system, and frees all particles associated with it void DeleteSystem( ParticleEnum::ParticleID type ); // Kills all the particles of any type that was Initialized with isDynamic to true void DumpDynaLoad(); // Returns an identifier that can be used to reference // a continuously playing particle effect ParticlePlayerID GetUniqueID()const; // Tells the PM to play a cycling particle system. Note that this function // must be called every frame to have the emitter keep adding particles to // it. Otherwise, EMISSION bias is set to zero. Alive particles will gradually // fall to earth and disappear. void PlayCyclic( ParticlePlayerID id, const ParticleAttributes& attr, const rmt::Matrix& localMatrix ); void PlayCyclic( ParticlePlayerID id, const ParticleAttributes& attr, const rmt::Vector& position ); // Add a new particle system to the manager and insert it into the scene graph void Add ( const ParticleAttributes& attr, const rmt::Matrix& localMatrix ); void Add ( const ParticleAttributes& attr, const rmt::Vector& position ); // Temporary force render function for debugging only void DebugRender (); // Update animations on all managed particle systems void Update ( unsigned int deltaTime); // Remove all particle systems from the manager void ClearSystems (); protected: private: // Disable all constructors and the copy assignment operator, the singleton functions // CreateInstance and DestroyInstance handle this for the user ParticleManager(); ~ParticleManager(); ParticleManager( const ParticleManager& ); ParticleManager& operator=( const ParticleManager& ); // Reorients the transform matrix so that Up is always <0,1,0> // needed for particle system's gravity to always work the right way void ReorientUpAxis( const rmt::Matrix& in, rmt::Matrix* out ); class ManagedParticleSystem { public: ManagedParticleSystem( tParticleSystemFactory*, tEffectController* ); ~ManagedParticleSystem(); void Display()const { mpSystem->Display(); } void Update( float deltaTime ); void Unlock() { mUserID = -1; } bool IsLocked()const { return (mUserID >= 0); } void SetBias( unsigned int bias, float value ){ mpSystem->SetBias( bias, value ); } void SetActive( bool isActive ); void Reset(); void SetTransform( const rmt::Matrix& ); int LastFrameReached() const; ParticlePlayerID GetUserID()const { return mUserID; } void ThrowUpNewParticles() { mThrowUpNewParticles = true; } bool IsActive()const { return mIsActive; } void Lock( ParticlePlayerID id ) { mUserID = id; } void SetVelocity( const rmt::Vector& velocity ) { mpSystem->SetVelocity( velocity ); } private: RenderEnums::LayerEnum mLayer; ParticlePlayerID mUserID; bool mIsActive; float mEmissionBias; bool mThrowUpNewParticles; bool mIsInDSG; ParticleSystemDSG* mpSystem; }; // List of all active particle systems within the manager // Use a list for constant time random access deletions // typedef std::vector< ManagedParticleSystem*, s2alloc > MPSVector; // typedef std::vector< MPSVector, s2alloc > MPSVectorVector; typedef tPtrDynamicArray< ManagedParticleSystem* > MPSVector; typedef tPtrDynamicArray< MPSVector > MPSVectorVector; MPSVectorVector mActiveSystems; // List of all particle types that are dynamically loaded std::vector< bool, s2alloc > mIsParticleTypeDynamicallyLoaded; // Static instance of the ParticleManager singleton static ParticleManager* spInstance; }; // A little syntactic sugar for getting at this singleton. inline ParticleManager* GetParticleManager() { return( ParticleManager::GetInstance() ); } #endif