Refactored Actor screen to local conversion 93/265493/1
authorDavid Steele <david.steele@samsung.com>
Wed, 20 Oct 2021 13:40:37 +0000 (14:40 +0100)
committerDavid Steele <david.steele@samsung.com>
Wed, 20 Oct 2021 14:46:33 +0000 (15:46 +0100)
Change-Id: I145644d1702e9e3f9f6571aff5651c811abbf39c

dali/internal/event/actors/actor-coords.cpp [new file with mode: 0644]
dali/internal/event/actors/actor-coords.h [new file with mode: 0644]
dali/internal/event/actors/actor-impl.cpp
dali/internal/file.list

diff --git a/dali/internal/event/actors/actor-coords.cpp b/dali/internal/event/actors/actor-coords.cpp
new file mode 100644 (file)
index 0000000..55b8bb1
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali/internal/event/actors/actor-coords.h>
+#include <dali/internal/event/common/projection.h>
+
+namespace Dali::Internal
+{
+bool ConvertScreenToLocal(
+  const Matrix&   viewMatrix,
+  const Matrix&   projectionMatrix,
+  const Matrix&   worldMatrix,
+  const Vector3&  currentSize,
+  const Viewport& viewport,
+  float&          localX,
+  float&          localY,
+  float           screenX,
+  float           screenY)
+{
+  // Get the ModelView matrix
+  Matrix modelView;
+  Matrix::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);
+  bool success = invertedMvp.Invert();
+
+  // Convert to GL coordinates
+  Vector4 screenPos(screenX - static_cast<float>(viewport.x), static_cast<float>(viewport.height) - screenY - static_cast<float>(viewport.y), 0.f, 1.f);
+
+  Vector4 nearPos;
+  if(success)
+  {
+    success = Unproject(screenPos, invertedMvp, static_cast<float>(viewport.width), static_cast<float>(viewport.height), nearPos);
+  }
+
+  Vector4 farPos;
+  if(success)
+  {
+    screenPos.z = 1.0f;
+    success     = Unproject(screenPos, invertedMvp, static_cast<float>(viewport.width), static_cast<float>(viewport.height), farPos);
+  }
+
+  if(success)
+  {
+    Vector4 local;
+    if(XyPlaneIntersect(nearPos, farPos, local))
+    {
+      Vector3 size = currentSize;
+      localX       = local.x + size.x * 0.5f;
+      localY       = local.y + size.y * 0.5f;
+    }
+    else
+    {
+      success = false;
+    }
+  }
+
+  return success;
+}
+
+bool ConvertScreenToLocalRenderTask(
+  const RenderTask& renderTask,
+  const Matrix&     worldMatrix,
+  const Vector3&    currentSize,
+  float&            localX,
+  float&            localY,
+  float             screenX,
+  float             screenY)
+{
+  bool         success = false;
+  CameraActor* camera  = renderTask.GetCameraActor();
+  if(camera)
+  {
+    Viewport viewport;
+    renderTask.GetViewport(viewport);
+
+    // need to translate coordinates to render tasks coordinate space
+    Vector2 converted(screenX, screenY);
+    if(renderTask.TranslateCoordinates(converted))
+    {
+      success = ConvertScreenToLocal(camera->GetViewMatrix(), camera->GetProjectionMatrix(), worldMatrix, currentSize, viewport, localX, localY, converted.x, converted.y);
+    }
+  }
+  return success;
+}
+
+bool ConvertScreenToLocalRenderTaskList(
+  const RenderTaskList& renderTaskList,
+  const Matrix&         worldMatrix,
+  const Vector3&        currentSize,
+  float&                localX,
+  float&                localY,
+  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(ConvertScreenToLocalRenderTask(*task, worldMatrix, currentSize, localX, localY, screenX, screenY))
+    {
+      // found a task where this conversion was ok so return
+      return true;
+    }
+  }
+  return false;
+};
+
+} // namespace Dali::Internal
diff --git a/dali/internal/event/actors/actor-coords.h b/dali/internal/event/actors/actor-coords.h
new file mode 100644 (file)
index 0000000..658d3e9
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef DALI_INTERNAL_EVENT_ACTORS_ACTOR_COORDS_H
+#define DALI_INTERNAL_EVENT_ACTORS_ACTOR_COORDS_H
+
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali/internal/event/actors/camera-actor-impl.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
+#include <dali/internal/event/render-tasks/render-task-list-impl.h>
+#include <dali/public-api/math/matrix.h>
+#include <dali/public-api/math/vector3.h>
+#include <dali/public-api/math/viewport.h>
+
+namespace Dali::Internal
+{
+/**
+ * Convert screen coordinates to local coordinates
+ *
+ * @param[in] viewMatrix The view matrix used to display this entity
+ * @param[in] projectionMatrix The projection matrix used to display this entity
+ * @param[in] worldMatrix The world matrix of this entity
+ * @param[in] viewport The viewport used for drawing
+ * @param[in] currentSize The 2d bounding box for this entity
+ * @param[out] localX The local X coordinate
+ * @param[out] localY The local Y coordinate
+ * @param[in] screenX The screen X coordinate
+ * @param[in] screenY The screen Y coordinate
+ * @return true if the conversion was successful
+ */
+bool ConvertScreenToLocal(const Matrix&   viewMatrix,
+                          const Matrix&   projectionMatrix,
+                          const Matrix&   worldMatrix,
+                          const Vector3&  currentSize,
+                          const Viewport& viewport,
+                          float&          localX,
+                          float&          localY,
+                          float           screenX,
+                          float           screenY);
+
+/**
+ * Convert screen coordinates to local coordinates
+ *
+ * @param[in] renderTask The render task used to display this entity
+ * @param[in] worldMatrix The world matrix of this entity
+ * @param[in] currentSize The 2d bounding box for this entity
+ * @param[out] localX The local X coordinate
+ * @param[out] localY The local Y coordinate
+ * @param[in] screenX The screen X coordinate
+ * @param[in] screenY The screen Y coordinate
+ * @return true if the conversion was successful
+ */
+bool ConvertScreenToLocalRenderTask(
+  const RenderTask& renderTask,
+  const Matrix&     worldMatrix,
+  const Vector3&    currentSize,
+  float&            localX,
+  float&            localY,
+  float             screenX,
+  float             screenY);
+
+/**
+ * Convert screen coordinates to local coordinates
+ * Search through the given renderTaskList to check if this entity can be converted
+ *
+ * @param[in] renderTaskList The render task list to search
+ * @param[in] worldMatrix The world matrix of this entity
+ * @param[in] currentSize The 2d bounding box for this entity
+ * @param[out] localX The local X coordinate
+ * @param[out] localY The local Y coordinate
+ * @param[in] screenX The screen X coordinate
+ * @param[in] screenY The screen Y coordinate
+ * @return true if the conversion was successful
+ */
+bool ConvertScreenToLocalRenderTaskList(
+  const RenderTaskList& renderTaskList,
+  const Matrix&         worldMatrix,
+  const Vector3&        currentSize,
+  float&                localX,
+  float&                localY,
+  float                 screenX,
+  float                 screenY);
+
+} // namespace Dali::Internal
+
+#endif // DALI_INTERNAL_EVENT_ACTORS_ACTOR_COORDS_H
index 3fd4f3e..decf85a 100644 (file)
 
 #include <dali/integration-api/debug.h>
 
