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