// Copyright (c) 2008-2023 the Urho3D project // License: MIT /// \file #pragma once #include "../GraphicsAPI/GraphicsDefs.h" #include "../Resource/Resource.h" namespace Urho3D { /// Particle emitter shapes. enum EmitterType { EMITTER_SPHERE = 0, EMITTER_BOX, EMITTER_SPHEREVOLUME, EMITTER_CYLINDER, EMITTER_RING }; /// %Color animation frame definition. /// @nocount struct ColorFrame { /// Construct with default values. ColorFrame() : time_(0.0f) { } /// Construct with a color and zero time. explicit ColorFrame(const Color& color) : color_(color), time_(0.0f) { } /// Construct from a color and time. ColorFrame(const Color& color, float time) : color_(color), time_(time) { } /// Return interpolated value with another color-time pair at the time specified. Color Interpolate(const ColorFrame& next, float time) const { float timeInterval = next.time_ - time_; if (timeInterval > 0.0f) { float t = (time - time_) / timeInterval; return color_.Lerp(next.color_, t); } else return next.color_; } /// Color. Color color_; /// Time. float time_; }; /// %Texture animation frame definition. /// @nocount struct TextureFrame { /// Construct with default values. TextureFrame() : uv_(0.0f, 0.0f, 1.0f, 1.0f), time_(0.0f) { } /// UV coordinates. Rect uv_; /// Time. float time_; }; static const unsigned DEFAULT_NUM_PARTICLES = 10; class Material; class XMLFile; class XMLElement; /// %Particle effect definition. class URHO3D_API ParticleEffect : public Resource { URHO3D_OBJECT(ParticleEffect, Resource); public: /// Construct. explicit ParticleEffect(Context* context); /// Destruct. ~ParticleEffect() override; /// Register object factory. /// @nobind static void RegisterObject(Context* context); /// Load resource from stream. May be called from a worker thread. Return true if successful. bool BeginLoad(Deserializer& source) override; /// Finish resource loading. Always called from the main thread. Return true if successful. bool EndLoad() override; /// Save resource. Return true if successful. bool Save(Serializer& dest) const override; using Resource::Load; /// Save resource to XMLElement. Return true if successful. bool Save(XMLElement& dest) const; /// Load resource from XMLElement synchronously. Return true if successful. bool Load(const XMLElement& source); /// Set material. /// @property void SetMaterial(Material* material); /// Set maximum number of particles. /// @property void SetNumParticles(unsigned num); /// Set whether to update when particles are not visible. /// @property void SetUpdateInvisible(bool enable); /// Set whether billboards are relative to the scene node. /// @property void SetRelative(bool enable); /// Set whether scene node scale affects billboards' size. /// @property void SetScaled(bool enable); /// Set whether billboards are sorted by distance. /// @property void SetSorted(bool enable); /// Set whether billboards have fixed size on screen (measured in pixels) regardless of distance to camera. /// @property void SetFixedScreenSize(bool enable); /// Set animation LOD bias. /// @property void SetAnimationLodBias(float lodBias); /// Set emitter type. /// @property void SetEmitterType(EmitterType type); /// Set emitter size. /// @property void SetEmitterSize(const Vector3& size); /// Set negative direction limit. /// @property void SetMinDirection(const Vector3& direction); /// Set positive direction limit. /// @property void SetMaxDirection(const Vector3& direction); /// Set constant force acting on particles. /// @property void SetConstantForce(const Vector3& force); /// Set particle velocity damping force. /// @property void SetDampingForce(float force); /// Set emission active period length (0 = infinite). /// @property void SetActiveTime(float time); /// Set emission inactive period length (0 = infinite). /// @property void SetInactiveTime(float time); /// Set minimum emission rate. /// @property void SetMinEmissionRate(float rate); /// Set maximum emission rate. /// @property void SetMaxEmissionRate(float rate); /// Set particle minimum size. /// @property void SetMinParticleSize(const Vector2& size); /// Set particle maximum size. /// @property void SetMaxParticleSize(const Vector2& size); /// Set particle minimum time to live. /// @property void SetMinTimeToLive(float time); /// Set particle maximum time to live. /// @property void SetMaxTimeToLive(float time); /// Set particle minimum velocity. /// @property void SetMinVelocity(float velocity); /// Set particle maximum velocity. /// @property void SetMaxVelocity(float velocity); /// Set particle minimum rotation. /// @property void SetMinRotation(float rotation); /// Set particle maximum rotation. /// @property void SetMaxRotation(float rotation); /// Set particle minimum rotation speed. /// @property void SetMinRotationSpeed(float speed); /// Set particle maximum rotation speed. /// @property void SetMaxRotationSpeed(float speed); /// Set particle size additive modifier. /// @property void SetSizeAdd(float sizeAdd); /// Set particle size multiplicative modifier. /// @property void SetSizeMul(float sizeMul); /// Set how the particles should rotate in relation to the camera. Default is to follow camera rotation on all axes (FC_ROTATE_XYZ). /// @property void SetFaceCameraMode(FaceCameraMode mode); /// Add a color frame sorted in the correct position based on time. void AddColorTime(const Color& color, float time); /// Add a color frame sorted in the correct position based on time. void AddColorFrame(const ColorFrame& colorFrame); /// Remove color frame at index. void RemoveColorFrame(unsigned index); /// Set color animation of particles. /// @nobindtemp void SetColorFrames(const Vector& colorFrames); /// Set color animation frame at index. If index is greater than number of color frames, new color frames are added. void SetColorFrame(unsigned index, const ColorFrame& colorFrame); /// Set number of color frames. /// @property void SetNumColorFrames(unsigned number); /// Sort the list of color frames based on time. void SortColorFrames(); /// Add a texture frame sorted in the correct position based on time. void AddTextureTime(const Rect& uv, float time); /// Add a texture frame sorted in the correct position based on time. void AddTextureFrame(const TextureFrame& textureFrame); /// Remove texture frame at index. void RemoveTextureFrame(unsigned index); /// Set particle texture animation. /// @nobindtemp void SetTextureFrames(const Vector& textureFrames); /// Set number of texture animation frames. void SetTextureFrame(unsigned index, const TextureFrame& textureFrame); /// Set number of texture frames. /// @property void SetNumTextureFrames(unsigned number); /// Sort the list of texture frames based on time. void SortTextureFrames(); /// Clone the particle effect. SharedPtr Clone(const String& cloneName = String::EMPTY) const; /// Return material. /// @property Material* GetMaterial() const { return material_; } /// Return maximum number of particles. /// @property unsigned GetNumParticles() const { return numParticles_; } /// Return whether to update when particles are not visible. /// @property bool GetUpdateInvisible() const { return updateInvisible_; } /// Return whether billboards are relative to the scene node. /// @property bool IsRelative() const { return relative_; } /// Return whether scene node scale affects billboards' size. /// @property bool IsScaled() const { return scaled_; } /// Return whether billboards are sorted. /// @property bool IsSorted() const { return sorted_; } /// Return whether billboards are fixed screen size. /// @property bool IsFixedScreenSize() const { return fixedScreenSize_; } /// Return animation Lod bias. /// @property float GetAnimationLodBias() const { return animationLodBias_; } /// Return emitter type. /// @property EmitterType GetEmitterType() const { return emitterType_; } /// Return emitter size. /// @property const Vector3& GetEmitterSize() const { return emitterSize_; } /// Return negative direction limit. /// @property const Vector3& GetMinDirection() const { return directionMin_; } /// Return positive direction limit. /// @property const Vector3& GetMaxDirection() const { return directionMax_; } /// Return constant force acting on particles. /// @property const Vector3& GetConstantForce() const { return constantForce_; } /// Return particle velocity damping force. /// @property float GetDampingForce() const { return dampingForce_; } /// Return emission active period length (0 = infinite). /// @property float GetActiveTime() const { return activeTime_; } /// Return emission inactive period length (0 = infinite). /// @property float GetInactiveTime() const { return inactiveTime_; } /// Return minimum emission rate. /// @property float GetMinEmissionRate() const { return emissionRateMin_; } /// Return maximum emission rate. /// @property float GetMaxEmissionRate() const { return emissionRateMax_; } /// Return particle minimum size. /// @property const Vector2& GetMinParticleSize() const { return sizeMin_; } /// Return particle maximum size. /// @property const Vector2& GetMaxParticleSize() const { return sizeMax_; } /// Return particle minimum time to live. /// @property float GetMinTimeToLive() const { return timeToLiveMin_; } /// Return particle maximum time to live. /// @property float GetMaxTimeToLive() const { return timeToLiveMax_; } /// Return particle minimum velocity. /// @property float GetMinVelocity() const { return velocityMin_; } /// Return particle maximum velocity. /// @property float GetMaxVelocity() const { return velocityMax_; } /// Return particle minimum rotation. /// @property float GetMinRotation() const { return rotationMin_; } /// Return particle maximum rotation. /// @property float GetMaxRotation() const { return rotationMax_; } /// Return particle minimum rotation speed. /// @property float GetMinRotationSpeed() const { return rotationSpeedMin_; } /// Return particle maximum rotation speed. /// @property float GetMaxRotationSpeed() const { return rotationSpeedMax_; } /// Return particle size additive modifier. /// @property float GetSizeAdd() const { return sizeAdd_; } /// Return particle size multiplicative modifier. /// @property float GetSizeMul() const { return sizeMul_; } /// Return all color animation frames. /// @nobindtemp const Vector& GetColorFrames() const { return colorFrames_; } /// Return number of color animation frames. /// @property unsigned GetNumColorFrames() const { return colorFrames_.Size(); } /// Return a color animation frame, or null if outside range. const ColorFrame* GetColorFrame(unsigned index) const; /// Return all texture animation frames. /// @nobindtemp const Vector& GetTextureFrames() const { return textureFrames_; } /// Return number of texture animation frames. /// @property unsigned GetNumTextureFrames() const { return textureFrames_.Size(); } /// Return a texture animation frame, or null if outside range. const TextureFrame* GetTextureFrame(unsigned index) const; /// Return how the particles rotate in relation to the camera. /// @property FaceCameraMode GetFaceCameraMode() const { return faceCameraMode_; } /// Return random direction. Vector3 GetRandomDirection() const; /// Return random size. Vector2 GetRandomSize() const; /// Return random velocity. float GetRandomVelocity() const; /// Return random timetolive. float GetRandomTimeToLive() const; /// Return random rotationspeed. float GetRandomRotationSpeed() const; /// Return random rotation. float GetRandomRotation() const; private: /// Read a float range from an XML element. void GetFloatMinMax(const XMLElement& element, float& minValue, float& maxValue); /// Read a Vector2 range from an XML element. void GetVector2MinMax(const XMLElement& element, Vector2& minValue, Vector2& maxValue); /// Read a Vector3 from an XML element. void GetVector3MinMax(const XMLElement& element, Vector3& minValue, Vector3& maxValue); /// Material. SharedPtr material_; /// Number of particles. unsigned numParticles_; /// Update when invisible flag. bool updateInvisible_; /// Billboards relative flag. bool relative_; /// Scale affects billboard scale flag. bool scaled_; /// Billboards sorted flag. bool sorted_; /// Billboards fixed screen size flag. bool fixedScreenSize_; /// Animation LOD bias. float animationLodBias_; /// Emitter shape. EmitterType emitterType_; /// Emitter size. Vector3 emitterSize_; /// Particle direction minimum. Vector3 directionMin_; /// Particle direction maximum. Vector3 directionMax_; /// Particle constant force. Vector3 constantForce_; /// Particle velocity damping force. float dampingForce_; /// Active period. float activeTime_; /// Inactive period. float inactiveTime_; /// Particles per second minimum. float emissionRateMin_; /// Particles per second maximum. float emissionRateMax_; /// Particle size minimum. Vector2 sizeMin_; /// Particle size maximum. Vector2 sizeMax_; /// Particle time to live minimum. float timeToLiveMin_; /// Particle time to live maximum. float timeToLiveMax_; /// Particle velocity minimum. float velocityMin_; /// Particle velocity maximum. float velocityMax_; /// Particle rotation angle minimum. float rotationMin_; /// Particle rotation angle maximum. float rotationMax_; /// Particle rotation speed minimum. float rotationSpeedMin_; /// Particle rotation speed maximum. float rotationSpeedMax_; /// Particle size additive parameter. float sizeAdd_; /// Particle size multiplicative parameter. float sizeMul_; /// Particle color animation frames. Vector colorFrames_; /// Texture animation frames. Vector textureFrames_; /// Material name acquired during BeginLoad(). String loadMaterialName_; /// Particle rotation mode in relation to the camera. FaceCameraMode faceCameraMode_; }; }