+#include <dali/internal/event/actors/actor-coords.h>
 #include <dali/internal/event/actors/actor-parent.h>
 #include <dali/internal/event/actors/actor-property-handler.h>
 #include <dali/internal/event/actors/actor-relayouter.h>
 #include <dali/internal/event/actors/camera-actor-impl.h>
 #include <dali/internal/event/common/event-thread-services.h>
-#include <dali/internal/event/common/projection.h>
 #include <dali/internal/event/common/property-helper.h>
 #include <dali/internal/event/common/scene-impl.h>
 #include <dali/internal/event/common/stage-impl.h>
@@ -256,60 +256,6 @@ void EmitSignal(Actor& actor, Signal& signal, Param... params)
   }
 }
 
-bool ScreenToLocalInternal(
-  const Matrix&   viewMatrix,
-  const Matrix&   projectionMatrix,
-  const Matrix&   worldMatrix,
-  const Viewport& viewport,
-  const Vector3&  currentSize,
-  float&          localX,
-  float&          localY,
-  float           screenX,
-  float           screenY)
-{
-  // Get the ModelView matrix
-  Matrix modelView;
-  Matrix::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);
-  bool success = invertedMvp.Invert();
-
-  // Convert to GL coordinates
-  Vector4 screenPos(screenX - static_cast<float>(viewport.x), static_cast<float>(viewport.height) - screenY - static_cast<float>(viewport.y), 0.f, 1.f);
-
-  Vector4 nearPos;
-  if(success)
-  {
-    success = Unproject(screenPos, invertedMvp, static_cast<float>(viewport.width), static_cast<float>(viewport.height), nearPos);
-  }
-
-  Vector4 farPos;
-  if(success)
-  {
-    screenPos.z = 1.0f;
-    success     = Unproject(screenPos, invertedMvp, static_cast<float>(viewport.width), static_cast<float>(viewport.height), farPos);
-  }
-
-  if(success)
-  {
-    Vector4 local;
-    if(XyPlaneIntersect(nearPos, farPos, local))
-    {
-      Vector3 size = currentSize;
-      localX       = local.x + size.x * 0.5f;
-      localY       = local.y + size.y * 0.5f;
-    }
-    else
-    {
-      success = false;
-    }
-  }
-
-  return success;
-}
-
 } // unnamed namespace
 
 ActorPtr Actor::New()
