From: David Steele Date: Thu, 16 Mar 2023 17:47:29 +0000 (+0000) Subject: Merge "Add BuildPickingRay to devel api" into devel/master X-Git-Tag: dali_2.2.18~1 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-core.git;a=commitdiff_plain;h=c4750afbf79f15bf71e2aa8ef54f84750463aae2;hp=100744f9f2b356c09ea16ea91e19ff3502d4b192 Merge "Add BuildPickingRay to devel api" into devel/master --- diff --git a/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp b/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp index 4d17b65..a9167e0 100644 --- a/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp +++ b/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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. @@ -628,4 +628,75 @@ int UtcDaliHitTestAlgorithmOrder(void) DALI_TEST_CHECK(results.actor == green); END_TEST; -} \ No newline at end of file +} + +int UtcDaliHitTestAlgorithmBuildPickingRay01(void) +{ + TestApplication application; + tet_infoline("Testing Dali::HitTestAlgorithm::BuildPickingRay positive test"); + + Stage stage = Stage::GetCurrent(); + RenderTaskList renderTaskList = stage.GetRenderTaskList(); + RenderTask defaultRenderTask = renderTaskList.GetTask(0u); + Dali::CameraActor cameraActor = defaultRenderTask.GetCameraActor(); + + Vector2 stageSize(stage.GetSize()); + + Vector2 actorSize(stageSize * 0.5f); + // Create two actors with half the size of the stage and set them to be overlapping + Actor blue = Actor::New(); + blue.SetProperty(Actor::Property::NAME, "Blue"); + blue.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); + blue.SetProperty(Actor::Property::PARENT_ORIGIN, AnchorPoint::CENTER); + blue.SetProperty(Actor::Property::SIZE, actorSize); + + Actor green = Actor::New(); + green.SetProperty(Actor::Property::NAME, "Green"); + green.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); + green.SetProperty(Actor::Property::PARENT_ORIGIN, AnchorPoint::CENTER); + green.SetProperty(Actor::Property::SIZE, actorSize); + + // Add the actors to the view + stage.Add(blue); + stage.Add(green); + + // Render and notify + application.SendNotification(); + application.Render(0); + + Vector2 screenCoords(stageSize * 0.5f); // touch center of screen + Vector3 origin; + Vector3 direction; + bool built = HitTestAlgorithm::BuildPickingRay(defaultRenderTask, screenCoords, origin, direction); + + Vector3 camPos = cameraActor[Actor::Property::POSITION]; + DALI_TEST_EQUALS(built, true, TEST_LOCATION); + DALI_TEST_EQUALS(camPos, origin, TEST_LOCATION); + direction.Normalize(); + DALI_TEST_EQUALS(direction, -Vector3::ZAXIS, 0.01f, TEST_LOCATION); + + screenCoords.x = stageSize.width * 0.75f; + built = HitTestAlgorithm::BuildPickingRay(defaultRenderTask, screenCoords, origin, direction); + DALI_TEST_EQUALS(built, true, TEST_LOCATION); + DALI_TEST_EQUALS(camPos, origin, TEST_LOCATION); + direction.Normalize(); + DALI_TEST_EQUALS(direction, Vector3(0.075f, 0.0f, -1.0f), 0.01f, TEST_LOCATION); + + screenCoords.x = 0.0f; + screenCoords.y = 0.0f; + built = HitTestAlgorithm::BuildPickingRay(defaultRenderTask, screenCoords, origin, direction); + DALI_TEST_EQUALS(built, true, TEST_LOCATION); + DALI_TEST_EQUALS(camPos, origin, TEST_LOCATION); + direction.Normalize(); + DALI_TEST_EQUALS(direction, Vector3(-0.144f, -0.24f, -0.96f), 0.01f, TEST_LOCATION); + + screenCoords.x = stageSize.width; + screenCoords.y = stageSize.height; + built = HitTestAlgorithm::BuildPickingRay(defaultRenderTask, screenCoords, origin, direction); + DALI_TEST_EQUALS(built, true, TEST_LOCATION); + DALI_TEST_EQUALS(camPos, origin, TEST_LOCATION); + direction.Normalize(); + DALI_TEST_EQUALS(direction, Vector3(0.144f, 0.24f, -0.96f), 0.01f, TEST_LOCATION); + + END_TEST; +} diff --git a/dali/devel-api/events/hit-test-algorithm.cpp b/dali/devel-api/events/hit-test-algorithm.cpp index 5f0ba26..e9e3e7f 100644 --- a/dali/devel-api/events/hit-test-algorithm.cpp +++ b/dali/devel-api/events/hit-test-algorithm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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. @@ -19,6 +19,7 @@ #include // INTERNAL INCLUDES +#include #include #include #include @@ -34,6 +35,30 @@ bool HitTest(Stage stage, const Vector2& screenCoordinates, Results& results, Hi return Internal::HitTestAlgorithm::HitTest(stageImpl.GetSize(), stageImpl.GetRenderTaskList(), stageImpl.GetLayerList(), screenCoordinates, results, func); } +bool BuildPickingRay(RenderTask renderTask, const Vector2& screenCoordinates, Vector3& origin, Vector3& direction) +{ + Viewport viewport = renderTask.GetViewport(); + if(screenCoordinates.x < static_cast(viewport.x) || + screenCoordinates.x > static_cast(viewport.x + viewport.width) || + screenCoordinates.y < static_cast(viewport.y) || + screenCoordinates.y > static_cast(viewport.y + viewport.height)) + { + // The screen coordinate is outside the viewport of render task. The viewport clips all layers. + return false; + } + CameraActor cameraActor = renderTask.GetCameraActor(); + Internal::CameraActor& cameraActorImpl = GetImplementation(cameraActor); + Vector4 rayOrigin; + Vector4 rayDirection; + bool success = cameraActorImpl.BuildPickingRay(screenCoordinates, viewport, rayOrigin, rayDirection); + if(success) + { + origin = Vector3(rayOrigin.x, rayOrigin.y, rayOrigin.z); + direction = Vector3(rayDirection.x, rayDirection.y, rayDirection.z); + } + return success; +} + } // namespace HitTestAlgorithm } // namespace Dali diff --git a/dali/devel-api/events/hit-test-algorithm.h b/dali/devel-api/events/hit-test-algorithm.h index 1417f6e..cc7aad9 100644 --- a/dali/devel-api/events/hit-test-algorithm.h +++ b/dali/devel-api/events/hit-test-algorithm.h @@ -2,7 +2,7 @@ #define __DALI_HIT_TEST_ALGORITHM_H__ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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. @@ -143,6 +143,17 @@ using HitTestFunction = bool (*)(Actor, TraverseType); */ DALI_CORE_API bool HitTest(Stage stage, const Vector2& screenCoordinates, Results& results, HitTestFunction func); +/** + * @brief Given screen coordinates, this method returns the camera origin in world coordinates and the direction of the picking ray in world-space. + * + * @param[in] renderTask The render task owning a camera. + * @param[in] screenCoordinates The screen coordinates. + * @param[out] origin The camera origin in world coordinates + * @param[out] direction The direction of the picking ray in world-space + * @return true if the screen coordinates are inside the render task's viewport + */ +DALI_CORE_API bool BuildPickingRay(RenderTask renderTask, const Vector2& screenCoordinates, Vector3& origin, Vector3& direction); + } // namespace HitTestAlgorithm } // namespace Dali