[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / public-api / particle-system / particle-emitter.h
1 #ifndef DALI_TOOLKIT_PARTICLE_SYSTEM_PARTICLE_EMITTER_H
2 #define DALI_TOOLKIT_PARTICLE_SYSTEM_PARTICLE_EMITTER_H
3 /*
4  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 // INTERNAL INCLUDES
21 #include <dali-toolkit/public-api/particle-system/particle-types.h>
22
23 // EXTERNAL INCLUDES
24 #include <dali/public-api/actors/actor.h>
25 #include <dali/public-api/object/base-handle.h>
26 #include <memory>
27
28 namespace Dali::Toolkit::ParticleSystem::Internal
29 {
30 class ParticleEmitter;
31 }
32
33 namespace Dali::Toolkit::ParticleSystem
34 {
35 class ParticleSource;
36
37 class ParticleDomain;
38
39 class ParticleList;
40
41 class ParticleModifier;
42
43 class ParticleRenderer;
44
45 /**
46  * @class ParticleEmitter
47  *
48  * ParticleEmitter manages a particle emission process. The primary function
49  * of the particle emitter class is to emit particles into a simulated environment.
50  *
51  * ParticleEmitter is responsible for:
52
53  * - Particle generation:
54  *
55  * The emitter generates particles with specific initial properties,
56  * such as position, velocity, size etc. It can create particles various ways which can be
57  * implemented by overriding ParticleSourceInterface. It may create particles in bursts, streams
58  * or in response to specific events. The ParticleSource must be set in order to generate particles
59  * in the system.
60  *
61  * - Particle simulation:
62  *
63  * The emitter updates state of each particle by invoking ParticleModifier stack. It updates particles
64  * over time to simulate desired behaviour. Particle modifiers may apply modifications to the system like
65  * applying forces (gravity, wind), integrating physics.
66  *
67  * The stack of modifiers is executed in order and output of previous modifier is an input of
68  * next one.
69  *
70  * At least one ParticleModifier must be set in order to update particle system and run
71  * the simulation.
72  *
73  * - Particle rendering
74  *
75  * ParticleRenderer must be set in order to render particles. The basic renderer renders only 2D billboard
76  * projected (always facing the camera) particles however the behaviour can be altered in order to render
77  * more complex systems.
78  *
79  * Rendering may be optimize for different graphics APIs.
80  *
81  * - Particle management
82  *
83  * The emitter manages the lifecycle of particles, including creation (via ParticleSource),
84  * update (via ParticleModifier stack) and removal (modifiers and specified lifetime of particles). It
85  * handles scenarios such as recycling particles that have reached the end of their lifespan, reusing them,
86  * or dynamically adjusting their properties based on the emitter's parameters or external factors.
87  *
88  * The particles are stored as ParticleList object which is generated internally. The emitter controls
89  * behaviour of the particle list.
90  *
91  * The basic components making the Particle System are:
92  * - ParticleEmitter - responsible for controlling the emission
93  * - ParticleSource - responsible for generating new particles in the system
94  * - ParticleModifier - responsible for altering the behaviour of particles (updates) and controlling the lifetime
95  * - ParticleRenderer - responsible for rendering the particle system
96  * - ParticleList - storage for particle data
97  * - Particle - view on a selected particle data
98  * - ParticleDomain - the domain of particle system (area/volume) that particle system is bound within
99  *
100  */
101 class DALI_TOOLKIT_API ParticleEmitter : public Dali::BaseHandle
102 {
103 public:
104   /**
105    * @brief Enum describing status of emitter
106    */
107   enum class Status
108   {
109     INCOMPLETE, ///< Status set when not all data is set in order to run simulation
110     READY,      ///< Emitter ready (fully set up)
111     STARTED,    ///< Emitter started
112     PAUSED,     ///< Emitter paused
113     STOPPED     ///< Emitter stopped
114   };
115
116   /**
117    * @brief Creates new ParticleEmitter
118    *
119    * Function creates new ParticleEmitter object with given initial specification.
120    *
121    * @return valid emitter object
122    */
123   static ParticleEmitter New();
124
125   /**
126    * @brief Downcasts a handle to ParticleEmitter handle.
127    *
128    * If handle points to an ParticleEmitter object, the downcast produces valid handle.
129    * If not, the returned handle is left uninitialized.
130    *
131    * @param[in] handle to An object
132    * @return handle to a ParticleEmitter object or an uninitialized handle
133    */
134   static ParticleEmitter DownCast(BaseHandle handle);
135
136   /**
137    * @brief Enables parallel processing on the CPU
138    *
139    * This flag gives a hint to attached ParticleSystem objects to use
140    * multiple threads if possible.
141    *
142    * Setting this hint may have no effect after the particle system started
143    * simulation. It should be set before calling Start() function.
144    *
145    * @param[in] enabled if True it will try to use MT
146    */
147   void EnableParallelProcessing(bool enabled);
148
149   /**
150    * @brief Tests whether parallel processing is enabled
151    *
152    * @return True if parallel processing mode is enabled.
153    */
154   [[nodiscard]] bool IsParallelProcessingEnabled() const;
155
156   /**
157    * @brief Sets emitter source
158    *
159    * ParticleSource represents objects responsible for emitting
160    * new particles as well as reusing expired particles.
161    *
162    * @param[in] particleSource valid particle emitter source object
163    *
164    */
165   void SetSource(const ParticleSource& particleSource);
166
167   /**
168    * @brief Returns currently used particle emitter source
169    *
170    * @return Handle to the ParticleSource object
171    */
172   [[nodiscard]] ParticleSource GetSource() const;
173
174   /**
175    * @brief Sets emitter domain
176    *
177    * ParticleDomain encloses the area of particle emission.
178    *
179    * @param[in] particleDomain valid particle emitter domain
180    */
181   void SetDomain(const ParticleDomain& particleDomain);
182
183   /**
184    * @brief Sets emitter domain
185    *
186    * ParticleRenderer provides implementation for rendering set of particles
187    *
188    * @param[in] particleRenderer a valid instance of ParticleRenderer
189    */
190   void SetRenderer(const ParticleRenderer& particleRenderer);
191
192   /**
193    * @brief Sets maximum particle count in the system
194    *
195    * This value is mutable but changing number of particles will
196    * force regenerating the whole system data!
197    *
198    * @param[in] maxParticleCount maximum number of particles in the system
199    */
200   void SetParticleCount(uint32_t maxParticleCount);
201
202   /**
203    * @brief Returns maximum number of particles in the system
204    *
205    * @return Maximum number of particles
206    */
207   uint32_t GetParticleCount();
208
209   /**
210    * @brief Returns currently used particle emitter domain
211    *
212    * @return Handle to the ParticleDomain object
213    */
214   [[nodiscard]] ParticleDomain GetDomain() const;
215
216   /**
217    * @brief Returns currently used particle emitter renderer
218    *
219    * @return Handle to the ParticleRenderer object
220    */
221   [[nodiscard]] ParticleRenderer GetRenderer() const;
222
223   /**
224    * @brief Attaches particle system to an actor
225    *
226    * @param[in] actor actor to attach the particle system
227    */
228   void AttachTo(Actor actor);
229
230   /**
231    * @brief Adds new modifier
232    * @param[in] particleMmodifier valid ParticleModifier object
233    *
234    * @return Index into the modifier stack associated with added modifier
235    */
236   uint32_t AddModifier(const ParticleModifier& particleMmodifier);
237
238   /**
239    * @brief Sets particle emission rate per second
240    *
241    * @param[in] ratePerSecond maximum number of particles emitted per second
242    */
243   void SetEmissionRate(uint32_t ratePerSecond);
244
245   /**
246    * @brief Returns emission rate per second
247    *
248    * @return Value of emission rate
249    */
250   [[nodiscard]] uint32_t GetEmissionRate() const;
251
252   /**
253    * @brief number of particles to be emitted on start of the emitter
254    *
255    * @param[in] count Initial count of particles in the system
256    */
257   void SetInitialParticleCount(uint32_t count);
258
259   /**
260    * @brief returns number of particles being emitted on start of the emitter
261    *
262    * @return number of particles
263    */
264   [[nodiscard]] uint32_t GetInitialParticleCount() const;
265
266   /**
267    * @brief Sets maximum number of particles alive
268    *
269    * This function limits number of active particles in the system.
270    *
271    * If set to 0, there is no limit.
272    *
273    * If set to non-zero, if the system reaches limit, no new particles
274    * will spawn until some of them die.
275    *
276    * @param[in] count Limit of active particles
277    */
278   void SetActiveParticlesLimit(uint32_t count);
279
280   /**
281    * @brief Returns active particles limit
282    *
283    * @return Number of active particles system is limited to
284    */
285   [[nodiscard]] uint32_t GetActiveParticlesLimit() const;
286
287   /**
288    * @brief Returns modifier in stack
289    *
290    * @param[in] index Index of modifier
291    * @return Returns valid pointer to the modifier or nullptr
292    */
293   ParticleModifier GetModifierAt(uint32_t index);
294
295   /**
296    * @brief Removes modifier at specified index
297    *
298    * @param[in] index of modifier to be removed
299    */
300   void RemoveModifierAt(uint32_t index);
301
302   /**
303    * @brief Returns ParticleList object
304    *
305    * @return Valid reference to the ParticleList
306    */
307   ParticleList& GetParticleList();
308
309   /**
310    * @brief Starts emitting particles
311    */
312   void Start();
313
314   /**
315    * @brief Stops emitting particles
316    */
317   void Stop();
318
319   /**
320    * @brief Returns current emitter status
321    *
322    * @return Current emitter status
323    */
324   [[nodiscard]] Status GetStatus() const;
325
326   /**
327    * @brief Constructor
328    */
329   ParticleEmitter() = default;
330
331 private:
332   /// @cond internal
333   /**
334    * @brief This constructor is used by ParticleEmitter::New() methods.
335    *
336    * @param [in] impl A pointer to a newly allocated implementation
337    */
338   ParticleEmitter(Dali::Toolkit::ParticleSystem::Internal::ParticleEmitter* impl);
339   /// @endcond
340 };
341 } // namespace Dali::Toolkit::ParticleSystem
342
343 #endif // DALI_TOOLKIT_PARTICLE_SYSTEM_PARTICLE_EMITTER_H