[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / public-api / particle-system / particle-list.h
1 #ifndef DALI_TOOLKIT_PARTICLE_SYSTEM_PARTICLE_LIST_H
2 #define DALI_TOOLKIT_PARTICLE_SYSTEM_PARTICLE_LIST_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.h>
22
23 // EXTERNAL INCLUDES
24 #include <dali/public-api/common/list-wrapper.h>
25 #include <dali/public-api/object/base-handle.h>
26 #include <cinttypes>
27
28 namespace Dali::Toolkit::ParticleSystem::Internal
29 {
30 class ParticleList;
31 }
32
33 namespace Dali::Toolkit::ParticleSystem
34 {
35 /**
36  * The function is a wrapper needed to retrieve data type enum through template
37  */
38 template<class T>
39 struct StreamDataTypeWrapper
40 {
41   static ParticleStream::StreamDataType GetType()
42   {
43     return {};
44   }
45 };
46
47 /**
48  * @class ParticleList
49  *
50  * ParticleList defines a storage or a partial view on an existing storage of particle-related data.
51  *
52  * ParticleList contains streams of data (properties) laid out independently (non-interleaved).
53  *
54  * The layout is more optimal for:
55  * - parallel processing
56  * - data-oriented processing (CPU-cache friendly)
57  * - adding custom streams of data (for example, physics properties)
58  *
59  * Some streams are being added automatically by the emitter when certain modifiers are being added.
60  * If the modifier requires particular data it the emitter will update the list with proper stream.
61  *
62  * There are several built-in streams defined:
63  * - POSITION
64  * - VELOCITY
65  * - COLOR
66  * - OPACITY
67  * - SIZE
68  *
69  * The New() function allows adding streams upon creation.
70  *
71  * Custom streams may be used by custom renderers, modifiers and sources but also may play
72  * a role of temporary storage space when it comes to computing particle parameters.
73  *
74  * Represents all or subset of group of particles
75  */
76 class DALI_TOOLKIT_API ParticleList : public Dali::BaseHandle
77 {
78 public:
79   /**
80    * @brief Constructor
81    */
82   ParticleList();
83
84   /**
85    * @brief Bit flags grouping built-in particle streams by type
86    */
87   struct ParticleStreamTypeFlags
88   {
89     ParticleStreamTypeFlags(const ParticleStreamTypeFlags& flags)
90     {
91       value = flags.value;
92     }
93
94     ParticleStreamTypeFlags(const ParticleStreamTypeFlagBit& bit)
95     : value(bit)
96     {
97     }
98
99     ParticleStreamTypeFlags& operator|=(ParticleStreamTypeFlagBit flagBit)
100     {
101       value |= flagBit;
102       return *this;
103     }
104
105     ParticleStreamTypeFlags operator&(ParticleStreamTypeFlagBit flagBit)
106     {
107       return (value & flagBit);
108     }
109
110     explicit operator uint32_t() const
111     {
112       return value;
113     }
114
115     explicit operator bool() const
116     {
117       return value;
118     }
119
120     uint32_t value;
121   };
122
123   /**
124    * @brief Creates new ParticleList
125    *
126    * ParticleList is a storage object that contains data for particle system
127    * layouted as an array of streams.
128    *
129    * Stream may contain data like position, velocity, etc.
130    *
131    * When new ParticleList is created the default streams can be pre-allocated.
132    *
133    * @param[in] capacity Maximum capacity (number of particles in the system)
134    * @param[in] defaultStreams Default data streams to pre-allocate
135    */
136   static ParticleList New(uint32_t capacity, const ParticleStreamTypeFlags& defaultStreams);
137
138   /**
139    * @brief Downcasts a handle to ParticleList handle.
140    *
141    * If handle points to an ParticleList object, the downcast produces valid handle.
142    * If not, the returned handle is left uninitialized.
143    *
144    * @param[in] handle to An object
145    * @return handle to a ParticleList object or an uninitialized handle
146    */
147   static ParticleList DownCast(BaseHandle handle);
148
149   /**
150    * @brief Registers new data-stream with given unique identifier
151    *
152    * @tparam T Type of data stored in the stream
153    * @param[in] defaults Default value of the stream uninitialized data
154    *
155    * Streams added using AddStream() function are automatically passed into
156    * the shader program as input attributes.
157    *
158    * If there is no need for the stream to be used as a shader attribute
159    * then use AddLocalStream() instead.
160    *
161    * @return Returns index of an allocated data stream
162    */
163   template<class T>
164   inline uint32_t AddStream(T defaults)
165   {
166     return AddStream(&defaults, StreamDataTypeWrapper<T>::GetType(), sizeof(T), false);
167   }
168
169   /**
170    * @brief Adds local data stream
171    *
172    * @tparam T Type of data stored in the stream
173    * @param[in] defaults Default value of the stream
174    *
175    * @return Returns index of newly allocated data stream
176    */
177   template<class T>
178   inline uint32_t AddLocalStream(T defaults)
179   {
180     return AddStream(&defaults, sizeof(T), StreamDataTypeWrapper<T>::GetType(), true);
181   }
182
183   template<class T>
184   T* GetStream(uint32_t streamIndex)
185   {
186     return reinterpret_cast<T*>(GetRawStream(streamIndex));
187   }
188
189   template<class T>
190   T* GetDefaultStream(ParticleStreamTypeFlagBit streamFlagBit)
191   {
192     return reinterpret_cast<T*>(GetDefaultStream(streamFlagBit));
193   }
194
195   /**
196    * @brief Returns size of list including only active particles
197    *
198    * @return
199    */
200   uint32_t GetActiveParticleCount();
201
202   /**
203    * @brief Returns capacity of particle list
204    */
205   [[nodiscard]] uint32_t GetCapacity() const;
206
207   /**
208    * Creates new particle in the list with specified lifetime
209    *
210    * @param[in] lifetime Expected lifetime of new particle (0.0f - lives forever)
211    * @return index into data streams
212    */
213   Particle NewParticle(float lifetime);
214
215   /**
216    * @brief Returns internal data size of streams
217    *
218    * @param[in] includeLocalStreams If true, the size will include local streams
219    * @return Size of data structure
220    */
221   uint32_t GetParticleDataSize(bool includeLocalStreams);
222
223   /**
224    * @brief Returns index associated with specified default stream
225    *
226    * @param[in] defaultStreamBit Default stream bit
227    * @return Returns a valid index or -1 on error.
228    */
229   int GetDefaultStreamIndex(ParticleStreamTypeFlagBit defaultStreamBit);
230
231   std::list<Particle>& GetActiveParticles();
232
233 private:
234   /// @cond internal
235   /**
236    * @brief Adds new data stream to the list
237    *
238    * @param[in] defaults Default values to fill the stream with
239    * @param[in] dataTypeSize size of stored data type
240    * @param[in] dataType Stream data type
241    * @param[in] localStream Flag indicating whether stream is local (not used in shaders) or not
242    * @return Index of new stream
243    */
244   uint32_t
245   AddStream(void* defaults, size_t dataTypeSize, ParticleStream::StreamDataType dataType, bool localStream);
246   /// @endcond
247
248   /// @cond internal
249   /**
250    * @brief Returns raw data pointer to the stream at given index
251    *
252    * @param[in] streamIndex Stream index
253    *
254    * @return Valid data pointer or nullptr if index invalid
255    */
256   void* GetRawStream(uint32_t streamIndex);
257   /// @endcond
258
259   /// @cond internal
260   /**
261    * @brief Returns raw data stream of a default (built-in) stream
262    * @param[in] streamBit Bit (ParticleStreamTypeFlagBit) representing the stream
263    *
264    * @return Returns valid pointer to the data or nullptr if stream hasn't been used
265    */
266   void* GetDefaultStream(ParticleStreamTypeFlagBit streamBit);
267   /// @endcond
268
269   /// @cond internal
270   /**
271    * @brief This constructor is used by ParticleList::New() methods.
272    *
273    * @param [in] impl A pointer to a newly allocated implementation
274    */
275   ParticleList(Dali::Toolkit::ParticleSystem::Internal::ParticleList* impl);
276   /// @endcond
277 };
278
279 } // namespace Dali::Toolkit::ParticleSystem
280
281 #endif