1 //
2 // Copyright (c) 2008-2017 the Urho3D project.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 //
22 
23 #pragma once
24 
25 #include "../Graphics/GraphicsDefs.h"
26 #include "../Resource/Resource.h"
27 
28 namespace Urho3D
29 {
30 
31 /// Particle emitter shapes.
32 enum EmitterType
33 {
34     EMITTER_SPHERE = 0,
35     EMITTER_BOX
36 };
37 
38 /// %Color animation frame definition.
39 struct ColorFrame
40 {
41     /// Construct with default values.
ColorFrameColorFrame42     ColorFrame() :
43         time_(0.0f)
44     {
45     }
46 
47     /// Construct with a color and zero time.
ColorFrameColorFrame48     ColorFrame(const Color& color) :
49         color_(color),
50         time_(0.0f)
51     {
52     }
53 
54     /// Construct from a color and time.
ColorFrameColorFrame55     ColorFrame(const Color& color, float time) :
56         color_(color),
57         time_(time)
58     {
59     }
60 
61     /// Return interpolated value with another color-time pair at the time specified.
InterpolateColorFrame62     Color Interpolate(const ColorFrame& next, float time) const
63     {
64         float timeInterval = next.time_ - time_;
65         if (timeInterval > 0.0f)
66         {
67             float t = (time - time_) / timeInterval;
68             return color_.Lerp(next.color_, t);
69         }
70         else
71             return next.color_;
72     }
73 
74     /// Color.
75     Color color_;
76     /// Time.
77     float time_;
78 };
79 
80 /// %Texture animation frame definition.
81 struct TextureFrame
82 {
83     /// Construct with default values.
TextureFrameTextureFrame84     TextureFrame() :
85         uv_(0.0f, 0.0f, 1.0f, 1.0f),
86         time_(0.0f)
87     {
88     }
89 
90     /// UV coordinates.
91     Rect uv_;
92     /// Time.
93     float time_;
94 };
95 
96 static const unsigned DEFAULT_NUM_PARTICLES = 10;
97 
98 class Material;
99 class XMLFile;
100 class XMLElement;
101 
102 /// %Particle effect definition.
103 class URHO3D_API ParticleEffect : public Resource
104 {
105     URHO3D_OBJECT(ParticleEffect, Resource);
106 
107 public:
108     /// Construct.
109     ParticleEffect(Context* context);
110     /// Destruct.
111     virtual ~ParticleEffect();
112     /// Register object factory.
113     static void RegisterObject(Context* context);
114 
115     /// Load resource from stream. May be called from a worker thread. Return true if successful.
116     virtual bool BeginLoad(Deserializer& source);
117     /// Finish resource loading. Always called from the main thread. Return true if successful.
118     virtual bool EndLoad();
119     /// Save resource. Return true if successful.
120     virtual bool Save(Serializer& dest) const;
121 
122     /// Save resource to XMLElement. Return true if successful.
123     bool Save(XMLElement& dest) const;
124     /// Load resource from XMLElement synchronously. Return true if successful.
125     bool Load(const XMLElement& source);
126     /// Set material.
127     void SetMaterial(Material* material);
128     /// Set maximum number of particles.
129     void SetNumParticles(unsigned num);
130     /// Set whether to update when particles are not visible.
131     void SetUpdateInvisible(bool enable);
132     /// Set whether billboards are relative to the scene node.
133     void SetRelative(bool enable);
134     /// Set whether scene node scale affects billboards' size.
135     void SetScaled(bool enable);
136     /// Set whether billboards are sorted by distance.
137     void SetSorted(bool enable);
138     /// Set whether billboards have fixed size on screen (measured in pixels) regardless of distance to camera.
139     void SetFixedScreenSize(bool enable);
140     /// Set animation LOD bias.
141     void SetAnimationLodBias(float lodBias);
142     /// Set emitter type.
143     void SetEmitterType(EmitterType type);
144     /// Set emitter size.
145     void SetEmitterSize(const Vector3& size);
146     /// Set negative direction limit.
147     void SetMinDirection(const Vector3& direction);
148     /// Set positive direction limit.
149     void SetMaxDirection(const Vector3& direction);
150     /// Set constant force acting on particles.
151     void SetConstantForce(const Vector3& force);
152     /// Set particle velocity damping force.
153     void SetDampingForce(float force);
154     /// Set emission active period length (0 = infinite.)
155     void SetActiveTime(float time);
156     /// Set emission inactive period length (0 = infinite.)
157     void SetInactiveTime(float time);
158     /// Set minimum emission rate.
159     void SetMinEmissionRate(float rate);
160     /// Set maximum emission rate.
161     void SetMaxEmissionRate(float rate);
162     /// Set particle minimum size.
163     void SetMinParticleSize(const Vector2& size);
164     /// Set particle maximum size.
165     void SetMaxParticleSize(const Vector2& size);
166     /// Set particle minimum time to live.
167     void SetMinTimeToLive(float time);
168     /// Set particle maximum time to live.
169     void SetMaxTimeToLive(float time);
170     /// Set particle minimum velocity.
171     void SetMinVelocity(float velocity);
172     /// Set particle maximum velocity.
173     void SetMaxVelocity(float velocity);
174     /// Set particle minimum rotation.
175     void SetMinRotation(float rotation);
176     /// Set particle maximum rotation.
177     void SetMaxRotation(float rotation);
178     /// Set particle minimum rotation speed.
179     void SetMinRotationSpeed(float speed);
180     /// Set particle maximum rotation speed.
181     void SetMaxRotationSpeed(float speed);
182     /// Set particle size additive modifier.
183     void SetSizeAdd(float sizeAdd);
184     /// Set particle size multiplicative modifier.
185     void SetSizeMul(float sizeMul);
186     /// Set how the particles should rotate in relation to the camera. Default is to follow camera rotation on all axes (FC_ROTATE_XYZ.)
187     void SetFaceCameraMode(FaceCameraMode mode);
188 
189     /// Add a color frame sorted in the correct position based on time.
190     void AddColorTime(const Color& color, const float time);
191     /// Add a color frame sorted in the correct position based on time.
192     void AddColorFrame(const ColorFrame& colorFrame);
193     /// Remove color frame at index
194     void RemoveColorFrame(unsigned index);
195     /// Set color animation of particles.
196     void SetColorFrames(const Vector<ColorFrame>& colorFrames);
197     /// Set color animation frame at index. If index is greater than number of color frames, new color frames are added.
198     void SetColorFrame(unsigned index, const ColorFrame& colorFrame);
199     /// Set number of color frames.
200     void SetNumColorFrames(unsigned number);
201     /// Sort the list of color frames based on time.
202     void SortColorFrames();
203 
204     /// Add a texture frame sorted in the correct position based on time.
205     void AddTextureTime(const Rect& uv, const float time);
206     /// Add a texture frame sorted in the correct position based on time.
207     void AddTextureFrame(const TextureFrame& textureFrame);
208     /// Remove texture frame at index
209     void RemoveTextureFrame(unsigned index);
210     /// Set particle texture animation.
211     void SetTextureFrames(const Vector<TextureFrame>& animation);
212     /// Set number of texture animation frames.
213     void SetTextureFrame(unsigned index, const TextureFrame& textureFrame);
214     /// Set number of texture frames.
215     void SetNumTextureFrames(unsigned number);
216     /// Sort the list of texture frames based on time.
217     void SortTextureFrames();
218     /// Clone the particle effect.
219     SharedPtr<ParticleEffect> Clone(const String& cloneName = String::EMPTY) const;
220 
221     /// Return material.
GetMaterial()222     Material* GetMaterial() const { return material_; }
223 
224     /// Return maximum number of particles.
GetNumParticles()225     unsigned GetNumParticles() const { return numParticles_; }
226 
227     /// Return whether to update when particles are not visible.
GetUpdateInvisible()228     bool GetUpdateInvisible() const { return updateInvisible_; }
229 
230     /// Return whether billboards are relative to the scene node.
IsRelative()231     bool IsRelative() const { return relative_; }
232 
233     /// Return whether scene node scale affects billboards' size.
IsScaled()234     bool IsScaled() const { return scaled_; }
235 
236     /// Return whether billboards are sorted.
IsSorted()237     bool IsSorted() const { return sorted_; }
238 
239     /// Return whether billboards are fixed screen size.
IsFixedScreenSize()240     bool IsFixedScreenSize() const { return fixedScreenSize_; }
241 
242     /// Return animation Lod bias.
GetAnimationLodBias()243     float GetAnimationLodBias() const { return animationLodBias_; }
244 
245     /// Return emitter type.
GetEmitterType()246     EmitterType GetEmitterType() const { return emitterType_; }
247 
248     /// Return emitter size.
GetEmitterSize()249     const Vector3& GetEmitterSize() const { return emitterSize_; }
250 
251     /// Return negative direction limit.
GetMinDirection()252     const Vector3& GetMinDirection() const { return directionMin_; }
253 
254     /// Return positive direction limit.
GetMaxDirection()255     const Vector3& GetMaxDirection() const { return directionMax_; }
256 
257     /// Return constant force acting on particles.
GetConstantForce()258     const Vector3& GetConstantForce() const { return constantForce_; }
259 
260     /// Return particle velocity damping force.
GetDampingForce()261     float GetDampingForce() const { return dampingForce_; }
262 
263     /// Return emission active period length (0 = infinite.)
GetActiveTime()264     float GetActiveTime() const { return activeTime_; }
265 
266     /// Return emission inactive period length (0 = infinite.)
GetInactiveTime()267     float GetInactiveTime() const { return inactiveTime_; }
268 
269     /// Return minimum emission rate.
GetMinEmissionRate()270     float GetMinEmissionRate() const { return emissionRateMin_; }
271 
272     /// Return maximum emission rate.
GetMaxEmissionRate()273     float GetMaxEmissionRate() const { return emissionRateMax_; }
274 
275     /// Return particle minimum size.
GetMinParticleSize()276     const Vector2& GetMinParticleSize() const { return sizeMin_; }
277 
278     /// Return particle maximum size.
GetMaxParticleSize()279     const Vector2& GetMaxParticleSize() const { return sizeMax_; }
280 
281     /// Return particle minimum time to live.
GetMinTimeToLive()282     float GetMinTimeToLive() const { return timeToLiveMin_; }
283 
284     /// Return particle maximum time to live.
GetMaxTimeToLive()285     float GetMaxTimeToLive() const { return timeToLiveMax_; }
286 
287     /// Return particle minimum velocity.
GetMinVelocity()288     float GetMinVelocity() const { return velocityMin_; }
289 
290     /// Return particle maximum velocity.
GetMaxVelocity()291     float GetMaxVelocity() const { return velocityMax_; }
292 
293     /// Return particle minimum rotation.
GetMinRotation()294     float GetMinRotation() const { return rotationMin_; }
295 
296     /// Return particle maximum rotation.
GetMaxRotation()297     float GetMaxRotation() const { return rotationMax_; }
298 
299     /// Return particle minimum rotation speed.
GetMinRotationSpeed()300     float GetMinRotationSpeed() const { return rotationSpeedMin_; }
301 
302     /// Return particle maximum rotation speed.
GetMaxRotationSpeed()303     float GetMaxRotationSpeed() const { return rotationSpeedMax_; }
304 
305     /// Return particle size additive modifier.
GetSizeAdd()306     float GetSizeAdd() const { return sizeAdd_; }
307 
308     /// Return particle size multiplicative modifier.
GetSizeMul()309     float GetSizeMul() const { return sizeMul_; }
310 
311     /// Return all color animation frames.
GetColorFrames()312     const Vector<ColorFrame>& GetColorFrames() const { return colorFrames_; }
313 
314     /// Return number of color animation frames.
GetNumColorFrames()315     unsigned GetNumColorFrames() const { return colorFrames_.Size(); }
316 
317     /// Return a color animation frame, or null if outside range.
318     const ColorFrame* GetColorFrame(unsigned index) const;
319 
320     /// Return all texture animation frames.
GetTextureFrames()321     const Vector<TextureFrame>& GetTextureFrames() const { return textureFrames_; }
322 
323     /// Return number of texture animation frames.
GetNumTextureFrames()324     unsigned GetNumTextureFrames() const { return textureFrames_.Size(); }
325 
326     /// Return a texture animation frame, or null if outside range.
327     const TextureFrame* GetTextureFrame(unsigned index) const;
328 
329     /// Return how the particles rotate in relation to the camera.
GetFaceCameraMode()330     FaceCameraMode GetFaceCameraMode() const { return faceCameraMode_; }
331 
332     /// Return random direction.
333     Vector3 GetRandomDirection() const;
334     /// Return random size.
335     Vector2 GetRandomSize() const;
336     /// Return random velocity.
337     float GetRandomVelocity() const;
338     /// Return random timetolive.
339     float GetRandomTimeToLive() const;
340     /// Return random rotationspeed.
341     float GetRandomRotationSpeed() const;
342     /// Return random rotation.
343     float GetRandomRotation() const;
344 
345 private:
346     /// Read a float range from an XML element.
347     void GetFloatMinMax(const XMLElement& element, float& minValue, float& maxValue);
348     /// Read a Vector2 range from an XML element.
349     void GetVector2MinMax(const XMLElement& element, Vector2& minValue, Vector2& maxValue);
350     /// Read a Vector3 from an XML element.
351     void GetVector3MinMax(const XMLElement& element, Vector3& minValue, Vector3& maxValue);
352 
353     /// Material.
354     SharedPtr<Material> material_;
355     /// Number of particles.
356     unsigned numParticles_;
357     /// Update when invisible flag.
358     bool updateInvisible_;
359     /// Billboards relative flag.
360     bool relative_;
361     /// Scale affects billboard scale flag.
362     bool scaled_;
363     /// Billboards sorted flag.
364     bool sorted_;
365     /// Billboards fixed screen size flag.
366     bool fixedScreenSize_;
367     /// Animation LOD bias.
368     float animationLodBias_;
369     /// Emitter shape.
370     EmitterType emitterType_;
371     /// Emitter size.
372     Vector3 emitterSize_;
373     /// Particle direction minimum.
374     Vector3 directionMin_;
375     /// Particle direction maximum.
376     Vector3 directionMax_;
377     /// Particle constant force.
378     Vector3 constantForce_;
379     /// Particle velocity damping force.
380     float dampingForce_;
381     /// Active period.
382     float activeTime_;
383     /// Inactive period.
384     float inactiveTime_;
385     /// Particles per second minimum.
386     float emissionRateMin_;
387     /// Particles per second maximum.
388     float emissionRateMax_;
389     /// Particle size minimum.
390     Vector2 sizeMin_;
391     /// Particle size maximum.
392     Vector2 sizeMax_;
393     /// Particle time to live minimum.
394     float timeToLiveMin_;
395     /// Particle time to live maximum.
396     float timeToLiveMax_;
397     /// Particle velocity minimum.
398     float velocityMin_;
399     /// Particle velocity maximum.
400     float velocityMax_;
401     /// Particle rotation angle minimum.
402     float rotationMin_;
403     /// Particle rotation angle maximum.
404     float rotationMax_;
405     /// Particle rotation speed minimum.
406     float rotationSpeedMin_;
407     /// Particle rotation speed maximum.
408     float rotationSpeedMax_;
409     /// Particle size additive parameter.
410     float sizeAdd_;
411     /// Particle size multiplicative parameter.
412     float sizeMul_;
413     /// Particle color animation frames.
414     Vector<ColorFrame> colorFrames_;
415     /// Texture animation frames.
416     Vector<TextureFrame> textureFrames_;
417     /// Material name acquired during BeginLoad().
418     String loadMaterialName_;
419     /// Particle rotation mode in relation to the camera.
420     FaceCameraMode faceCameraMode_;
421 };
422 
423 }
424