Merge "use modern construct '= default' for special functions." into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / transform-manager.cpp
index e9baa27..277ccfb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 //EXTERNAL INCLUDES
 #include <algorithm>
 #include <cstring>
+#include <type_traits>
 
 //INTERNAL INCLUDES
 #include <dali/public-api/common/constants.h>
-#include <dali/public-api/common/compile-time-assert.h>
 #include <dali/internal/common/math.h>
 
 namespace Dali
@@ -42,19 +42,47 @@ namespace
 static const float gDefaultTransformComponentAnimatableData[] = { 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f };
 
 //Default values for anchor point (CENTER) and parent origin (TOP_LEFT)
-static const float gDefaultTransformComponentStaticData[] = { 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f };
-
-DALI_COMPILE_TIME_ASSERT( sizeof(gDefaultTransformComponentAnimatableData) == sizeof(TransformComponentAnimatable) );
-DALI_COMPILE_TIME_ASSERT( sizeof(gDefaultTransformComponentStaticData) == sizeof(TransformComponentStatic) );
+static const float gDefaultTransformComponentStaticData[] = { 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, true };
+
+static_assert( sizeof(gDefaultTransformComponentAnimatableData) == sizeof(TransformComponentAnimatable), "gDefaultTransformComponentAnimatableData should have the same number of floats as specified in TransformComponentAnimatable" );
+static_assert( sizeof(gDefaultTransformComponentStaticData) == sizeof(TransformComponentStatic), "gDefaultTransformComponentStaticData should have the same number of floats as specified in TransformComponentStatic" );
+
+/**
+ * @brief Calculates the center position for the transform component
+ * @param[out] centerPosition The calculated center-position of the transform component
+ * @param[in] transformComponentStatic A const reference to the static component transform struct
+ * @param[in] transformComponentAnimatable A const reference to the animatable component transform struct
+ * @param[in] size The size of the current transform component
+ * @param[in] half Halfway point of the transform
+ * @param[in] topLeft The top-left coords of the transform
+ */
+inline void CalculateCenterPosition(
+  Vector3& centerPosition,
+  const TransformComponentStatic& transformComponentStatic,
+  const TransformComponentAnimatable& transformComponentAnimatable,
+  const Vector3& size,
+  const Vector3& half,
+  const Vector3& topLeft )
+{
+  // Calculate the center-point by applying the scale and rotation on the anchor point.
+  centerPosition = ( half - transformComponentStatic.mAnchorPoint ) * size * transformComponentAnimatable.mScale;
+  centerPosition *= transformComponentAnimatable.mOrientation;
+
+  // If the position is ignoring the anchor-point, then remove the anchor-point shift from the position.
+  if( ! transformComponentStatic.mPositionUsesAnchorPoint )
+  {
+    centerPosition -= ( topLeft - transformComponentStatic.mAnchorPoint ) * size;
+  }
 }
 
+} // unnamed namespace
+
 TransformManager::TransformManager()
 :mComponentCount(0),
  mReorder(false)
 {}
 
