Seperate some matrix operations to MatrixUtils
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / transform-manager.cpp
1 /*
2  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/update/manager/transform-manager.h>
20
21 //EXTERNAL INCLUDES
22 #include <algorithm>
23 #include <cstring>
24 #include <type_traits>
25
26 //INTERNAL INCLUDES
27 #include <dali/internal/common/math.h>
28 #include <dali/internal/common/matrix-utils.h>
29 #include <dali/public-api/common/constants.h>
30
31 namespace Dali
32 {
33 namespace Internal
34 {
35 namespace SceneGraph
36 {
37 namespace
38 {
39 //Default values for scale (1.0,1.0,1.0), orientation (Identity) and position (0.0,0.0,0.0)
40 static const float gDefaultTransformComponentAnimatableData[] = {1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f};
41
42 //Default values for anchor point (CENTER) and parent origin (TOP_LEFT)
43 static const float gDefaultTransformComponentStaticData[] = {0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, true};
44
45 static_assert(sizeof(gDefaultTransformComponentAnimatableData) == sizeof(TransformComponentAnimatable), "gDefaultTransformComponentAnimatableData should have the same number of floats as specified in TransformComponentAnimatable");
46 static_assert(sizeof(gDefaultTransformComponentStaticData) == sizeof(TransformComponentStatic), "gDefaultTransformComponentStaticData should have the same number of floats as specified in TransformComponentStatic");
47
48 /**
49  * @brief Calculates the center position for the transform component
50  * @param[out] centerPosition The calculated center-position of the transform component
51  * @param[in] transformComponentStatic A const reference to the static component transform struct
52  * @param[in] transformComponentAnimatable A const reference to the animatable component transform struct
53  * @param[in] size The size of the current transform component
54  * @param[in] half Halfway point of the transform
55  * @param[in] topLeft The top-left coords of the transform
56  */
57 inline void CalculateCenterPosition(
58   Vector3&                            centerPosition,
59   const TransformComponentStatic&     transformComponentStatic,
60   const TransformComponentAnimatable& transformComponentAnimatable,
61   const Vector3&                      size,
62   const Vector3&                      half,
63   const Vector3&                      topLeft)
64 {
65   // Calculate the center-point by applying the scale and rotation on the anchor point.
66   centerPosition = (half - transformComponentStatic.mAnchorPoint) * size * transformComponentAnimatable.mScale;
67   centerPosition *= transformComponentAnimatable.mOrientation;
68
69   // If the position is ignoring the anchor-point, then remove the anchor-point shift from the position.
70   if(!transformComponentStatic.mPositionUsesAnchorPoint)
71   {
72     centerPosition -= (topLeft - transformComponentStatic.mAnchorPoint) * size;
73   }
74 }
75
76 } // unnamed namespace
77
78 TransformManager::TransformManager()
79 : mComponentCount(0),
80   mReorder(false)
81 {
82 }
83
84 TransformManager::~TransformManager() = default;
85
86 TransformId TransformManager::CreateTransform()
87 {
88   //Get id for the new component
89   TransformId id = mIds.Add(mComponentCount);
90
91   if(mTxComponentAnimatable.Size() <= mComponentCount)
92   {
93     //Make room for another component
94     mTxComponentAnimatable.PushBack(TransformComponentAnimatable());
95     mTxComponentStatic.PushBack(TransformComponentStatic());
96     mInheritanceMode.PushBack(INHERIT_ALL);
97     mComponentId.PushBack(id);
98     mSize.PushBack(Vector3(0.0f, 0.0f, 0.0f));
99     mParent.PushBack(INVALID_TRANSFORM_ID);
100     mWorld.PushBack(Matrix::IDENTITY);
101     mLocal.PushBack(Matrix::IDENTITY);
102     mBoundingSpheres.PushBack(Vector4(0.0f, 0.0f, 0.0f, 0.0f));
103     mTxComponentAnimatableBaseValue.PushBack(TransformComponentAnimatable());
104     mSizeBase.PushBack(Vector3(0.0f, 0.0f, 0.0f));
105     mComponentDirty.PushBack(false);
106     mLocalMatrixDirty.PushBack(false);
107   }
108   else
109   {
110     //Set default values
111     memcpy(&mTxComponentAnimatable[mComponentCount], &gDefaultTransformComponentAnimatableData, sizeof(TransformComponentAnimatable));
112     memcpy(&mTxComponentStatic[mComponentCount], &gDefaultTransformComponentStaticData, sizeof(TransformComponentStatic));
113     memcpy(&mTxComponentAnimatableBaseValue[mComponentCount], &gDefaultTransformComponentAnimatableData, sizeof(TransformComponentAnimatable));
114     mInheritanceMode[mComponentCount] = INHERIT_ALL;
115     mComponentId[mComponentCount]     = id;
116     mSize[mComponentCount]            = Vector3(0.0f, 0.0f, 0.0f);
117     mParent[mComponentCount]          = INVALID_TRANSFORM_ID;
118     mLocal[mComponentCount].SetIdentity();
119     mWorld[mComponentCount].SetIdentity();
120     mBoundingSpheres[mComponentCount]  = Vector4(0.0f, 0.0f, 0.0f, 0.0f);
121     mSizeBase[mComponentCount]         = Vector3(0.0f, 0.0f, 0.0f);
122     mComponentDirty[mComponentCount]   = false;
123     mLocalMatrixDirty[mComponentCount] = false;
124   }
125
126   mComponentCount++;
127   return id;
128 }
129
130 void TransformManager::RemoveTransform(TransformId id)
131 {
132   //Move the last element to the gap
133   mComponentCount--;
134   TransformId index                      = mIds[id];
135   mTxComponentAnimatable[index]          = mTxComponentAnimatable[mComponentCount];
136   mTxComponentStatic[index]              = mTxComponentStatic[mComponentCount];
137   mInheritanceMode[index]                = mInheritanceMode[mComponentCount];
138   mSize[index]                           = mSize[mComponentCount];
139   mParent[index]                         = mParent[mComponentCount];
140   mWorld[index]                          = mWorld[mComponentCount];
141   mLocal[index]                          = mLocal[mComponentCount];
142   mTxComponentAnimatableBaseValue[index] = mTxComponentAnimatableBaseValue[mComponentCount];
143   mSizeBase[index]                       = mSizeBase[mComponentCount];
144   mComponentDirty[index]                 = mComponentDirty[mComponentCount];
145   mLocalMatrixDirty[index]               = mLocalMatrixDirty[mComponentCount];
146   mBoundingSpheres[index]                = mBoundingSpheres[mComponentCount];
147
148   TransformId lastItemId = mComponentId[mComponentCount];
149   mIds[lastItemId]       = index;
150   mComponentId[index]    = lastItemId;
151   mIds.Remove(id);
152
153   mReorder = true;
154 }
155
156 void TransformManager::SetParent(TransformId id, TransformId parentId)
157 {
158   DALI_ASSERT_ALWAYS(id != parentId);
159   TransformId index      = mIds[id];
160   mParent[index]         = parentId;
161   mComponentDirty[index] = true;
162   mReorder               = true;
163 }
164
165 const Matrix& TransformManager::GetWorldMatrix(TransformId id) const
166 {
167   return mWorld[mIds[id]];
168 }
169
170 Matrix& TransformManager::GetWorldMatrix(TransformId id)
171 {
172   return mWorld[mIds[id]];
173 }
174
175 void TransformManager::SetInheritPosition(TransformId id, bool inherit)
176 {
177   TransformId index = mIds[id];
178   if(inherit)
179   {
180     mInheritanceMode[index] |= INHERIT_POSITION;
181   }
182   else
183   {
184     mInheritanceMode[index] &= ~INHERIT_POSITION;
185   }
186
187   mComponentDirty[index] = true;
188 }
189
190 void TransformManager::SetInheritScale(TransformId id, bool inherit)
191 {
192   TransformId index = mIds[id];
193   if(inherit)
194   {
195     mInheritanceMode[index] |= INHERIT_SCALE;
196   }
197   else
198   {
199     mInheritanceMode[index] &= ~INHERIT_SCALE;
200   }
201
202   mComponentDirty[index] = true;
203 }
204
205 void TransformManager::SetInheritOrientation(TransformId id, bool inherit)
206 {
207   TransformId index = mIds[id];
208   if(inherit)
209   {
210     mInheritanceMode[index] |= INHERIT_ORIENTATION;
211   }
212   else
213   {
214     mInheritanceMode[index] &= ~INHERIT_ORIENTATION;
215   }
216
217   mComponentDirty[index] = true;
218 }
219
220 void TransformManager::ResetToBaseValue()
221 {
222   if(mComponentCount)
223   {
224     memcpy(&mTxComponentAnimatable[0], &mTxComponentAnimatableBaseValue[0], sizeof(TransformComponentAnimatable) * mComponentCount);
225     memcpy(&mSize[0], &mSizeBase[0], sizeof(Vector3) * mComponentCount);
226     memset(&mLocalMatrixDirty[0], false, sizeof(bool) * mComponentCount);
227   }
228 }
229
230 bool TransformManager::Update()
231 {
232   bool componentsChanged = false;
233
234   if(mReorder)
235   {
236     //If some transform component has change its parent or has been removed since last update
237     //we need to reorder the vectors
238     ReorderComponents();
239     mReorder = false;
240   }
241
242   //Iterate through all components to compute its world matrix
243   Vector3       centerPosition;
244   Vector3       localPosition;
245   const Vector3 half(0.5f, 0.5f, 0.5f);
246   const Vector3 topLeft(0.0f, 0.0f, 0.5f);
247   for(unsigned int i(0); i < mComponentCount; ++i)
248   {
249     if(DALI_LIKELY(mInheritanceMode[i] != DONT_INHERIT_TRANSFORM && mParent[i] != INVALID_TRANSFORM_ID))
250     {
251       const TransformId& parentIndex = mIds[mParent[i]];
252       if(DALI_LIKELY(mInheritanceMode[i] == INHERIT_ALL))
253       {
254         if(mComponentDirty[i] || mLocalMatrixDirty[parentIndex])
255         {
256           //Full transform inherited
257           mLocalMatrixDirty[i] = true;
258           CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i], mSize[i], half, topLeft);
259           localPosition = mTxComponentAnimatable[i].mPosition + centerPosition + (mTxComponentStatic[i].mParentOrigin - half) * mSize[parentIndex];
260           mLocal[i].SetTransformComponents(mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, localPosition);
261         }
262
263         //Update the world matrix
264         MatrixUtils::Multiply(mWorld[i], mLocal[i], mWorld[parentIndex]);
265       }
266       else
267       {
268         //Some components are not inherited
269         Vector3       parentPosition, parentScale;
270         Quaternion    parentOrientation;
271         const Matrix& parentMatrix = mWorld[parentIndex];
272         parentMatrix.GetTransformComponents(parentPosition, parentOrientation, parentScale);
273
274         Vector3 localScale = mTxComponentAnimatable[i].mScale;
275         if((mInheritanceMode[i] & INHERIT_SCALE) == 0)
276         {
277           //Don't inherit scale
278           localScale /= parentScale;
279         }
280
281         Quaternion localOrientation(mTxComponentAnimatable[i].mOrientation);
282         if((mInheritanceMode[i] & INHERIT_ORIENTATION) == 0)
283         {
284           //Don't inherit orientation
285           parentOrientation.Invert();
286           localOrientation = parentOrientation * mTxComponentAnimatable[i].mOrientation;
287         }
288
289         Matrix localMatrix = mLocal[i];
290
291         if((mInheritanceMode[i] & INHERIT_POSITION) == 0)
292         {
293           //Don't inherit position
294           CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i], mSize[i], half, topLeft);
295           mLocal[i].SetTransformComponents(localScale, localOrientation, Vector3::ZERO);
296           MatrixUtils::Multiply(mWorld[i], mLocal[i], parentMatrix);
297           mWorld[i].SetTranslation(mTxComponentAnimatable[i].mPosition + centerPosition);
298         }
299         else
300         {
301           CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i], mSize[i], half, topLeft);
302           localPosition = mTxComponentAnimatable[i].mPosition + centerPosition + (mTxComponentStatic[i].mParentOrigin - half) * mSize[parentIndex];
303           mLocal[i].SetTransformComponents(localScale, localOrientation, localPosition);
304           MatrixUtils::Multiply(mWorld[i], mLocal[i], parentMatrix);
305         }
306
307         mLocalMatrixDirty[i] = mComponentDirty[i] || (localMatrix != mLocal[i]);
308       }
309     }
310     else //Component has no parent or doesn't inherit transform
311     {
312       Matrix localMatrix = mLocal[i];
313       CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i], mSize[i], half, topLeft);
314       localPosition = mTxComponentAnimatable[i].mPosition + centerPosition;
315       mLocal[i].SetTransformComponents(mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, localPosition);
316       mWorld[i]            = mLocal[i];
317       mLocalMatrixDirty[i] = mComponentDirty[i] || (localMatrix != mLocal[i]);
318     }
319
320     //Update the bounding sphere
321     Vec3 centerToEdge = {mSize[i].Length() * 0.5f, 0.0f, 0.0f};
322     Vec3 centerToEdgeWorldSpace;
323     TransformVector3(centerToEdgeWorldSpace, mWorld[i].AsFloat(), centerToEdge);
324
325     mBoundingSpheres[i]   = mWorld[i].GetTranslation();
326     mBoundingSpheres[i].w = Length(centerToEdgeWorldSpace);
327
328     componentsChanged  = componentsChanged || mComponentDirty[i];
329     mComponentDirty[i] = false;
330   }
331
332   return componentsChanged;
333 }
334
335 void TransformManager::SwapComponents(unsigned int i, unsigned int j)
336 {
337   std::swap(mTxComponentAnimatable[i], mTxComponentAnimatable[j]);
338   std::swap(mTxComponentStatic[i], mTxComponentStatic[j]);
339   std::swap(mInheritanceMode[i], mInheritanceMode[j]);
340   std::swap(mSize[i], mSize[j]);
341   std::swap(mParent[i], mParent[j]);
342   std::swap(mComponentId[i], mComponentId[j]);
343   std::swap(mTxComponentAnimatableBaseValue[i], mTxComponentAnimatableBaseValue[j]);
344   std::swap(mSizeBase[i], mSizeBase[j]);
345   std::swap(mLocal[i], mLocal[j]);
346   std::swap(mComponentDirty[i], mComponentDirty[j]);
347   std::swap(mBoundingSpheres[i], mBoundingSpheres[j]);
348   std::swap(mWorld[i], mWorld[j]);
349
350   mIds[mComponentId[i]] = i;
351   mIds[mComponentId[j]] = j;
352 }
353
354 void TransformManager::ReorderComponents()
355 {
356   mOrderedComponents.Resize(mComponentCount);
357
358   uint16_t    sceneId = 0u;
359   TransformId parentId;
360
361   // Create sceneId first
362   for(TransformId i = 0; i < mComponentCount; ++i)
363   {
364     mOrderedComponents[i].id    = mComponentId[i];
365     mOrderedComponents[i].level = 0u;
366
367     parentId = mParent[i];
368     if(parentId == INVALID_TRANSFORM_ID)
369     {
370       mOrderedComponents[i].sceneId = sceneId++;
371     }
372   }
373
374   // Propagate sceneId and level
375   for(TransformId i = 0; i < mComponentCount; ++i)
376   {
377     parentId = mParent[i];
378     while(parentId != INVALID_TRANSFORM_ID)
379     {
380       const uint32_t parentIndex = mIds[parentId];
381       ++mOrderedComponents[i].level;
382       mOrderedComponents[i].sceneId = mOrderedComponents[parentIndex].sceneId;
383       if(parentIndex < i)
384       {
385         // Parent information update done. We can reuse it.
386         mOrderedComponents[i].level += mOrderedComponents[parentIndex].level;
387         break;
388       }
389       else
390       {
391         parentId = mParent[parentIndex];
392       }
393     }
394   }
395
396   std::stable_sort(mOrderedComponents.Begin(), mOrderedComponents.End());
397   TransformId previousIndex = 0;
398   for(TransformId newIndex = 0; newIndex < mComponentCount - 1; ++newIndex)
399   {
400     previousIndex = mIds[mOrderedComponents[newIndex].id];
401     if(previousIndex != newIndex)
402     {
403       SwapComponents(previousIndex, newIndex);
404     }
405   }
406 }
407
408 Vector3& TransformManager::GetVector3PropertyValue(TransformId id, TransformManagerProperty property)
409 {
410   switch(property)
411   {
412     case TRANSFORM_PROPERTY_POSITION:
413     {
414       TransformId index(mIds[id]);
415       return mTxComponentAnimatable[index].mPosition;
416     }
417     case TRANSFORM_PROPERTY_SCALE:
418     {
419       TransformId index(mIds[id]);
420       return mTxComponentAnimatable[index].mScale;
421     }
422     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
423     {
424       TransformId index(mIds[id]);
425       return mTxComponentStatic[index].mParentOrigin;
426     }
427     case TRANSFORM_PROPERTY_ANCHOR_POINT:
428     {
429       TransformId index(mIds[id]);
430       return mTxComponentStatic[index].mAnchorPoint;
431     }
432     case TRANSFORM_PROPERTY_SIZE:
433     {
434       TransformId index(mIds[id]);
435       return mSize[index];
436     }
437     default:
438     {
439       DALI_ASSERT_ALWAYS(false);
440       return mTxComponentAnimatable[mIds[id]].mPosition;
441     }
442   }
443 }
444
445 const Vector3& TransformManager::GetVector3PropertyValue(TransformId id, TransformManagerProperty property) const
446 {
447   switch(property)
448   {
449     case TRANSFORM_PROPERTY_POSITION:
450     {
451       return mTxComponentAnimatable[mIds[id]].mPosition;
452     }
453     case TRANSFORM_PROPERTY_SCALE:
454     {
455       return mTxComponentAnimatable[mIds[id]].mScale;
456     }
457     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
458     {
459       return mTxComponentStatic[mIds[id]].mParentOrigin;
460     }
461     case TRANSFORM_PROPERTY_ANCHOR_POINT:
462     {
463       return mTxComponentStatic[mIds[id]].mAnchorPoint;
464     }
465     case TRANSFORM_PROPERTY_SIZE:
466     {
467       return mSize[mIds[id]];
468     }
469     default:
470     {
471       DALI_ASSERT_ALWAYS(false);
472       return mTxComponentAnimatable[mIds[id]].mPosition;
473     }
474   }
475 }
476
477 const float& TransformManager::GetVector3PropertyComponentValue(TransformId id, TransformManagerProperty property, unsigned int component) const
478 {
479   switch(property)
480   {
481     case TRANSFORM_PROPERTY_POSITION:
482     {
483       return mTxComponentAnimatable[mIds[id]].mPosition[component];
484     }
485     case TRANSFORM_PROPERTY_SCALE:
486     {
487       return mTxComponentAnimatable[mIds[id]].mScale[component];
488     }
489     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
490     {
491       return mTxComponentStatic[mIds[id]].mParentOrigin[component];
492     }
493     case TRANSFORM_PROPERTY_ANCHOR_POINT:
494     {
495       return mTxComponentStatic[mIds[id]].mAnchorPoint[component];
496     }
497     case TRANSFORM_PROPERTY_SIZE:
498     {
499       return mSize[mIds[id]][component];
500     }
501     default:
502     {
503       DALI_ASSERT_ALWAYS(false);
504       return mTxComponentAnimatable[mIds[id]].mPosition[component];
505     }
506   }
507 }
508
509 void TransformManager::SetVector3PropertyValue(TransformId id, TransformManagerProperty property, const Vector3& value)
510 {
511   TransformId index(mIds[id]);
512   mComponentDirty[index] = true;
513
514   switch(property)
515   {
516     case TRANSFORM_PROPERTY_POSITION:
517     {
518       mTxComponentAnimatable[index].mPosition = value;
519       break;
520     }
521     case TRANSFORM_PROPERTY_SCALE:
522     {
523       mTxComponentAnimatable[index].mScale = value;
524       break;
525     }
526     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
527     {
528       mTxComponentStatic[index].mParentOrigin = value;
529       break;
530     }
531     case TRANSFORM_PROPERTY_ANCHOR_POINT:
532     {
533       mTxComponentStatic[index].mAnchorPoint = value;
534       break;
535     }
536     case TRANSFORM_PROPERTY_SIZE:
537     {
538       mSize[index] = value;
539       break;
540     }
541     default:
542     {
543       DALI_ASSERT_ALWAYS(false);
544     }
545   }
546 }
547
548 void TransformManager::SetVector3PropertyComponentValue(TransformId id, TransformManagerProperty property, float value, unsigned int component)
549 {
550   TransformId index(mIds[id]);
551   mComponentDirty[index] = true;
552
553   switch(property)
554   {
555     case TRANSFORM_PROPERTY_POSITION:
556     {
557       mTxComponentAnimatable[index].mPosition[component] = value;
558       break;
559     }
560     case TRANSFORM_PROPERTY_SCALE:
561     {
562       mTxComponentAnimatable[index].mScale[component] = value;
563       break;
564     }
565     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
566     {
567       mTxComponentStatic[index].mParentOrigin[component] = value;
568       break;
569     }
570     case TRANSFORM_PROPERTY_ANCHOR_POINT:
571     {
572       mTxComponentStatic[index].mAnchorPoint[component] = value;
573       break;
574     }
575     case TRANSFORM_PROPERTY_SIZE:
576     {
577       mSize[index][component] = value;
578       break;
579     }
580     default:
581     {
582       DALI_ASSERT_ALWAYS(false);
583     }
584   }
585 }
586
587 void TransformManager::BakeVector3PropertyValue(TransformId id, TransformManagerProperty property, const Vector3& value)
588 {
589   TransformId index(mIds[id]);
590   mComponentDirty[index] = true;
591
592   switch(property)
593   {
594     case TRANSFORM_PROPERTY_POSITION:
595     {
596       mTxComponentAnimatable[index].mPosition = mTxComponentAnimatableBaseValue[index].mPosition = value;
597       break;
598     }
599     case TRANSFORM_PROPERTY_SCALE:
600     {
601       mTxComponentAnimatable[index].mScale = mTxComponentAnimatableBaseValue[index].mScale = value;
602       break;
603     }
604     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
605     {
606       mTxComponentStatic[index].mParentOrigin = value;
607       break;
608     }
609     case TRANSFORM_PROPERTY_ANCHOR_POINT:
610     {
611       mTxComponentStatic[index].mAnchorPoint = value;
612       break;
613     }
614     case TRANSFORM_PROPERTY_SIZE:
615     {
616       mSize[index] = mSizeBase[index] = value;
617       break;
618     }
619     default:
620     {
621       DALI_ASSERT_ALWAYS(false);
622     }
623   }
624 }
625
626 void TransformManager::BakeRelativeVector3PropertyValue(TransformId id, TransformManagerProperty property, const Vector3& value)
627 {
628   TransformId index(mIds[id]);
629   mComponentDirty[index] = true;
630
631   switch(property)
632   {
633     case TRANSFORM_PROPERTY_POSITION:
634     {
635       mTxComponentAnimatable[index].mPosition = mTxComponentAnimatableBaseValue[index].mPosition = mTxComponentAnimatable[index].mPosition + value;
636       break;
637     }
638     case TRANSFORM_PROPERTY_SCALE:
639     {
640       mTxComponentAnimatable[index].mScale = mTxComponentAnimatableBaseValue[index].mScale = mTxComponentAnimatable[index].mScale + value;
641       break;
642     }
643     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
644     {
645       mTxComponentStatic[index].mParentOrigin = mTxComponentStatic[index].mParentOrigin + value;
646       break;
647     }
648     case TRANSFORM_PROPERTY_ANCHOR_POINT:
649     {
650       mTxComponentStatic[index].mAnchorPoint = mTxComponentStatic[index].mAnchorPoint + value;
651       break;
652     }
653     case TRANSFORM_PROPERTY_SIZE:
654     {
655       mSize[index] = mSizeBase[index] = mSize[index] + value;
656       break;
657     }
658     default:
659     {
660       DALI_ASSERT_ALWAYS(false);
661     }
662   }
663 }
664
665 void TransformManager::BakeMultiplyVector3PropertyValue(TransformId id, TransformManagerProperty property, const Vector3& value)
666 {
667   TransformId index(mIds[id]);
668   mComponentDirty[index] = true;
669
670   switch(property)
671   {
672     case TRANSFORM_PROPERTY_POSITION:
673     {
674       mTxComponentAnimatable[index].mPosition = mTxComponentAnimatableBaseValue[index].mPosition = mTxComponentAnimatable[index].mPosition * value;
675       break;
676     }
677     case TRANSFORM_PROPERTY_SCALE:
678     {
679       mTxComponentAnimatable[index].mScale = mTxComponentAnimatableBaseValue[index].mScale = mTxComponentAnimatable[index].mScale * value;
680       break;
681     }
682     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
683     {
684       mTxComponentStatic[index].mParentOrigin = mTxComponentStatic[index].mParentOrigin * value;
685       break;
686     }
687     case TRANSFORM_PROPERTY_ANCHOR_POINT:
688     {
689       mTxComponentStatic[index].mAnchorPoint = mTxComponentStatic[index].mAnchorPoint * value;
690       break;
691     }
692     case TRANSFORM_PROPERTY_SIZE:
693     {
694       mSize[index] = mSizeBase[index] = mSize[index] * value;
695       break;
696     }
697     default:
698     {
699       DALI_ASSERT_ALWAYS(false);
700     }
701   }
702 }
703
704 void TransformManager::BakeVector3PropertyComponentValue(TransformId id, TransformManagerProperty property, float value, unsigned int component)
705 {
706   TransformId index(mIds[id]);
707   mComponentDirty[index] = true;
708
709   switch(property)
710   {
711     case TRANSFORM_PROPERTY_POSITION:
712     {
713       mTxComponentAnimatable[index].mPosition[component] = mTxComponentAnimatableBaseValue[index].mPosition[component] = value;
714       break;
715     }
716     case TRANSFORM_PROPERTY_SCALE:
717     {
718       mTxComponentAnimatable[index].mScale[component] = mTxComponentAnimatableBaseValue[index].mScale[component] = value;
719       break;
720     }
721     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
722     {
723       mTxComponentStatic[index].mParentOrigin[component] = value;
724       break;
725     }
726     case TRANSFORM_PROPERTY_ANCHOR_POINT:
727     {
728       mTxComponentStatic[index].mAnchorPoint[component] = value;
729       break;
730     }
731     case TRANSFORM_PROPERTY_SIZE:
732     {
733       mSize[index][component] = mSizeBase[index][component] = value;
734       break;
735     }
736     default:
737     {
738       DALI_ASSERT_ALWAYS(false);
739     }
740   }
741 }
742
743 void TransformManager::BakeXVector3PropertyValue(TransformId id, TransformManagerProperty property, float value)
744 {
745   TransformId index(mIds[id]);
746   mComponentDirty[index] = true;
747
748   switch(property)
749   {
750     case TRANSFORM_PROPERTY_POSITION:
751     {
752       mTxComponentAnimatable[index].mPosition.x = mTxComponentAnimatableBaseValue[index].mPosition.x = value;
753       break;
754     }
755     case TRANSFORM_PROPERTY_SCALE:
756     {
757       mTxComponentAnimatable[index].mScale.x = mTxComponentAnimatableBaseValue[index].mScale.x = value;
758       break;
759     }
760     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
761     {
762       mTxComponentStatic[index].mParentOrigin.x = value;
763       break;
764     }
765     case TRANSFORM_PROPERTY_ANCHOR_POINT:
766     {
767       mTxComponentStatic[index].mAnchorPoint.x = value;
768       break;
769     }
770     case TRANSFORM_PROPERTY_SIZE:
771     {
772       mSize[index].x = mSizeBase[index].x = value;
773       break;
774     }
775     default:
776     {
777       DALI_ASSERT_ALWAYS(false);
778     }
779   }
780 }
781
782 void TransformManager::BakeYVector3PropertyValue(TransformId id, TransformManagerProperty property, float value)
783 {
784   TransformId index(mIds[id]);
785   mComponentDirty[index] = true;
786
787   switch(property)
788   {
789     case TRANSFORM_PROPERTY_POSITION:
790     {
791       mTxComponentAnimatable[index].mPosition.y = mTxComponentAnimatableBaseValue[index].mPosition.y = value;
792       break;
793     }
794     case TRANSFORM_PROPERTY_SCALE:
795     {
796       mTxComponentAnimatable[index].mScale.y = mTxComponentAnimatableBaseValue[index].mScale.y = value;
797       break;
798     }
799     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
800     {
801       mTxComponentStatic[index].mParentOrigin.y = value;
802       break;
803     }
804     case TRANSFORM_PROPERTY_ANCHOR_POINT:
805     {
806       mTxComponentStatic[index].mAnchorPoint.y = value;
807       break;
808     }
809     case TRANSFORM_PROPERTY_SIZE:
810     {
811       mSize[index].y = mSizeBase[index].y = value;
812       break;
813     }
814     default:
815     {
816       DALI_ASSERT_ALWAYS(false);
817     }
818   }
819 }
820
821 void TransformManager::BakeZVector3PropertyValue(TransformId id, TransformManagerProperty property, float value)
822 {
823   TransformId index(mIds[id]);
824   mComponentDirty[index] = true;
825
826   switch(property)
827   {
828     case TRANSFORM_PROPERTY_POSITION:
829     {
830       mTxComponentAnimatable[index].mPosition.z = mTxComponentAnimatableBaseValue[index].mPosition.z = value;
831       break;
832     }
833     case TRANSFORM_PROPERTY_SCALE:
834     {
835       mTxComponentAnimatable[index].mScale.z = mTxComponentAnimatableBaseValue[index].mScale.z = value;
836       break;
837     }
838     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
839     {
840       mTxComponentStatic[index].mParentOrigin.z = value;
841       break;
842     }
843     case TRANSFORM_PROPERTY_ANCHOR_POINT:
844     {
845       mTxComponentStatic[index].mAnchorPoint.z = value;
846       break;
847     }
848     case TRANSFORM_PROPERTY_SIZE:
849     {
850       mSize[index].z = mSizeBase[index].z = value;
851       break;
852     }
853     default:
854     {
855       DALI_ASSERT_ALWAYS(false);
856     }
857   }
858 }
859
860 Quaternion& TransformManager::GetQuaternionPropertyValue(TransformId id)
861 {
862   TransformId index(mIds[id]);
863   return mTxComponentAnimatable[index].mOrientation;
864 }
865
866 const Quaternion& TransformManager::GetQuaternionPropertyValue(TransformId id) const
867 {
868   return mTxComponentAnimatable[mIds[id]].mOrientation;
869 }
870
871 void TransformManager::SetQuaternionPropertyValue(TransformId id, const Quaternion& q)
872 {
873   TransformId index(mIds[id]);
874   mTxComponentAnimatable[index].mOrientation = q;
875   mComponentDirty[index]                     = true;
876 }
877
878 void TransformManager::BakeQuaternionPropertyValue(TransformId id, const Quaternion& q)
879 {
880   TransformId index(mIds[id]);
881   mTxComponentAnimatable[index].mOrientation = mTxComponentAnimatableBaseValue[index].mOrientation = q;
882   mComponentDirty[index]                                                                           = true;
883 }
884
885 void TransformManager::BakeRelativeQuaternionPropertyValue(TransformId id, const Quaternion& q)
886 {
887   TransformId index(mIds[id]);
888   mTxComponentAnimatable[index].mOrientation = mTxComponentAnimatableBaseValue[index].mOrientation = mTxComponentAnimatable[index].mOrientation * q;
889   mComponentDirty[index]                                                                           = true;
890 }
891
892 const Vector4& TransformManager::GetBoundingSphere(TransformId id) const
893 {
894   return mBoundingSpheres[mIds[id]];
895 }
896
897 void TransformManager::GetWorldMatrixAndSize(TransformId id, Matrix& worldMatrix, Vector3& size) const
898 {
899   TransformId index = mIds[id];
900   worldMatrix       = mWorld[index];
901   size              = mSize[index];
902 }
903
904 void TransformManager::SetPositionUsesAnchorPoint(TransformId id, bool value)
905 {
906   TransformId index(mIds[id]);
907   mComponentDirty[index]                             = true;
908   mTxComponentStatic[index].mPositionUsesAnchorPoint = value;
909 }
910
911 } //namespace SceneGraph
912 } //namespace Internal
913 } //namespace Dali