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