-TransformManager::~TransformManager()
-{}
+TransformManager::~TransformManager() = default;
 
 TransformId TransformManager::CreateTransform()
 {
@@ -104,7 +132,7 @@ void TransformManager::RemoveTransform(TransformId id)
 {
   //Move the last element to the gap
   mComponentCount--;
-  unsigned int index = mIds[id];
+  TransformId index = mIds[id];
   mTxComponentAnimatable[index] = mTxComponentAnimatable[mComponentCount];
   mTxComponentStatic[index] = mTxComponentStatic[mComponentCount];
   mInheritanceMode[index] = mInheritanceMode[mComponentCount];
@@ -129,7 +157,9 @@ void TransformManager::RemoveTransform(TransformId id)
 void TransformManager::SetParent( TransformId id, TransformId parentId )
 {
   DALI_ASSERT_ALWAYS( id != parentId );
-  mParent[ mIds[id] ] = parentId;
+  TransformId index = mIds[id];
+  mParent[ index ] = parentId;
+  mComponentDirty[ index ] = true;
   mReorder = true;
 }
 
@@ -145,7 +175,7 @@ Matrix& TransformManager::GetWorldMatrix( TransformId id )
 
 void TransformManager::SetInheritPosition( TransformId id, bool inherit )
 {
-  unsigned int index = mIds[id];
+  TransformId index = mIds[id];
   if( inherit )
   {
     mInheritanceMode[ index ] |= INHERIT_POSITION;
@@ -160,7 +190,7 @@ void TransformManager::SetInheritPosition( TransformId id, bool inherit )
 
 void TransformManager::SetInheritScale( TransformId id, bool inherit )
 {
-  unsigned int index = mIds[id];
+  TransformId index = mIds[id];
   if( inherit )
   {
     mInheritanceMode[ index ] |= INHERIT_SCALE;
@@ -175,7 +205,7 @@ void TransformManager::SetInheritScale( TransformId id, bool inherit )
 
 void TransformManager::SetInheritOrientation( TransformId id, bool inherit )
 {
-  unsigned int index = mIds[id];
+  TransformId index = mIds[id];
   if( inherit )
   {
     mInheritanceMode[ index ] |= INHERIT_ORIENTATION;
@@ -198,8 +228,10 @@ void TransformManager::ResetToBaseValue()
   }
 }
 
-void TransformManager::Update()
+bool TransformManager::Update()
 {
+  bool componentsChanged = false;
+
   if( mReorder )
   {
     //If some transform component has change its parent or has been removed since last update
@@ -209,26 +241,24 @@ void TransformManager::Update()
   }
 
   //Iterate through all components to compute its world matrix
-  Vector3 anchorPosition;
+  Vector3 centerPosition;
   Vector3 localPosition;
-  Vector3 half( 0.5f,0.5f,0.5f );
+  const Vector3 half( 0.5f,0.5f,0.5f );
+  const Vector3 topLeft( 0.0f, 0.0f, 0.5f );
   for( unsigned int i(0); i<mComponentCount; ++i )
   {
     if( DALI_LIKELY( mInheritanceMode[i] != DONT_INHERIT_TRANSFORM && mParent[i] != INVALID_TRANSFORM_ID ) )
     {
-      const unsigned int& parentIndex = mIds[mParent[i] ];
+      const TransformId& parentIndex = mIds[mParent[i] ];
       if( DALI_LIKELY( mInheritanceMode[i] == INHERIT_ALL ) )
       {
         if( mComponentDirty[i] || mLocalMatrixDirty[parentIndex])
         {
           //Full transform inherited
-          mComponentDirty[i] = false;
           mLocalMatrixDirty[i] = true;
-
-          anchorPosition = ( half - mTxComponentStatic[i].mAnchorPoint ) * mSize[i] * mTxComponentAnimatable[i].mScale;
-          anchorPosition *= mTxComponentAnimatable[i].mOrientation;
-          localPosition = mTxComponentAnimatable[i].mPosition + anchorPosition + ( mTxComponentStatic[i].mParentOrigin - half ) *  mSize[parentIndex];
-          mLocal[i].SetTransformComponents( mTxComponentAnimatable[i].mScale,mTxComponentAnimatable[i].mOrientation, localPosition );
+          CalculateCenterPosition( centerPosition, mTxComponentStatic[ i ], mTxComponentAnimatable[ i ], mSize[ i ], half, topLeft );
+          localPosition = mTxComponentAnimatable[i].mPosition + centerPosition + ( mTxComponentStatic[i].mParentOrigin - half ) *  mSize[parentIndex];
+          mLocal[i].SetTransformComponents( mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, localPosition );
         }
 
         //Update the world matrix
@@ -260,26 +290,29 @@ void TransformManager::Update()
         if( (mInheritanceMode[i] & INHERIT_POSITION) == 0 )
         {
           //Don't inherit position
+          CalculateCenterPosition( centerPosition, mTxComponentStatic[ i ], mTxComponentAnimatable[ i ], mSize[ i ], half, topLeft );
           mLocal[i].SetTransformComponents( localScale, localOrientation, Vector3::ZERO );
           Matrix::Multiply( mWorld[i], mLocal[i], parentMatrix );
-          mWorld[i].SetTranslation( mTxComponentAnimatable[i].mPosition);
+          mWorld[i].SetTranslation( mTxComponentAnimatable[i].mPosition + centerPosition );
         }
         else
         {
-          anchorPosition = ( half - mTxComponentStatic[i].mAnchorPoint ) * mSize[i] * mTxComponentAnimatable[i].mScale;
-          anchorPosition *= mTxComponentAnimatable[i].mOrientation;
-          localPosition = mTxComponentAnimatable[i].mPosition + anchorPosition + ( mTxComponentStatic[i].mParentOrigin - half ) *  mSize[parentIndex];
+          CalculateCenterPosition( centerPosition, mTxComponentStatic[ i ], mTxComponentAnimatable[ i ], mSize[ i ], half, topLeft );
+          localPosition = mTxComponentAnimatable[i].mPosition + centerPosition + ( mTxComponentStatic[i].mParentOrigin - half ) *  mSize[parentIndex];
           mLocal[i].SetTransformComponents( localScale, localOrientation, localPosition );
           Matrix::Multiply( mWorld[i], mLocal[i], parentMatrix );
         }
+
+        mLocalMatrixDirty[i] = true;
       }
     }
     else  //Component has no parent or doesn't inherit transform
     {
-      anchorPosition = ( half - mTxComponentStatic[i].mAnchorPoint ) * mSize[i] * mTxComponentAnimatable[i].mScale;
-      anchorPosition *= mTxComponentAnimatable[i].mOrientation;
-      localPosition = mTxComponentAnimatable[i].mPosition + anchorPosition;
-      mWorld[i].SetTransformComponents( mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, localPosition );
+      CalculateCenterPosition( centerPosition, mTxComponentStatic[ i ], mTxComponentAnimatable[ i ], mSize[ i ], half, topLeft );
+      localPosition = mTxComponentAnimatable[i].mPosition + centerPosition;
+      mLocal[i].SetTransformComponents( mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, localPosition );
+      mWorld[i] = mLocal[i];
+      mLocalMatrixDirty[i] = true;
     }
 
     //Update the bounding sphere
@@ -289,7 +322,12 @@ void TransformManager::Update()
 
     mBoundingSpheres[i] = mWorld[i].GetTranslation();
     mBoundingSpheres[i].w = Length( centerToEdgeWorldSpace );
+
+    componentsChanged = componentsChanged || mComponentDirty[i];
+    mComponentDirty[i] = false;
   }
+
+  return componentsChanged;
 }
 
 void TransformManager::SwapComponents( unsigned int i, unsigned int j )
@@ -305,6 +343,7 @@ void TransformManager::SwapComponents( unsigned int i, unsigned int j )
   std::swap( mLocal[i], mLocal[j] );
   std::swap( mComponentDirty[i], mComponentDirty[j] );
   std::swap( mBoundingSpheres[i], mBoundingSpheres[j] );
+  std::swap( mWorld[i], mWorld[j] );
 
   mIds[ mComponentId[i] ] = i;
   mIds[ mComponentId[j] ] = j;
@@ -315,7 +354,7 @@ void TransformManager::ReorderComponents()
   mOrderedComponents.Resize(mComponentCount);
 
   TransformId parentId;
-  for( size_t i(0); i<mComponentCount; ++i )
+  for( TransformId i = 0; i<mComponentCount; ++i )
   {
     mOrderedComponents[i].id = mComponentId[i];
     mOrderedComponents[i].level = 0u;
@@ -328,10 +367,15 @@ void TransformManager::ReorderComponents()
     }
   }
 
-  std::sort( mOrderedComponents.Begin(), mOrderedComponents.End());
-  for( size_t i(0); i<mComponentCount-1; ++i )
+  std::stable_sort( mOrderedComponents.Begin(), mOrderedComponents.End());
+  TransformId previousIndex = 0;
+  for( TransformId newIndex = 0; newIndex < mComponentCount-1; ++newIndex )
   {
-    SwapComponents( mIds[mOrderedComponents[i].id], i);
+    previousIndex = mIds[mOrderedComponents[newIndex].id];
+    if( previousIndex != newIndex )
+    {
+      SwapComponents( previousIndex, newIndex);
+    }
   }
 }
 
@@ -341,32 +385,27 @@ Vector3& TransformManager::GetVector3PropertyValue( TransformId id, TransformMan
   {
     case TRANSFORM_PROPERTY_POSITION:
     {
-      unsigned int index( mIds[id] );
-      mComponentDirty[ index ] = true;
+      TransformId index( mIds[id] );
       return mTxComponentAnimatable[ index ].mPosition;
     }
     case TRANSFORM_PROPERTY_SCALE:
     {
-      unsigned int index( mIds[id] );
-      mComponentDirty[ index ] = true;
+      TransformId index( mIds[id] );
       return mTxComponentAnimatable[ index ].mScale;
     }
     case TRANSFORM_PROPERTY_PARENT_ORIGIN:
     {
-      unsigned int index( mIds[id] );
-      mComponentDirty[ index ] = true;
+      TransformId index( mIds[id] );
       return mTxComponentStatic[ index ].mParentOrigin;
     }
     case TRANSFORM_PROPERTY_ANCHOR_POINT:
     {
-      unsigned int index( mIds[id] );
-      mComponentDirty[ index ] = true;
+      TransformId index( mIds[id] );
       return mTxComponentStatic[ index ].mAnchorPoint;
     }
     case TRANSFORM_PROPERTY_SIZE:
     {
-      unsigned int index( mIds[id] );
-      mComponentDirty[ index ] = true;
+      TransformId index( mIds[id] );
       return mSize[ index ];
     }
     default:
@@ -443,7 +482,7 @@ const float& TransformManager::GetVector3PropertyComponentValue(TransformId id,
 
 void TransformManager::SetVector3PropertyValue( TransformId id, TransformManagerProperty property, const Vector3& value )
 {
-  unsigned int index( mIds[id] );
+  TransformId index( mIds[id] );
   mComponentDirty[ index ] = true;
 
   switch( property )
@@ -482,7 +521,7 @@ void TransformManager::SetVector3PropertyValue( TransformId id, TransformManager
 
 void TransformManager::SetVector3PropertyComponentValue( TransformId id, TransformManagerProperty property, float value, unsigned int component )
 {
-  unsigned int index( mIds[id] );
+  TransformId index( mIds[id] );
   mComponentDirty[ index ] = true;
 
   switch( property )
@@ -521,7 +560,7 @@ void TransformManager::SetVector3PropertyComponentValue( TransformId id, Transfo
 
 void TransformManager::BakeVector3PropertyValue( TransformId id, TransformManagerProperty property, const Vector3& value )
 {
-  unsigned int index( mIds[id] );
+  TransformId index( mIds[id] );
   mComponentDirty[ index ] = true;
 
   switch( property )
@@ -560,7 +599,7 @@ void TransformManager::BakeVector3PropertyValue( TransformId id, TransformManage
 
 void TransformManager::BakeRelativeVector3PropertyValue( TransformId id, TransformManagerProperty property, const Vector3& value )
 {
-  unsigned int index( mIds[id] );
+  TransformId index( mIds[id] );
   mComponentDirty[ index ] = true;
 
   switch( property )
@@ -599,7 +638,7 @@ void TransformManager::BakeRelativeVector3PropertyValue( TransformId id, Transfo
 
 void TransformManager::BakeMultiplyVector3PropertyValue( TransformId id, TransformManagerProperty property, const Vector3& value )
 {
-  unsigned int index( mIds[id] );
+  TransformId index( mIds[id] );
   mComponentDirty[ index ] = true;
 
   switch( property )
@@ -638,7 +677,7 @@ void TransformManager::BakeMultiplyVector3PropertyValue( TransformId id, Transfo
 
 void TransformManager::BakeVector3PropertyComponentValue( TransformId id, TransformManagerProperty property, float value, unsigned int component )
 {
-  unsigned int index( mIds[id] );
+  TransformId index( mIds[id] );
   mComponentDirty[ index ] = true;
 
   switch( property )
@@ -677,7 +716,7 @@ void TransformManager::BakeVector3PropertyComponentValue( TransformId id, Transf
 
 void TransformManager::BakeXVector3PropertyValue( TransformId id, TransformManagerProperty property, float value )
 {
-  unsigned int index( mIds[id] );
+  TransformId index( mIds[id] );
   mComponentDirty[ index ] = true;
 
   switch( property )
@@ -716,7 +755,7 @@ void TransformManager::BakeXVector3PropertyValue( TransformId id, TransformManag
 
 void TransformManager::BakeYVector3PropertyValue( TransformId id, TransformManagerProperty property, float value )
 {
-  unsigned int index( mIds[id] );
+  TransformId index( mIds[id] );
   mComponentDirty[ index ] = true;
 
   switch( property )
@@ -755,7 +794,7 @@ void TransformManager::BakeYVector3PropertyValue( TransformId id, TransformManag
 
 void TransformManager::BakeZVector3PropertyValue( TransformId id, TransformManagerProperty property, float value )
 {
-  unsigned int index( mIds[id] );
+  TransformId index( mIds[id] );
   mComponentDirty[ index ] = true;
 
   switch( property )
@@ -794,8 +833,7 @@ void TransformManager::BakeZVector3PropertyValue( TransformId id, TransformManag
 
 Quaternion& TransformManager::GetQuaternionPropertyValue( TransformId id )
 {
-  unsigned int index( mIds[id] );
-  mComponentDirty[ index ] = true;
+  TransformId index( mIds[id] );
   return mTxComponentAnimatable[ index ].mOrientation;
 }
 
@@ -806,21 +844,21 @@ const Quaternion& TransformManager::GetQuaternionPropertyValue( TransformId id )
 
 void TransformManager::SetQuaternionPropertyValue( TransformId id, const Quaternion& q )
 {
-  unsigned int index( mIds[id] );
+  TransformId index( mIds[id] );
   mTxComponentAnimatable[ index ].mOrientation = q;
   mComponentDirty[ index ] = true;
 }
 
 void TransformManager::BakeQuaternionPropertyValue( TransformId id, const Quaternion& q )
 {
-  unsigned int index( mIds[id] );
+  TransformId index( mIds[id] );
   mTxComponentAnimatable[ index ].mOrientation = mTxComponentAnimatableBaseValue[index].mOrientation = q;
   mComponentDirty[ index ] = true;
 }
 
 void TransformManager::BakeRelativeQuaternionPropertyValue( TransformId id, const Quaternion& q )
 {
-  unsigned int index( mIds[id] );
+  TransformId index( mIds[id] );
   mTxComponentAnimatable[ index ].mOrientation = mTxComponentAnimatableBaseValue[index].mOrientation = mTxComponentAnimatable[ index ].mOrientation * q;
   mComponentDirty[ index ] = true;
 }
@@ -832,11 +870,18 @@ const Vector4& TransformManager::GetBoundingSphere( TransformId id ) const
 
 void TransformManager::GetWorldMatrixAndSize( TransformId id, Matrix& worldMatrix, Vector3& size ) const
 {
-  unsigned int index = mIds[id];
+  TransformId index = mIds[id];
   worldMatrix = mWorld[index];
   size = mSize[index];
 }
 
+void TransformManager::SetPositionUsesAnchorPoint( TransformId id, bool value )
+{
+  TransformId index( mIds[ id ] );
+  mComponentDirty[ index ] = true;
+  mTxComponentStatic[ index ].mPositionUsesAnchorPoint = value;
+}
+
 } //namespace SceneGraph
 } //namespace Internal
 } //namespace Dali