Revert "[Tizen] Fix Svace issue for 64bit"
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / actor-coords.cpp
index ce8b7a6..4ee6566 100644 (file)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <dali/internal/common/matrix-utils.h>
 #include <dali/internal/event/actors/actor-coords.h>
 #include <dali/internal/event/common/event-thread-services.h>
 #include <dali/internal/event/common/projection.h>
 
 namespace Dali::Internal
 {
+namespace
+{
+/**
+ * @brief Get the Viewport Extents from RenderTask
+ *
+ * @param[in] renderTask RenderTask what we want to get viewport.
+ * @param[out] viewportExtent Calculated extent by renderTask.
+ * @return True if we success to get viewports. False otherwise
+ */
+bool GetViewportExtentsFromRenderTask(const RenderTask& renderTask, Rect<float>& viewportExtent)
+{
+  if(renderTask.GetFrameBuffer())
+  {
+    Dali::Actor mappingActor = renderTask.GetScreenToFrameBufferMappingActor();
+    if(mappingActor)
+    {
+      // NOTE : We will assume that mapping actor always use default camera.
+      Vector2 screenPosition    = mappingActor.GetProperty<Vector2>(Dali::Actor::Property::SCREEN_POSITION);
+      Vector3 size              = mappingActor.GetCurrentProperty<Vector3>(Dali::Actor::Property::SIZE) * mappingActor.GetCurrentProperty<Vector3>(Dali::Actor::Property::WORLD_SCALE);
+      Vector3 anchorPointOffSet = size * GetImplementation(mappingActor).GetAnchorPointForPosition();
+      Vector2 position          = Vector2(screenPosition.x - anchorPointOffSet.x, screenPosition.y - anchorPointOffSet.y);
+      viewportExtent.x          = position.x;
+      viewportExtent.y          = position.y;
+      viewportExtent.width      = size.x;
+      viewportExtent.height     = size.y;
+    }
+    else
+    {
+      return false;
+    }
+  }
+  else
+  {
+    Viewport viewport;
+    renderTask.GetViewport(viewport);
+    viewportExtent.x      = viewport.x;
+    viewportExtent.y      = viewport.y;
+    viewportExtent.width  = viewport.width;
+    viewportExtent.height = viewport.height;
+  }
+  return true;
+}
+} // namespace
 bool ConvertScreenToLocal(
   const Matrix&   viewMatrix,
   const Matrix&   projectionMatrix,
@@ -35,11 +79,11 @@ bool ConvertScreenToLocal(
 {
   // Get the ModelView matrix
   Matrix modelView;
-  Matrix::Multiply(modelView, worldMatrix, viewMatrix);
+  MatrixUtils::Multiply(modelView, worldMatrix, viewMatrix);
 
   // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects
   Matrix invertedMvp(false /*don't init*/);
-  Matrix::Multiply(invertedMvp, modelView, projectionMatrix);
+  MatrixUtils::Multiply(invertedMvp, modelView, projectionMatrix);
   bool success = invertedMvp.Invert();
 
   // Convert to GL coordinates
@@ -155,6 +199,252 @@ Rect<> CalculateActorScreenExtents(const Actor& actor, const Vector2& screenPosi
   return {position.x, position.y, size.x, size.y};
 }
 
+bool ConvertLocalToScreen(
+  const Matrix&  viewMatrix,
+  const Matrix&  projectionMatrix,
+  const Matrix&  worldMatrix,
+  const Rect<>&  viewportExtent,
+  const Vector3& localPosition,
+  float&         screenX,
+  float&         screenY)
+{
+  bool success = false;
+
+  // Convert local to projection coordinates
+  // note, P*(V*(M*pos))) is faster than (P*V*M)*pos
+  Vector4 mvpPos(localPosition.x, localPosition.y, localPosition.z, 1.0f);
+
+  mvpPos = worldMatrix * mvpPos;
+  mvpPos = viewMatrix * mvpPos;
+  mvpPos = projectionMatrix * mvpPos;
+
+  if(DALI_LIKELY(!EqualsZero(mvpPos.w)))
+  {
+    success = true;
+    screenX = viewportExtent.x + (mvpPos.x + mvpPos.w) * viewportExtent.width * 0.5f / mvpPos.w;
+    screenY = viewportExtent.y + (-mvpPos.y + mvpPos.w) * viewportExtent.height * 0.5f / mvpPos.w;
+  }
+  return success;
+}
+
+bool ConvertLocalToScreenRenderTask(
+  const RenderTask& renderTask,
+  const Actor&      actor,
+  const Matrix&     worldMatrix,
+  const Vector3&    localPosition,
+  float&            screenX,
+  float&            screenY)
+{
+  bool         success     = false;
+  const Actor* sourceActor = renderTask.GetSourceActor();
+  if(sourceActor == nullptr)
+  {
+    return success;
+  }
+
+  // Check whether current actor is in this rendertask.
+  bool         actorInRendertask = false;
+  const Actor* targetActor       = &actor;
+  while(targetActor)
+  {
+    if(sourceActor == targetActor)
+    {
+      actorInRendertask = true;
+      break;
+    }
+    targetActor = targetActor->GetParent();
+  }
+  if(!actorInRendertask)
+  {
+    return success;
+  }
+
+  CameraActor* camera = renderTask.GetCameraActor();
+  if(camera)
+  {
+    Rect<float> viewportExtent = {0.f, 0.f, 0.f, 0.f};
+    if(!GetViewportExtentsFromRenderTask(renderTask, viewportExtent))
+    {
+      return success;
+    }
+
+    if(ConvertLocalToScreen(camera->GetViewMatrix(), camera->GetProjectionMatrix(), worldMatrix, viewportExtent, localPosition, screenX, screenY))
+    {
+      success = true;
+    }
+  }
+  return success;
+}
+
+bool ConvertLocalToScreenRenderTaskList(
+  const RenderTaskList& renderTaskList,
+  const Actor&          actor,
+  const Matrix&         worldMatrix,
+  const Vector3&        localPosition,
+  float&                screenX,
+  float&                screenY)
+{
+  // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
+  uint32_t taskCount = renderTaskList.GetTaskCount();
+  for(uint32_t i = taskCount; i > 0; --i)
+  {
+    RenderTaskPtr task = renderTaskList.GetTask(i - 1);
+    if(ConvertLocalToScreenRenderTask(*task, actor, worldMatrix, localPosition, screenX, screenY))
+    {
+      // found a task where this conversion was ok so return
+      return true;
+    }
+  }
+  return false;
+}
+
+const Vector2 CalculateActorScreenPositionRenderTaskList(const Actor& actor, BufferIndex bufferIndex)
+{
+  if(actor.OnScene())
+  {
+    const auto& node  = actor.GetNode();
+    Scene&      scene = actor.GetScene();
+
+    Vector2 result;
+
+    auto        worldMatrix    = node.GetWorldMatrix(bufferIndex);
+    const auto& renderTaskList = scene.GetRenderTaskList();
+    ConvertLocalToScreenRenderTaskList(renderTaskList, actor, worldMatrix, node.GetSize(bufferIndex) * (actor.GetAnchorPointForPosition() - Vector3(0.5f, 0.5f, 0.5f)), result.x, result.y);
+
+    return result;
+  }
+  return Vector2::ZERO;
+}
+
+bool ConvertLocalToScreenExtentRenderTask(
+  const RenderTask& renderTask,
+  const Actor&      actor,
+  const Matrix&     worldMatrix,
+  const Vector3&    currentSize,
+  Rect<>&           screenExtent)
+{
+  bool         success     = false;
+  const Actor* sourceActor = renderTask.GetSourceActor();
+  if(sourceActor == nullptr)
+  {
+    return success;
+  }
+
+  // Check whether current actor is in this rendertask.
+  bool         actorInRendertask = false;
+  const Actor* targetActor       = &actor;
+  while(targetActor)
+  {
+    if(sourceActor == targetActor)
+    {
+      actorInRendertask = true;
+      break;
+    }
+    targetActor = targetActor->GetParent();
+  }
+  if(!actorInRendertask)
+  {
+    return success;
+  }
+
+  CameraActor* camera = renderTask.GetCameraActor();
+  if(camera)
+  {
+    Rect<float> viewportExtent = {0.f, 0.f, 0.f, 0.f};
+    if(!GetViewportExtentsFromRenderTask(renderTask, viewportExtent))
+    {
+      return success;
+    }
+
+    constexpr uint32_t BOX_POINT_COUNT           = 8;
+    const Vector3      BBOffset[BOX_POINT_COUNT] = {
+      Vector3(-currentSize.width * 0.5f, -currentSize.height * 0.5f, -currentSize.depth * 0.5f),
+      Vector3(-currentSize.width * 0.5f, currentSize.height * 0.5f, -currentSize.depth * 0.5f),
+      Vector3(currentSize.width * 0.5f, -currentSize.height * 0.5f, -currentSize.depth * 0.5f),
+      Vector3(currentSize.width * 0.5f, currentSize.height * 0.5f, -currentSize.depth * 0.5f),
+      Vector3(-currentSize.width * 0.5f, -currentSize.height * 0.5f, currentSize.depth * 0.5f),
+      Vector3(-currentSize.width * 0.5f, currentSize.height * 0.5f, currentSize.depth * 0.5f),
+      Vector3(currentSize.width * 0.5f, -currentSize.height * 0.5f, currentSize.depth * 0.5f),
+      Vector3(currentSize.width * 0.5f, currentSize.height * 0.5f, currentSize.depth * 0.5f),
+    };
+
+    float minScreenX = 0.0f;
+    float minScreenY = 0.0f;
+    float maxScreenX = 0.0f;
+    float maxScreenY = 0.0f;
+
+    const auto& viewMatrix       = camera->GetViewMatrix();
+    const auto& projectionMatrix = camera->GetProjectionMatrix();
+
+    success = ConvertLocalToScreen(viewMatrix, projectionMatrix, worldMatrix, viewportExtent, BBOffset[0], minScreenX, minScreenY);
+    if(success)
+    {
+      maxScreenX = minScreenX;
+      maxScreenY = minScreenY;
+      for(uint32_t i = 1; i < BOX_POINT_COUNT; ++i)
+      {
+        float   screenX       = 0.0f;
+        float   screenY       = 0.0f;
+        Vector3 localPosition = BBOffset[i];
+        if(DALI_UNLIKELY(!ConvertLocalToScreen(viewMatrix, projectionMatrix, worldMatrix, viewportExtent, localPosition, screenX, screenY)))
+        {
+          success = false;
+          break;
+        }
+        minScreenX = std::min(minScreenX, screenX);
+        maxScreenX = std::max(maxScreenX, screenX);
+        minScreenY = std::min(minScreenY, screenY);
+        maxScreenY = std::max(maxScreenY, screenY);
+      }
+      if(success)
+      {
+        screenExtent.x      = minScreenX;
+        screenExtent.y      = minScreenY;
+        screenExtent.width  = maxScreenX - minScreenX;
+        screenExtent.height = maxScreenY - minScreenY;
+      }
+    }
+  }
+  return success;
+}
+
+bool ConvertLocalToScreenExtentRenderTaskList(
+  const RenderTaskList& renderTaskList,
+  const Actor&          actor,
+  const Matrix&         worldMatrix,
+  const Vector3&        currentSize,
+  Rect<>&               screenExtent)
+{
+  // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
+  uint32_t taskCount = renderTaskList.GetTaskCount();
+  for(uint32_t i = taskCount; i > 0; --i)
+  {
+    RenderTaskPtr task = renderTaskList.GetTask(i - 1);
+    if(ConvertLocalToScreenExtentRenderTask(*task, actor, worldMatrix, currentSize, screenExtent))
+    {
+      // found a task where this conversion was ok so return
+      return true;
+    }
+  }
+  return false;
+}
+
+Rect<> CalculateActorScreenExtentsRenderTaskList(const Actor& actor, BufferIndex bufferIndex)
+{
+  Rect<> result = {0.0f, 0.0f, 0.0f, 0.0f};
+
+  if(actor.OnScene())
+  {
+    const auto& node  = actor.GetNode();
+    Scene&      scene = actor.GetScene();
+
+    auto        worldMatrix    = node.GetWorldMatrix(bufferIndex);
+    const auto& renderTaskList = scene.GetRenderTaskList();
+    ConvertLocalToScreenExtentRenderTaskList(renderTaskList, actor, worldMatrix, node.GetSize(bufferIndex), result);
+  }
+  return result;
+}
+
 /**
  * @brief Computes and center position by using transform properties.
  * @param[in] anchorPoint anchorPoint of an actor.
@@ -235,7 +525,7 @@ Matrix CalculateActorWorldTransform(const Actor& actor)
 
         //Update the world matrix
         Matrix tempMatrix;
-        Matrix::Multiply(tempMatrix, localMatrix, worldMatrix);
+        MatrixUtils::Multiply(tempMatrix, localMatrix, worldMatrix);
         worldMatrix = tempMatrix;
       }
       else
@@ -261,7 +551,7 @@ Matrix CalculateActorWorldTransform(const Actor& actor)
         {
           localMatrix.SetTransformComponents(localScale, localOrientation, Vector3::ZERO);
           Matrix tempMatrix;
-          Matrix::Multiply(tempMatrix, localMatrix, worldMatrix);
+          MatrixUtils::Multiply(tempMatrix, localMatrix, worldMatrix);
           worldMatrix = tempMatrix;
           worldMatrix.SetTranslation(actorPosition + centerPosition);
         }
@@ -270,7 +560,7 @@ Matrix CalculateActorWorldTransform(const Actor& actor)
           localPosition = actorPosition + centerPosition + (parentOrigin - Vector3(0.5f, 0.5f, 0.5f)) * parentSize;
           localMatrix.SetTransformComponents(localScale, localOrientation, localPosition);
           Matrix tempMatrix;
-          Matrix::Multiply(tempMatrix, localMatrix, worldMatrix);
+          MatrixUtils::Multiply(tempMatrix, localMatrix, worldMatrix);
           worldMatrix = tempMatrix;
         }
       }