From: David Steele Date: Wed, 20 Oct 2021 13:40:37 +0000 (+0100) Subject: Refactored Actor screen to local conversion X-Git-Tag: dali_2.0.49~3 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-core.git;a=commitdiff_plain;h=a42d8f30cafd2c74a3146607f13ab6aa7ca0c3f6 Refactored Actor screen to local conversion Change-Id: I145644d1702e9e3f9f6571aff5651c811abbf39c --- diff --git a/dali/internal/event/actors/actor-coords.cpp b/dali/internal/event/actors/actor-coords.cpp new file mode 100644 index 0000000..55b8bb1 --- /dev/null +++ b/dali/internal/event/actors/actor-coords.cpp @@ -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 +#include + +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(viewport.x), static_cast(viewport.height) - screenY - static_cast(viewport.y), 0.f, 1.f); + + Vector4 nearPos; + if(success) + { + success = Unproject(screenPos, invertedMvp, static_cast(viewport.width), static_cast(viewport.height), nearPos); + } + + Vector4 farPos; + if(success) + { + screenPos.z = 1.0f; + success = Unproject(screenPos, invertedMvp, static_cast(viewport.width), static_cast(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 index 0000000..658d3e9 --- /dev/null +++ b/dali/internal/event/actors/actor-coords.h @@ -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 +#include +#include +#include +#include +#include + +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 diff --git a/dali/internal/event/actors/actor-impl.cpp b/dali/internal/event/actors/actor-impl.cpp index 3fd4f3e..decf85a 100644 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -37,12 +37,12 @@ #include +#include #include #include #include #include #include -#include #include #include #include @@ -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(viewport.x), static_cast(viewport.height) - screenY - static_cast(viewport.y), 0.f, 1.f); - - Vector4 nearPos; - if(success) - { - success = Unproject(screenPos, invertedMvp, static_cast(viewport.width), static_cast(viewport.height), nearPos); - } - - Vector4 farPos; - if(success) - { - screenPos.z = 1.0f; - success = Unproject(screenPos, invertedMvp, static_cast(viewport.width), static_cast(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() diff --git a/dali/internal/file.list b/dali/internal/file.list index a833158..0345097 100644 --- a/dali/internal/file.list +++ b/dali/internal/file.list @@ -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