d61acc2a7a60cc5ba7b7c1f79e5c15a31abff45c
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / transform-manager.cpp
1 /*
2  * Copyright (c) 2021 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] = (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] = (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   TransformId parentId;
358   for(TransformId i = 0; i < mComponentCount; ++i)
359   {
360     mOrderedComponents[i].id    = mComponentId[i];
361     mOrderedComponents[i].level = 0u;
362
363     parentId = mParent[i];
364     while(parentId != INVALID_TRANSFORM_ID)
365     {
366       mOrderedComponents[i].level++;
367       parentId = mParent[mIds[parentId]];
368     }
369   }
370
371   std::stable_sort(mOrderedComponents.Begin(), mOrderedComponents.End());
372   TransformId previousIndex = 0;
373   for(TransformId newIndex = 0; newIndex < mComponentCount - 1; ++newIndex)
374   {
375     previousIndex = mIds[mOrderedComponents[newIndex].id];
376     if(previousIndex != newIndex)
377     {
378       SwapComponents(previousIndex, newIndex);
379     }
380   }
381 }
382
383 Vector3& TransformManager::GetVector3PropertyValue(TransformId id, TransformManagerProperty property)
384 {
385   switch(property)
386   {
387     case TRANSFORM_PROPERTY_POSITION:
388     {
389       TransformId index(mIds[id]);
390       return mTxComponentAnimatable[index].mPosition;
391     }
392     case TRANSFORM_PROPERTY_SCALE:
393     {
394       TransformId index(mIds[id]);
395       return mTxComponentAnimatable[index].mScale;
396     }
397     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
398     {
399       TransformId index(mIds[id]);
400       return mTxComponentStatic[index].mParentOrigin;
401     }
402     case TRANSFORM_PROPERTY_ANCHOR_POINT:
403     {
404       TransformId index(mIds[id]);
405       return mTxComponentStatic[index].mAnchorPoint;
406     }
407     case TRANSFORM_PROPERTY_SIZE:
408     {
409       TransformId index(mIds[id]);
410       return mSize[index];
411     }
412     default:
413     {
414       DALI_ASSERT_ALWAYS(false);
415       return mTxComponentAnimatable[mIds[id]].mPosition;
416     }
417   }
418 }
419
420 const Vector3& TransformManager::GetVector3PropertyValue(TransformId id, TransformManagerProperty property) const
421 {
422   switch(property)
423   {
424     case TRANSFORM_PROPERTY_POSITION:
425     {
426       return mTxComponentAnimatable[mIds[id]].mPosition;
427     }
428     case TRANSFORM_PROPERTY_SCALE:
429     {
430       return mTxComponentAnimatable[mIds[id]].mScale;
431     }
432     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
433     {
434       return mTxComponentStatic[mIds[id]].mParentOrigin;
435     }
436     case TRANSFORM_PROPERTY_ANCHOR_POINT:
437     {
438       return mTxComponentStatic[mIds[id]].mAnchorPoint;
439     }
440     case TRANSFORM_PROPERTY_SIZE:
441     {
442       return mSize[mIds[id]];
443     }
444     default:
445     {
446       DALI_ASSERT_ALWAYS(false);
447       return mTxComponentAnimatable[mIds[id]].mPosition;
448     }
449   }
450 }
451
452 const float& TransformManager::GetVector3PropertyComponentValue(TransformId id, TransformManagerProperty property, unsigned int component) const
453 {
454   switch(property)
455   {
456     case TRANSFORM_PROPERTY_POSITION:
457     {
458       return mTxComponentAnimatable[mIds[id]].mPosition[component];
459     }
460     case TRANSFORM_PROPERTY_SCALE:
461     {
462       return mTxComponentAnimatable[mIds[id]].mScale[component];
463     }
464     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
465     {
466       return mTxComponentStatic[mIds[id]].mParentOrigin[component];
467     }
468     case TRANSFORM_PROPERTY_ANCHOR_POINT:
469     {
470       return mTxComponentStatic[mIds[id]].mAnchorPoint[component];
471     }
472     case TRANSFORM_PROPERTY_SIZE:
473     {
474       return mSize[mIds[id]][component];
475     }
476     default:
477     {
478       DALI_ASSERT_ALWAYS(false);
479       return mTxComponentAnimatable[mIds[id]].mPosition[component];
480     }
481   }
482 }
483
484 void TransformManager::SetVector3PropertyValue(TransformId id, TransformManagerProperty property, const Vector3& value)
485 {
486   TransformId index(mIds[id]);
487   mComponentDirty[index] = true;
488
489   switch(property)
490   {
491     case TRANSFORM_PROPERTY_POSITION:
492     {
493       mTxComponentAnimatable[index].mPosition = value;
494       break;
495     }
496     case TRANSFORM_PROPERTY_SCALE:
497     {
498       mTxComponentAnimatable[index].mScale = value;
499       break;
500     }
501     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
502     {
503       mTxComponentStatic[index].mParentOrigin = value;
504       break;
505     }
506     case TRANSFORM_PROPERTY_ANCHOR_POINT:
507     {
508       mTxComponentStatic[index].mAnchorPoint = value;
509       break;
510     }
511     case TRANSFORM_PROPERTY_SIZE:
512     {
513       mSize[index] = value;
514       break;
515     }
516     default:
517     {
518       DALI_ASSERT_ALWAYS(false);
519     }
520   }
521 }
522
523 void TransformManager::SetVector3PropertyComponentValue(TransformId id, TransformManagerProperty property, float value, unsigned int component)
524 {
525   TransformId index(mIds[id]);
526   mComponentDirty[index] = true;
527
528   switch(property)
529   {
530     case TRANSFORM_PROPERTY_POSITION:
531     {
532       mTxComponentAnimatable[index].mPosition[component] = value;
533       break;
534     }
535     case TRANSFORM_PROPERTY_SCALE:
536     {
537       mTxComponentAnimatable[index].mScale[component] = value;
538       break;
539     }
540     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
541     {
542       mTxComponentStatic[index].mParentOrigin[component] = value;
543       break;
544     }
545     case TRANSFORM_PROPERTY_ANCHOR_POINT:
546     {
547       mTxComponentStatic[index].mAnchorPoint[component] = value;
548       break;
549     }
550     case TRANSFORM_PROPERTY_SIZE:
551     {
552       mSize[index][component] = value;
553       break;
554     }
555     default:
556     {
557       DALI_ASSERT_ALWAYS(false);
558     }
559   }
560 }
561
562 void TransformManager::BakeVector3PropertyValue(TransformId id, TransformManagerProperty property, const Vector3& value)
563 {
564   TransformId index(mIds[id]);
565   mComponentDirty[index] = true;
566
567   switch(property)
568   {
569     case TRANSFORM_PROPERTY_POSITION:
570     {
571       mTxComponentAnimatable[index].mPosition = mTxComponentAnimatableBaseValue[index].mPosition = value;
572       break;
573     }
574     case TRANSFORM_PROPERTY_SCALE:
575     {
576       mTxComponentAnimatable[index].mScale = mTxComponentAnimatableBaseValue[index].mScale = value;
577       break;
578     }
579     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
580     {
581       mTxComponentStatic[index].mParentOrigin = value;
582       break;
583     }
584     case TRANSFORM_PROPERTY_ANCHOR_POINT:
585     {
586       mTxComponentStatic[index].mAnchorPoint = value;
587       break;
588     }
589     case TRANSFORM_PROPERTY_SIZE:
590     {
591       mSize[index] = mSizeBase[index] = value;
592       break;
593     }
594     default:
595     {
596       DALI_ASSERT_ALWAYS(false);
597     }
598   }
599 }
600
601 void TransformManager::BakeRelativeVector3PropertyValue(TransformId id, TransformManagerProperty property, const Vector3& value)
602 {
603   TransformId index(mIds[id]);
604   mComponentDirty[index] = true;
605
606   switch(property)
607   {
608     case TRANSFORM_PROPERTY_POSITION:
609     {
610       mTxComponentAnimatable[index].mPosition = mTxComponentAnimatableBaseValue[index].mPosition = mTxComponentAnimatable[index].mPosition + value;
611       break;
612     }
613     case TRANSFORM_PROPERTY_SCALE:
614     {
615       mTxComponentAnimatable[index].mScale = mTxComponentAnimatableBaseValue[index].mScale = mTxComponentAnimatable[index].mScale + value;
616       break;
617     }
618     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
619     {
620       mTxComponentStatic[index].mParentOrigin = mTxComponentStatic[index].mParentOrigin + value;
621       break;
622     }
623     case TRANSFORM_PROPERTY_ANCHOR_POINT:
624     {
625       mTxComponentStatic[index].mAnchorPoint = mTxComponentStatic[index].mAnchorPoint + value;
626       break;
627     }
628     case TRANSFORM_PROPERTY_SIZE:
629     {
630       mSize[index] = mSizeBase[index] = mSize[index] + value;
631       break;
632     }
633     default:
634     {
635       DALI_ASSERT_ALWAYS(false);
636     }
637   }
638 }
639
640 void TransformManager::BakeMultiplyVector3PropertyValue(TransformId id, TransformManagerProperty property, const Vector3& value)
641 {
642   TransformId index(mIds[id]);
643   mComponentDirty[index] = true;
644
645   switch(property)
646   {
647     case TRANSFORM_PROPERTY_POSITION:
648     {
649       mTxComponentAnimatable[index].mPosition = mTxComponentAnimatableBaseValue[index].mPosition = mTxComponentAnimatable[index].mPosition * value;
650       break;
651     }
652     case TRANSFORM_PROPERTY_SCALE:
653     {
654       mTxComponentAnimatable[index].mScale = mTxComponentAnimatableBaseValue[index].mScale = mTxComponentAnimatable[index].mScale * value;
655       break;
656     }
657     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
658     {
659       mTxComponentStatic[index].mParentOrigin = mTxComponentStatic[index].mParentOrigin * value;
660       break;
661     }
662     case TRANSFORM_PROPERTY_ANCHOR_POINT:
663     {
664       mTxComponentStatic[index].mAnchorPoint = mTxComponentStatic[index].mAnchorPoint * value;
665       break;
666     }
667     case TRANSFORM_PROPERTY_SIZE:
668     {
669       mSize[index] = mSizeBase[index] = mSize[index] * value;
670       break;
671     }
672     default:
673     {
674       DALI_ASSERT_ALWAYS(false);
675     }
676   }
677 }
678
679 void TransformManager::BakeVector3PropertyComponentValue(TransformId id, TransformManagerProperty property, float value, unsigned int component)
680 {
681   TransformId index(mIds[id]);
682   mComponentDirty[index] = true;
683
684   switch(property)
685   {
686     case TRANSFORM_PROPERTY_POSITION:
687     {
688       mTxComponentAnimatable[index].mPosition[component] = mTxComponentAnimatableBaseValue[index].mPosition[component] = value;
689       break;
690     }
691     case TRANSFORM_PROPERTY_SCALE:
692     {
693       mTxComponentAnimatable[index].mScale[component] = mTxComponentAnimatableBaseValue[index].mScale[component] = value;
694       break;
695     }
696     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
697     {
698       mTxComponentStatic[index].mParentOrigin[component] = value;
699       break;
700     }
701     case TRANSFORM_PROPERTY_ANCHOR_POINT:
702     {
703       mTxComponentStatic[index].mAnchorPoint[component] = value;
704       break;
705     }
706     case TRANSFORM_PROPERTY_SIZE:
707     {
708       mSize[index][component] = mSizeBase[index][component] = value;
709       break;
710     }
711     default:
712     {
713       DALI_ASSERT_ALWAYS(false);
714     }
715   }
716 }
717
718 void TransformManager::BakeXVector3PropertyValue(TransformId id, TransformManagerProperty property, float value)
719 {
720   TransformId index(mIds[id]);
721   mComponentDirty[index] = true;
722
723   switch(property)
724   {
725     case TRANSFORM_PROPERTY_POSITION:
726     {
727       mTxComponentAnimatable[index].mPosition.x = mTxComponentAnimatableBaseValue[index].mPosition.x = value;
728       break;
729     }
730     case TRANSFORM_PROPERTY_SCALE:
731     {
732       mTxComponentAnimatable[index].mScale.x = mTxComponentAnimatableBaseValue[index].mScale.x = value;
733       break;
734     }
735     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
736     {
737       mTxComponentStatic[index].mParentOrigin.x = value;
738       break;
739     }
740     case TRANSFORM_PROPERTY_ANCHOR_POINT:
741     {
742       mTxComponentStatic[index].mAnchorPoint.x = value;
743       break;
744     }
745     case TRANSFORM_PROPERTY_SIZE:
746     {
747       mSize[index].x = mSizeBase[index].x = value;
748       break;
749     }
750     default:
751     {
752       DALI_ASSERT_ALWAYS(false);
753     }
754   }
755 }
756
757 void TransformManager::BakeYVector3PropertyValue(TransformId id, TransformManagerProperty property, float value)
758 {
759   TransformId index(mIds[id]);
760   mComponentDirty[index] = true;
761
762   switch(property)
763   {
764     case TRANSFORM_PROPERTY_POSITION:
765     {
766       mTxComponentAnimatable[index].mPosition.y = mTxComponentAnimatableBaseValue[index].mPosition.y = value;
767       break;
768     }
769     case TRANSFORM_PROPERTY_SCALE:
770     {
771       mTxComponentAnimatable[index].mScale.y = mTxComponentAnimatableBaseValue[index].mScale.y = value;
772       break;
773     }
774     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
775     {
776       mTxComponentStatic[index].mParentOrigin.y = value;
777       break;
778     }
779     case TRANSFORM_PROPERTY_ANCHOR_POINT:
780     {
781       mTxComponentStatic[index].mAnchorPoint.y = value;
782       break;
783     }
784     case TRANSFORM_PROPERTY_SIZE:
785     {
786       mSize[index].y = mSizeBase[index].y = value;
787       break;
788     }
789     default:
790     {
791       DALI_ASSERT_ALWAYS(false);
792     }
793   }
794 }
795
796 void TransformManager::BakeZVector3PropertyValue(TransformId id, TransformManagerProperty property, float value)
797 {
798   TransformId index(mIds[id]);
799   mComponentDirty[index] = true;
800
801   switch(property)
802   {
803     case TRANSFORM_PROPERTY_POSITION:
804     {
805       mTxComponentAnimatable[index].mPosition.z = mTxComponentAnimatableBaseValue[index].mPosition.z = value;
806       break;
807     }
808     case TRANSFORM_PROPERTY_SCALE:
809     {
810       mTxComponentAnimatable[index].mScale.z = mTxComponentAnimatableBaseValue[index].mScale.z = value;
811       break;
812     }
813     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
814     {
815       mTxComponentStatic[index].mParentOrigin.z = value;
816       break;
817     }
818     case TRANSFORM_PROPERTY_ANCHOR_POINT:
819     {
820       mTxComponentStatic[index].mAnchorPoint.z = value;
821       break;
822     }
823     case TRANSFORM_PROPERTY_SIZE:
824     {
825       mSize[index].z = mSizeBase[index].z = value;
826       break;
827     }
828     default:
829     {
830       DALI_ASSERT_ALWAYS(false);
831     }
832   }
833 }
834
835 Quaternion& TransformManager::GetQuaternionPropertyValue(TransformId id)
836 {
837   TransformId index(mIds[id]);
838   return mTxComponentAnimatable[index].mOrientation;
839 }
840
841 const Quaternion& TransformManager::GetQuaternionPropertyValue(TransformId id) const
842 {
843   return mTxComponentAnimatable[mIds[id]].mOrientation;
844 }
845
846 void TransformManager::SetQuaternionPropertyValue(TransformId id, const Quaternion& q)
847 {
848   TransformId index(mIds[id]);
849   mTxComponentAnimatable[index].mOrientation = q;
850   mComponentDirty[index]                     = true;
851 }
852
853 void TransformManager::BakeQuaternionPropertyValue(TransformId id, const Quaternion& q)
854 {
855   TransformId index(mIds[id]);
856   mTxComponentAnimatable[index].mOrientation = mTxComponentAnimatableBaseValue[index].mOrientation = q;
857   mComponentDirty[index]                                                                           = true;
858 }
859
860 void TransformManager::BakeRelativeQuaternionPropertyValue(TransformId id, const Quaternion& q)
861 {
862   TransformId index(mIds[id]);
863   mTxComponentAnimatable[index].mOrientation = mTxComponentAnimatableBaseValue[index].mOrientation = mTxComponentAnimatable[index].mOrientation * q;
864   mComponentDirty[index]                                                                           = true;
865 }
866
867 const Vector4& TransformManager::GetBoundingSphere(TransformId id) const
868 {
869   return mBoundingSpheres[mIds[id]];
870 }
871
872 void TransformManager::GetWorldMatrixAndSize(TransformId id, Matrix& worldMatrix, Vector3& size) const
873 {
874   TransformId index = mIds[id];
875   worldMatrix       = mWorld[index];
876   size              = mSize[index];
877 }
878
879 void TransformManager::SetPositionUsesAnchorPoint(TransformId id, bool value)
880 {
881   TransformId index(mIds[id]);
882   mComponentDirty[index]                             = true;
883   mTxComponentStatic[index].mPositionUsesAnchorPoint = value;
884 }
885
886 } //namespace SceneGraph
887 } //namespace Internal
888 } //namespace Dali