@@ -1141,54 +1087,17 @@ void Actor::SetDrawMode(DrawMode::Type drawMode)
 
 bool Actor::ScreenToLocal(float& localX, float& localY, float screenX, float screenY) const
 {
-  // only valid when on-stage
-  if(mScene && OnScene())
-  {
-    const RenderTaskList& taskList = mScene->GetRenderTaskList();
-
-    Vector2 converted(screenX, screenY);
-
-    // do a reverse traversal of all lists (as the default onscreen one is typically the last one)
-    uint32_t taskCount = taskList.GetTaskCount();
-    for(uint32_t i = taskCount; i > 0; --i)
-    {
-      RenderTaskPtr task = taskList.GetTask(i - 1);
-      if(ScreenToLocal(*task, localX, localY, screenX, screenY))
-      {
-        // found a task where this conversion was ok so return
-        return true;
-      }
-    }
-  }
-  return false;
+  return mScene && OnScene() && ConvertScreenToLocalRenderTaskList(mScene->GetRenderTaskList(), GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
 }
 
 bool Actor::ScreenToLocal(const RenderTask& renderTask, float& localX, float& localY, float screenX, float screenY) const
 {
-  bool retval = false;
-  // only valid when on-stage
-  if(OnScene())
-  {
-    CameraActor* camera = renderTask.GetCameraActor();
-    if(camera)
-    {
-      Viewport viewport;
-      renderTask.GetViewport(viewport);
-
-      // need to translate coordinates to render tasks coordinate space
-      Vector2 converted(screenX, screenY);
-      if(renderTask.TranslateCoordinates(converted))
-      {
-        retval = ScreenToLocal(camera->GetViewMatrix(), camera->GetProjectionMatrix(), viewport, localX, localY, converted.x, converted.y);
-      }
-    }
-  }
-  return retval;
+  return OnScene() && ConvertScreenToLocalRenderTask(renderTask, GetNode().GetWorldMatrix(0), GetCurrentSize(), localX, localY, screenX, screenY);
 }
 
 bool Actor::ScreenToLocal(const Matrix& viewMatrix, const Matrix& projectionMatrix, const Viewport& viewport, float& localX, float& localY, float screenX, float screenY) const
 {
-  return OnScene() && ScreenToLocalInternal(viewMatrix, projectionMatrix, GetNode().GetWorldMatrix(0), viewport, GetCurrentSize(), localX, localY, screenX, screenY);
+  return OnScene() && ConvertScreenToLocal(viewMatrix, projectionMatrix, GetNode().GetWorldMatrix(0), GetCurrentSize(), viewport, localX, localY, screenX, screenY);
 }
 
 ActorGestureData& Actor::GetGestureData()
index a833158..0345097 100644 (file)
@@ -12,8 +12,8 @@ SET( internal_src_files
   ${internal_src_dir}/common/image-attributes.cpp
   ${internal_src_dir}/common/fixed-size-memory-pool.cpp
   ${internal_src_dir}/common/const-string.cpp
-
   ${internal_src_dir}/event/actors/actor-impl.cpp
+  ${internal_src_dir}/event/actors/actor-coords.cpp
   ${internal_src_dir}/event/actors/actor-property-handler.cpp
   ${internal_src_dir}/event/actors/actor-relayouter.cpp
   ${internal_src_dir}/event/actors/actor-parent-impl.cpp