/*
- * 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.
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;
+}
/*
- * 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.
#include <dali/devel-api/events/hit-test-algorithm.h>
// INTERNAL INCLUDES
+#include <dali/internal/event/actors/camera-actor-impl.h>
#include <dali/internal/event/common/scene-impl.h>
#include <dali/internal/event/common/stage-impl.h>
#include <dali/internal/event/events/hit-test-algorithm-impl.h>
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<float>(viewport.x) ||
+ screenCoordinates.x > static_cast<float>(viewport.x + viewport.width) ||
+ screenCoordinates.y < static_cast<float>(viewport.y) ||
+ screenCoordinates.y > static_cast<float>(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
#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.
*/
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