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