1 #ifndef DALI_TOOLKIT_PARTICLE_SYSTEM_PARTICLE_EMITTER_H
2 #define DALI_TOOLKIT_PARTICLE_SYSTEM_PARTICLE_EMITTER_H
4 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <dali-toolkit/public-api/particle-system/particle-types.h>
24 #include <dali/public-api/actors/actor.h>
25 #include <dali/public-api/object/base-handle.h>
28 namespace Dali::Toolkit::ParticleSystem::Internal
30 class ParticleEmitter;
33 namespace Dali::Toolkit::ParticleSystem
41 class ParticleModifier;
43 class ParticleRenderer;
46 * @class ParticleEmitter
48 * ParticleEmitter manages a particle emission process. The primary function
49 * of the particle emitter class is to emit particles into a simulated environment.
51 * ParticleEmitter is responsible for:
53 * - Particle generation:
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
61 * - Particle simulation:
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.
67 * The stack of modifiers is executed in order and output of previous modifier is an input of
70 * At least one ParticleModifier must be set in order to update particle system and run
73 * - Particle rendering
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.
79 * Rendering may be optimize for different graphics APIs.
81 * - Particle management
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.
88 * The particles are stored as ParticleList object which is generated internally. The emitter controls
89 * behaviour of the particle list.
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
101 class DALI_TOOLKIT_API ParticleEmitter : public Dali::BaseHandle
105 * @brief Enum describing status of emitter
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
117 * @brief Creates new ParticleEmitter
119 * Function creates new ParticleEmitter object with given initial specification.
121 * @return valid emitter object
123 static ParticleEmitter New();
126 * @brief Downcasts a handle to ParticleEmitter handle.
128 * If handle points to an ParticleEmitter object, the downcast produces valid handle.
129 * If not, the returned handle is left uninitialized.
131 * @param[in] handle to An object
132 * @return handle to a ParticleEmitter object or an uninitialized handle
134 static ParticleEmitter DownCast(BaseHandle handle);
137 * @brief Enables parallel processing on the CPU
139 * This flag gives a hint to attached ParticleSystem objects to use
140 * multiple threads if possible.
142 * Setting this hint may have no effect after the particle system started
143 * simulation. It should be set before calling Start() function.
145 * @param[in] enabled if True it will try to use MT
147 void EnableParallelProcessing(bool enabled);
150 * @brief Tests whether parallel processing is enabled
152 * @return True if parallel processing mode is enabled.
154 [[nodiscard]] bool IsParallelProcessingEnabled() const;
157 * @brief Sets emitter source
159 * ParticleSource represents objects responsible for emitting
160 * new particles as well as reusing expired particles.
162 * @param[in] particleSource valid particle emitter source object
165 void SetSource(const ParticleSource& particleSource);
168 * @brief Returns currently used particle emitter source
170 * @return Handle to the ParticleSource object
172 [[nodiscard]] ParticleSource GetSource() const;
175 * @brief Sets emitter domain
177 * ParticleDomain encloses the area of particle emission.
179 * @param[in] particleDomain valid particle emitter domain
181 void SetDomain(const ParticleDomain& particleDomain);
184 * @brief Sets emitter domain
186 * ParticleRenderer provides implementation for rendering set of particles
188 * @param[in] particleRenderer a valid instance of ParticleRenderer
190 void SetRenderer(const ParticleRenderer& particleRenderer);
193 * @brief Sets maximum particle count in the system
195 * This value is mutable but changing number of particles will
196 * force regenerating the whole system data!
198 * @param[in] maxParticleCount maximum number of particles in the system
200 void SetParticleCount(uint32_t maxParticleCount);
203 * @brief Returns maximum number of particles in the system
205 * @return Maximum number of particles
207 uint32_t GetParticleCount();
210 * @brief Returns currently used particle emitter domain
212 * @return Handle to the ParticleDomain object
214 [[nodiscard]] ParticleDomain GetDomain() const;
217 * @brief Returns currently used particle emitter renderer
219 * @return Handle to the ParticleRenderer object
221 [[nodiscard]] ParticleRenderer GetRenderer() const;
224 * @brief Attaches particle system to an actor
226 * @param[in] actor actor to attach the particle system
228 void AttachTo(Actor actor);
231 * @brief Adds new modifier
232 * @param[in] particleMmodifier valid ParticleModifier object
234 * @return Index into the modifier stack associated with added modifier
236 uint32_t AddModifier(const ParticleModifier& particleMmodifier);
239 * @brief Sets particle emission rate per second
241 * @param[in] ratePerSecond maximum number of particles emitted per second
243 void SetEmissionRate(uint32_t ratePerSecond);
246 * @brief Returns emission rate per second
248 * @return Value of emission rate
250 [[nodiscard]] uint32_t GetEmissionRate() const;
253 * @brief number of particles to be emitted on start of the emitter
255 * @param[in] count Initial count of particles in the system
257 void SetInitialParticleCount(uint32_t count);
260 * @brief returns number of particles being emitted on start of the emitter
262 * @return number of particles
264 [[nodiscard]] uint32_t GetInitialParticleCount() const;
267 * @brief Sets maximum number of particles alive
269 * This function limits number of active particles in the system.
271 * If set to 0, there is no limit.
273 * If set to non-zero, if the system reaches limit, no new particles
274 * will spawn until some of them die.
276 * @param[in] count Limit of active particles
278 void SetActiveParticlesLimit(uint32_t count);
281 * @brief Returns active particles limit
283 * @return Number of active particles system is limited to
285 [[nodiscard]] uint32_t GetActiveParticlesLimit() const;
288 * @brief Returns modifier in stack
290 * @param[in] index Index of modifier
291 * @return Returns valid pointer to the modifier or nullptr
293 ParticleModifier GetModifierAt(uint32_t index);
296 * @brief Removes modifier at specified index
298 * @param[in] index of modifier to be removed
300 void RemoveModifierAt(uint32_t index);
303 * @brief Returns ParticleList object
305 * @return Valid reference to the ParticleList
307 ParticleList& GetParticleList();
310 * @brief Starts emitting particles
315 * @brief Stops emitting particles
320 * @brief Returns current emitter status
322 * @return Current emitter status
324 [[nodiscard]] Status GetStatus() const;
329 ParticleEmitter() = default;
334 * @brief This constructor is used by ParticleEmitter::New() methods.
336 * @param [in] impl A pointer to a newly allocated implementation
338 ParticleEmitter(Dali::Toolkit::ParticleSystem::Internal::ParticleEmitter* impl);
341 } // namespace Dali::Toolkit::ParticleSystem
343 #endif // DALI_TOOLKIT_PARTICLE_SYSTEM_PARTICLE_EMITTER_H