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