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