[dali_1.2.30] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / transform-manager.cpp
index e9baa27..0d55efe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -42,12 +42,41 @@ 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 };
+static const float gDefaultTransformComponentStaticData[] = { 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, true };
 
 DALI_COMPILE_TIME_ASSERT( sizeof(gDefaultTransformComponentAnimatableData) == sizeof(TransformComponentAnimatable) );
 DALI_COMPILE_TIME_ASSERT( sizeof(gDefaultTransformComponentStaticData) == sizeof(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)
@@ -129,7 +158,9 @@ void TransformManager::RemoveTransform(TransformId id)
 void TransformManager::SetParent( TransformId id, TransformId parentId )
 {
   DALI_ASSERT_ALWAYS( id != parentId );
-  mParent[ mIds[id] ] = parentId;
+  unsigned int index = mIds[id];
+  mParent[ index ] = parentId;
+  mComponentDirty[ index ] = true;
   mReorder = true;
 }
 
@@ -209,9 +240,10 @@ 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 ) )
@@ -222,13 +254,10 @@ void TransformManager::Update()
         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
@@ -266,20 +295,22 @@ void TransformManager::Update()
         }
         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,6 +320,8 @@ void TransformManager::Update()
 
     mBoundingSpheres[i] = mWorld[i].GetTranslation();
     mBoundingSpheres[i].w = Length( centerToEdgeWorldSpace );
+
+    mComponentDirty[i] = false;
   }
 }
 
@@ -305,6 +338,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;
@@ -328,10 +362,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());
+  unsigned int previousIndex = 0;
+  for( size_t newIndex(0); newIndex<mComponentCount-1; ++newIndex )
   {
-    SwapComponents( mIds[mOrderedComponents[i].id], i);
+    previousIndex = mIds[mOrderedComponents[newIndex].id];
+    if( previousIndex != newIndex )
+    {
+      SwapComponents( previousIndex, newIndex);
+    }
   }
 }
 
@@ -837,6 +876,13 @@ void TransformManager::GetWorldMatrixAndSize( TransformId id, Matrix& worldMatri
   size = mSize[index];
 }
 
+void TransformManager::SetPositionUsesAnchorPoint( TransformId id, bool value )
+{
+  unsigned int index( mIds[ id ] );
+  mComponentDirty[ index ] = true;
+  mTxComponentStatic[ index ].mPositionUsesAnchorPoint = value;
+}
+
 } //namespace SceneGraph
 } //namespace Internal
 } //namespace Dali