Level up Dali::Internal::FreeList as Dali::FreeList
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / transform-manager.h
1 #ifndef DALI_INTERNAL_TRANSFORM_MANAGER_H
2 #define DALI_INTERNAL_TRANSFORM_MANAGER_H
3
4 /*
5  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/devel-api/common/free-list.h>
23 #include <dali/public-api/common/constants.h>
24 #include <dali/public-api/common/dali-vector.h>
25 #include <dali/public-api/math/matrix.h>
26 #include <dali/public-api/math/quaternion.h>
27 #include <dali/public-api/math/vector3.h>
28
29 namespace Dali
30 {
31 namespace Internal
32 {
33 namespace SceneGraph
34 {
35 /**
36  * Struct to store the animatable part of a component (Scale, orientation and position)
37  */
38 struct TransformComponentAnimatable
39 {
40   TransformComponentAnimatable()
41   : mScale(Vector3::ONE),
42     mOrientation(Quaternion::IDENTITY),
43     mPosition(Vector3::ZERO)
44   {
45   }
46
47   Vector3    mScale;
48   Quaternion mOrientation;
49   Vector3    mPosition;
50 };
51
52 /**
53  * Struct to store the non-animatable part of a component (AnchorPoint and ParentOrigin)
54  */
55 struct TransformComponentStatic
56 {
57   TransformComponentStatic()
58   : mAnchorPoint(AnchorPoint::DEFAULT),
59     mParentOrigin(ParentOrigin::DEFAULT),
60     mPositionUsesAnchorPoint(true)
61   {
62   }
63
64   Vector3 mAnchorPoint;
65   Vector3 mParentOrigin;
66   bool    mPositionUsesAnchorPoint;
67 };
68
69 enum InheritanceMode
70 {
71   DONT_INHERIT_TRANSFORM = 0,
72   INHERIT_POSITION       = 1,
73   INHERIT_SCALE          = 2,
74   INHERIT_ORIENTATION    = 4,
75   INHERIT_ALL            = INHERIT_POSITION | INHERIT_SCALE | INHERIT_ORIENTATION,
76 };
77
78 enum TransformManagerProperty
79 {
80   TRANSFORM_PROPERTY_POSITION = 0,
81   TRANSFORM_PROPERTY_SCALE,
82   TRANSFORM_PROPERTY_ANCHOR_POINT,
83   TRANSFORM_PROPERTY_PARENT_ORIGIN,
84   TRANSFORM_PROPERTY_SIZE,
85   TRANSFORM_PROPERTY_WORLD_POSITION,
86   TRANSFORM_PROPERTY_WORLD_SCALE,
87   TRANSFORM_PROPERTY_WORLD_ORIENTATION,
88   TRANSFORM_PROPERTY_WORLD_MATRIX,
89   TRANSFORM_PROPERTY_COUNT,
90 };
91
92 using TransformId                             = uint32_t; // 4,294,967,295 transforms supported
93 static const TransformId INVALID_TRANSFORM_ID = -1;
94
95 class TransformManager;
96
97 struct TransformManagerData
98 {
99   TransformManager* Manager() const
100   {
101     return mManager;
102   }
103
104   TransformId Id() const
105   {
106     return mId;
107   }
108
109   TransformManager* mManager{nullptr};
110   TransformId       mId{INVALID_TRANSFORM_ID};
111 };
112
113 } // namespace SceneGraph
114 } // namespace Internal
115
116 // Allow TransformComponentAnimatable to be treated as a POD type
117 template<>
118 struct TypeTraits<Dali::Internal::SceneGraph::TransformComponentAnimatable> : public Dali::BasicTypes<Dali::Internal::SceneGraph::TransformComponentAnimatable>
119 {
120   enum
121   {
122     IS_TRIVIAL_TYPE = true
123   };
124 };
125
126 namespace Internal
127 {
128 namespace SceneGraph
129 {
130 /**
131  * Transform manager computes the local to world transformations
132  * of all the nodes in the scene. All the transformation data is stored contiguously
133  * in memory which minimizes cache misses during updates
134  */
135 class TransformManager
136 {
137 public:
138   /**
139    * Default constructor
140    */
141   TransformManager();
142
143   /**
144    * Class destructor
145    */
146   ~TransformManager();
147
148   /**
149    * Add a new transform component to the manager
150    * @return A TransformId used to access the component
151    */
152   TransformId CreateTransform();
153
154   /**
155    * Removes an existing transform component
156    * @param[in] id Id of the transform to remove
157    */
158   void RemoveTransform(TransformId id);
159
160   /**
161    * Sets the parent transform of an existing component
162    * @param[in] id Id of the transform
163    * @param[in] parentId Id of the new parent
164    */
165   void SetParent(TransformId id, TransformId parentId);
166
167   /**
168    * Gets the world transform matrix of an exisiting transform component
169    * @param[in] id Id of the transform component
170    * @return The local to world transformation matrix of the component
171    */
172   const Matrix& GetWorldMatrix(TransformId id) const;
173
174   /**
175    * Gets the world transform matrix of an exisiting transform component
176    * @param[in] id Id of the transform component
177    * @return The local to world transformation matrix of the component
178    */
179   Matrix& GetWorldMatrix(TransformId id);
180
181   /**
182    * Checks if the local transform was updated in the last Update
183    * @param[in] id Id of the transform
184    * @return true if local matrix changed in the last update, false otherwise
185    */
186   bool IsLocalMatrixDirty(TransformId id) const
187   {
188     return mLocalMatrixDirty[mIds[id]];
189   }
190
191   /**
192    * Sets position inheritance mode.
193    * @param[in] id Id of the transform
194    * @param[in] inherit True if position is inherited from parent, false otherwise
195    */
196   void SetInheritPosition(TransformId id, bool inherit);
197
198   /**
199    * Sets scale inheritance mode.
200    * @param[in] id Id of the transform
201    * @param[in] inherit True if scale is inherited from parent, false otherwise
202    */
203   void SetInheritScale(TransformId id, bool inherit);
204
205   /**
206    * Sets orientation inheritance mode.
207    * @param[in] id Id of the transform
208    * @param[in] inherit True if orientation is inherited from parent, false otherwise
209    */
210   void SetInheritOrientation(TransformId id, bool inherit);
211
212   /**
213    * Recomputes all world transform matrices
214    * @return true if any component has been changed in this frame, false otherwise
215    */
216   bool Update();
217
218   /**
219    * Resets all the animatable properties to its base value
220    */
221   void ResetToBaseValue();
222
223   /**
224    * Get the value of a Vector3 property
225    * @param[in] id Id of the transform component
226    * @param[in] property The property
227    */
228   Vector3& GetVector3PropertyValue(TransformId id, TransformManagerProperty property);
229
230   /**
231    * Get the value of a Vector3 property
232    * @param[in] id Id of the transform component
233    * @param[in] property The property
234    */
235   const Vector3& GetVector3PropertyValue(TransformId id, TransformManagerProperty property) const;
236
237   /**
238    * Get the value of a component of Vector3 property
239    * @param[in] id Id of the transform component
240    * @param[in] property The property
241    * param[in] component The component (0,1,2)
242    */
243   const float& GetVector3PropertyComponentValue(TransformId id, TransformManagerProperty property, uint32_t component) const;
244
245   /**
246    * Set the value of a Vector3 property
247    * @param[in] id Id of the transform component
248    * @param[in] property The property
249    * @param[in] value The new value
250    */
251   void SetVector3PropertyValue(TransformId id, TransformManagerProperty property, const Vector3& value);
252
253   /**
254    * Set the value of a component of a Vector3 property
255    * @param[in] id Id of the transform component
256    * @param[in] property The property
257    * @param[in] value The new value
258    * param[in] component The component (0,1,2)
259    */
260   void SetVector3PropertyComponentValue(TransformId id, TransformManagerProperty property, float value, uint32_t component);
261
262   /**
263    * Bakes the value of a Vector3 property
264    * @param[in] id Id of the transform component
265    * @param[in] property The property
266    * @param[in] value The new value
267    */
268   void BakeVector3PropertyValue(TransformId id, TransformManagerProperty property, const Vector3& value);
269
270   /**
271    * Bakes the value of a Vector3 property relative to the current value
272    * @param[in] id Id of the transform component
273    * @param[in] property The property
274    * @param[in] value The new value
275    */
276   void BakeRelativeVector3PropertyValue(TransformId id, TransformManagerProperty property, const Vector3& value);
277
278   /**
279    * Bakes the value of a Vector3 property by multiplying the current value and the new value
280    * @param[in] id Id of the transform component
281    * @param[in] property The property
282    * @param[in] value The new value
283    */
284   void BakeMultiplyVector3PropertyValue(TransformId id, TransformManagerProperty property, const Vector3& value);
285
286   /**
287    * Bakes the value of a component of Vector3 property
288    * @param[in] id Id of the transform component
289    * @param[in] property The property
290    * @param[in] value The new value
291    */
292   void BakeVector3PropertyComponentValue(TransformId id, TransformManagerProperty property, float value, uint32_t component);
293
294   /**
295    * Bakes the value of the x component of Vector3 property
296    * @param[in] id Id of the transform component
297    * @param[in] property The property
298    * @param[in] value The new value
299    */
300   void BakeXVector3PropertyValue(TransformId id, TransformManagerProperty property, float value);
301
302   /**
303    * Bakes the value of the y component of Vector3 property
304    * @param[in] id Id of the transform component
305    * @param[in] property The property
306    * @param[in] value The new value
307    */
308   void BakeYVector3PropertyValue(TransformId id, TransformManagerProperty property, float value);
309
310   /**
311    * Bakes the value of the z component of Vector3 property
312    * @param[in] id Id of the transform component
313    * @param[in] property The property
314    * @param[in] value The new value
315    */
316   void BakeZVector3PropertyValue(TransformId id, TransformManagerProperty property, float value);
317
318   /**
319    * Get the value of a quaternion property
320    * @param[in] id Id of the transform component
321    */
322   Quaternion& GetQuaternionPropertyValue(TransformId id);
323
324   /**
325    * Get the value of a quaternion property
326    * @param[in] id Id of the transform component
327    */
328   const Quaternion& GetQuaternionPropertyValue(TransformId id) const;
329
330   /**
331    * Set the value of a quaternion property
332    * @param[in] id Id of the transform component
333    * @param[in] q The new value
334    */
335   void SetQuaternionPropertyValue(TransformId id, const Quaternion& q);
336
337   /**
338    * Bake the value of a quaternion property
339    * @param[in] id Id of the transform component
340    * @param[in] q The new value
341    */
342   void BakeQuaternionPropertyValue(TransformId id, const Quaternion& q);
343
344   /**
345    * Bake the value of a quaternion property relative to its current value
346    * @param[in] id Id of the transform component
347    * @param[in] q The new value
348    */
349   void BakeRelativeQuaternionPropertyValue(TransformId id, const Quaternion& q);
350
351   /**
352    * Get the bounding sphere, in world coordinates, of a given component
353    * @param[in] id Id of the transform component
354    * @return The world space bounding sphere of the component
355    */
356   const Vector4& GetBoundingSphere(TransformId id) const;
357
358   /**
359    * Get the world matrix and size of a given component
360    * @param[in] id Id of the transform component
361    * @param[out] The world matrix of the component
362    * @param[out] size size of the component
363    */
364   void GetWorldMatrixAndSize(TransformId id, Matrix& worldMatrix, Vector3& size) const;
365
366   /**
367    * @brief Sets the boolean which states whether the position should use the anchor-point on the given transform component.
368    * @param[in] id Id of the transform component
369    * @param[in] value True if the position should use the anchor-point
370    */
371   void SetPositionUsesAnchorPoint(TransformId id, bool value);
372
373 private:
374   //Helper struct to order components
375   struct SOrderItem
376   {
377     bool operator<(const SOrderItem& item) const
378     {
379       if(sceneId != item.sceneId)
380       {
381         return sceneId < item.sceneId;
382       }
383       else
384       {
385         return level < item.level;
386       }
387     }
388
389     TransformId id;
390     uint16_t    sceneId;
391     uint16_t    level;
392   };
393
394   /**
395    * Swaps two components in the vectors
396    * @param[in] i Index of a component
397    * @param[in] j Index of a component
398    */
399   void SwapComponents(uint32_t i, uint32_t j);
400
401   /**
402    * Reorders components in hierarchical order so update can iterate sequentially
403    * updating the world transforms. The components are sorted in the breadth first
404    * order for each scene and grouped per scene.
405    */
406   void ReorderComponents();
407
408   uint32_t                             mComponentCount;                 ///< Total number of components
409   FreeList                             mIds;                            ///< FreeList of Ids
410   Vector<TransformComponentAnimatable> mTxComponentAnimatable;          ///< Animatable part of the components
411   Vector<TransformComponentStatic>     mTxComponentStatic;              ///< Static part of the components
412   Vector<uint32_t>                     mInheritanceMode;                ///< Inheritance mode of the components
413   Vector<TransformId>                  mComponentId;                    ///< Ids of the components
414   Vector<Vector3>                      mSize;                           ///< Size of the components
415   Vector<TransformId>                  mParent;                         ///< Parent of the components
416   Vector<Matrix>                       mWorld;                          ///< Local to world transform of the components
417   Vector<Matrix>                       mLocal;                          ///< Local to parent space transform of the components
418   Vector<Vector4>                      mBoundingSpheres;                ///< Bounding spheres. xyz is the center and w is the radius
419   Vector<TransformComponentAnimatable> mTxComponentAnimatableBaseValue; ///< Base values for the animatable part of the components
420   Vector<Vector3>                      mSizeBase;                       ///< Base value for the size of the components
421   Vector<bool>                         mComponentDirty;                 ///< 1u if some of the parts of the component has changed in this frame, 0 otherwise
422   Vector<bool>                         mLocalMatrixDirty;               ///< 1u if the local matrix has been updated in this frame, 0 otherwise
423   Vector<SOrderItem>                   mOrderedComponents;              ///< Used to reorder components when hierarchy changes
424   bool                                 mReorder;                        ///< Flag to determine if the components have to reordered in the next Update
425 };
426
427 } //namespace SceneGraph
428
429 } //namespace Internal
430
431 } //namespace Dali
432
433 #endif // DALI_INTERNAL_TRANSFORM_MANAGER_H