From 6e1aebb198e5075227e4656ed5a5cef02c99139a Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Tue, 4 Oct 2022 18:17:53 +0900 Subject: [PATCH] [Tizen] Create ProjectionDirection property at CameraActor This reverts commit da848111d06ada79d78b1b26aaf49746e1e37ae6. Change-Id: I30b4e5ad9a110347bacec5850d14a0bb122f96c6 --- automated-tests/src/dali/utc-Dali-CameraActor.cpp | 123 +++++++++++++++++++++- dali/devel-api/actors/camera-actor-devel.h | 27 ++++- dali/internal/event/actors/camera-actor-impl.cpp | 71 ++++++++++++- dali/internal/event/actors/camera-actor-impl.h | 39 ++++--- 4 files changed, 239 insertions(+), 21 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-CameraActor.cpp b/automated-tests/src/dali/utc-Dali-CameraActor.cpp index 7063dca..7a37225 100644 --- a/automated-tests/src/dali/utc-Dali-CameraActor.cpp +++ b/automated-tests/src/dali/utc-Dali-CameraActor.cpp @@ -275,7 +275,7 @@ int UtcDaliCameraActorSetGetTypeP(void) actor.SetType(Dali::Camera::LOOK_AT_TARGET); DALI_TEST_EQUALS(actor.GetType(), Dali::Camera::LOOK_AT_TARGET, TEST_LOCATION); - Dali::Camera::Type cameraType = actor.GetProperty(CameraActor::Property::TYPE); + Dali::Camera::Type cameraType = actor.GetProperty(CameraActor::Property::TYPE); Dali::Camera::Type currentCameraType = actor.GetCurrentProperty(CameraActor::Property::TYPE); DALI_TEST_EQUALS(Camera::LOOK_AT_TARGET, cameraType, TEST_LOCATION); DALI_TEST_EQUALS(Camera::LOOK_AT_TARGET, currentCameraType, TEST_LOCATION); @@ -1229,7 +1229,6 @@ int UtcDaliCameraActorSetCameraOnScene(void) DALI_TEST_EQUALS(TEST_FAR_PLANE_DISTANCE, actor.GetFarClippingPlane(), FLOAT_EPSILON, TEST_LOCATION); DALI_TEST_EQUALS(false, actor.GetInvertYAxis(), TEST_LOCATION); - Dali::Camera::Type cameraType = actor.GetProperty(CameraActor::Property::TYPE); DALI_TEST_EQUALS(cameraType, Camera::LOOK_AT_TARGET, TEST_LOCATION); @@ -1801,6 +1800,125 @@ int UtcDaliCameraActorReflectionByPlane(void) END_TEST; } +int UtcDaliCameraActorProjectionDirection(void) +{ + TestApplication application; + + Integration::Scene stage = application.GetScene(); + Vector2 stageSize = stage.GetSize(); + + CameraActor defaultCameraActor = stage.GetRenderTaskList().GetTask(0).GetCameraActor(); + CameraActor expectCameraActor1 = CameraActor::New(stageSize); + CameraActor expectCameraActor2 = CameraActor::New(stageSize); + CameraActor expectCameraActor3 = CameraActor::New(stageSize); + + float fieldOfView = defaultCameraActor.GetFieldOfView(); + float aspectRatio = defaultCameraActor.GetAspectRatio(); + + // Calculate expect camera 1's fov. + float anotherFieldOfView = 2.0f * std::atan(std::tan(fieldOfView * 0.5f) / aspectRatio); + expectCameraActor1.SetFieldOfView(anotherFieldOfView); + + // Calculate expect camera 2's fov and aspect ratio. + float anotherFieldOfView2 = 2.0f * std::atan(std::tan(fieldOfView * 0.5f) * aspectRatio); + float anotherAspectRatio = 1.0f / aspectRatio; + expectCameraActor2.SetFieldOfView(anotherFieldOfView2); + expectCameraActor2.SetAspectRatio(anotherAspectRatio); + + // Calculate expect camera 3's aspect raio + expectCameraActor3.SetAspectRatio(anotherAspectRatio); + + stage.Add(expectCameraActor1); + stage.Add(expectCameraActor2); + stage.Add(expectCameraActor3); + + application.SendNotification(); + application.Render(); + application.SendNotification(); + application.Render(); + + // Test default projection direction is VERTICAL + DALI_TEST_EQUALS(defaultCameraActor.GetProperty(Dali::DevelCameraActor::Property::PROJECTION_DIRECTION), static_cast(Dali::DevelCameraActor::ProjectionDirection::VERTICAL), TEST_LOCATION); + + Matrix matrixBefore, matrixAfter; + Matrix matrixExpect1, matrixExpect2, matrixExpect3; + + defaultCameraActor.GetProperty(CameraActor::CameraActor::Property::PROJECTION_MATRIX).Get(matrixBefore); + expectCameraActor1.GetProperty(CameraActor::CameraActor::Property::PROJECTION_MATRIX).Get(matrixExpect1); + expectCameraActor2.GetProperty(CameraActor::CameraActor::Property::PROJECTION_MATRIX).Get(matrixExpect2); + expectCameraActor3.GetProperty(CameraActor::CameraActor::Property::PROJECTION_MATRIX).Get(matrixExpect3); + + tet_printf("Check ProjectionDirection::HORIZONTAL\n"); + + defaultCameraActor.SetProperty(Dali::DevelCameraActor::Property::PROJECTION_DIRECTION, Dali::DevelCameraActor::ProjectionDirection::HORIZONTAL); + DALI_TEST_EQUALS(defaultCameraActor.GetProperty(Dali::DevelCameraActor::Property::PROJECTION_DIRECTION), static_cast(Dali::DevelCameraActor::ProjectionDirection::HORIZONTAL), TEST_LOCATION); + // NOTE : ProjectionDirection doesn't change camera actor's FieldOfView and AspectRatio value.) + DALI_TEST_EQUALS(defaultCameraActor.GetFieldOfView(), fieldOfView, TEST_LOCATION); + DALI_TEST_EQUALS(defaultCameraActor.GetAspectRatio(), aspectRatio, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + application.SendNotification(); + application.Render(); + + defaultCameraActor.GetProperty(CameraActor::CameraActor::Property::PROJECTION_MATRIX).Get(matrixAfter); + + // Check camera's ProjectionMatrix same as expect camera 1's ProjectionMatrix. + DALI_TEST_EQUALS(matrixAfter, matrixExpect1, Dali::Math::MACHINE_EPSILON_10000, TEST_LOCATION); + + tet_printf("Check ProjectionDirection::HORIZONTAL + Change aspect ratio\n"); + + defaultCameraActor.SetAspectRatio(anotherAspectRatio); + DALI_TEST_EQUALS(defaultCameraActor.GetAspectRatio(), anotherAspectRatio, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + application.SendNotification(); + application.Render(); + + defaultCameraActor.GetProperty(CameraActor::CameraActor::Property::PROJECTION_MATRIX).Get(matrixAfter); + + // Check camera's ProjectionMatrix same as expect camera 2's ProjectionMatrix. + DALI_TEST_EQUALS(matrixAfter, matrixExpect2, Dali::Math::MACHINE_EPSILON_10000, TEST_LOCATION); + + tet_printf("Check ProjectionDirection::HORIZONTAL + Change aspect ratio + Change fov\n"); + + defaultCameraActor.SetFieldOfView(anotherFieldOfView); + DALI_TEST_EQUALS(defaultCameraActor.GetFieldOfView(), anotherFieldOfView, TEST_LOCATION); + DALI_TEST_EQUALS(defaultCameraActor.GetAspectRatio(), anotherAspectRatio, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + application.SendNotification(); + application.Render(); + + defaultCameraActor.GetProperty(CameraActor::CameraActor::Property::PROJECTION_MATRIX).Get(matrixAfter); + + // Check camera's ProjectionMatrix same as expect camera 3's ProjectionMatrix. + DALI_TEST_EQUALS(matrixAfter, matrixExpect3, Dali::Math::MACHINE_EPSILON_10000, TEST_LOCATION); + + tet_printf("Check ProjectionDirection::VERTICAL, the original camera\n"); + + defaultCameraActor.SetProperty(Dali::DevelCameraActor::Property::PROJECTION_DIRECTION, Dali::DevelCameraActor::ProjectionDirection::VERTICAL); + defaultCameraActor.SetFieldOfView(fieldOfView); + defaultCameraActor.SetAspectRatio(aspectRatio); + DALI_TEST_EQUALS(defaultCameraActor.GetProperty(Dali::DevelCameraActor::Property::PROJECTION_DIRECTION), static_cast(Dali::DevelCameraActor::ProjectionDirection::VERTICAL), TEST_LOCATION); + DALI_TEST_EQUALS(defaultCameraActor.GetFieldOfView(), fieldOfView, TEST_LOCATION); + DALI_TEST_EQUALS(defaultCameraActor.GetAspectRatio(), aspectRatio, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + application.SendNotification(); + application.Render(); + + defaultCameraActor.GetProperty(CameraActor::CameraActor::Property::PROJECTION_MATRIX).Get(matrixAfter); + + // Check vertical camera's ProjectionMatrix same as original ProjectionMatrix. + DALI_TEST_EQUALS(matrixAfter, matrixBefore, Dali::Math::MACHINE_EPSILON_10000, TEST_LOCATION); + + END_TEST; +} + int UtcDaliCameraActorGetAspectRatioNegative(void) { TestApplication application; @@ -2236,7 +2354,6 @@ int UtcDaliCameraActorCulling01(void) END_TEST; } - int UtcDaliCameraActorSetProperty(void) { TestApplication application; diff --git a/dali/devel-api/actors/camera-actor-devel.h b/dali/devel-api/actors/camera-actor-devel.h index 563118e..e1a0a4c 100644 --- a/dali/devel-api/actors/camera-actor-devel.h +++ b/dali/devel-api/actors/camera-actor-devel.h @@ -2,7 +2,7 @@ #define DALI_CAMERA_ACTOR_DEVEL_H /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -24,6 +24,15 @@ namespace Dali { namespace DevelCameraActor { +/** + * @brief Enumeration for projection direction. + */ +enum ProjectionDirection +{ + VERTICAL, ///< Field of view direction based on vertial. + HORIZONTAL, ///< Field of view direction based on horizontal. +}; + namespace Property { enum @@ -33,7 +42,21 @@ enum * @details Type Property::VECTOR4 * @note Optional */ - REFLECTION_PLANE = CameraActor::Property::INVERT_Y_AXIS + 1 + REFLECTION_PLANE = CameraActor::Property::INVERT_Y_AXIS + 1, + + /** + * @brief Determine basic direction of projection relative properties. + * It will be used when we need to calculate some values relative with aspect ratio automatically. + * + * For example, if aspect ratio is 4:3 and set fieldOfView as 60 degree. + * If ProjectionDirection::VERTICAL, basic direction is vertical. so, FoV of horizontal direction become ~75.2 degree + * If ProjectionDirection::HORIZONTAL, basic direction is horizontal. so, FoV of vertical direction become ~46.8 degree + * + * @details Type Property::INT + * @note This property doesn't change FieldOfView value automatically. So result scene might be changed. + * @note Default is ProjectionDirection::VERTICAL. + */ + PROJECTION_DIRECTION, }; } // Namespace Property diff --git a/dali/internal/event/actors/camera-actor-impl.cpp b/dali/internal/event/actors/camera-actor-impl.cpp index 79971ff..b444d9f 100644 --- a/dali/internal/event/actors/camera-actor-impl.cpp +++ b/dali/internal/event/actors/camera-actor-impl.cpp @@ -134,6 +134,30 @@ void BuildOrthoPickingRay(const Matrix& viewMatrix, rayDir.w = 1.0f; } +/** + * @brief Convert from vertical FoV to horizontal FoV + * + * @param aspectRatio aspect ratio. + * @param verticalFov Vertical field of view by radian. + * @return Horizontal field of view by radian. + */ +inline float ConvertFovFromVerticalToHorizontal(float aspectRatio, float verticalFov) +{ + return 2.0f * std::atan(std::tan(verticalFov * 0.5f) * aspectRatio); +} + +/** + * @brief Convert from horizontal FoV to vertical FoV + * + * @param aspectRatio aspect ratio. + * @param horizontalFov Horizontal field of view by radian. + * @return Vertical field of view by radian. + */ +inline float ConvertFovFromHorizontalToVertical(float aspectRatio, float horizontalFov) +{ + return 2.0f * std::atan(std::tan(horizontalFov * 0.5f) / aspectRatio); +} + } // namespace CameraActorPtr CameraActor::New(const Size& size) @@ -159,6 +183,7 @@ CameraActor::CameraActor(const SceneGraph::Node& node) mTarget(SceneGraph::Camera::DEFAULT_TARGET_POSITION), mType(SceneGraph::Camera::DEFAULT_TYPE), mProjectionMode(SceneGraph::Camera::DEFAULT_MODE), + mProjectionDirection(Dali::DevelCameraActor::ProjectionDirection::VERTICAL), mFieldOfView(SceneGraph::Camera::DEFAULT_FIELD_OF_VIEW), mAspectRatio(SceneGraph::Camera::DEFAULT_ASPECT_RATIO), mNearClippingPlane(SceneGraph::Camera::DEFAULT_NEAR_CLIPPING_PLANE), @@ -269,6 +294,25 @@ Dali::Camera::ProjectionMode CameraActor::GetProjectionMode() const return mProjectionMode; } +void CameraActor::SetProjectionDirection(Dali::DevelCameraActor::ProjectionDirection direction) +{ + mPropertyChanged = true; + if(direction != mProjectionDirection) + { + mProjectionDirection = direction; + + // Update update side FoV value. + float verticalFieldOfView = mFieldOfView; + if(DALI_UNLIKELY(mProjectionDirection == DevelCameraActor::HORIZONTAL)) + { + verticalFieldOfView = ConvertFovFromHorizontalToVertical(mAspectRatio, mFieldOfView); + } + + // sceneObject is being used in a separate thread; queue a message to set + SetFieldOfViewMessage(GetEventThreadServices(), *mSceneObject, verticalFieldOfView); + } +} + void CameraActor::SetFieldOfView(float fieldOfView) { mPropertyChanged = true; @@ -276,8 +320,14 @@ void CameraActor::SetFieldOfView(float fieldOfView) { mFieldOfView = fieldOfView; + float verticalFieldOfView = mFieldOfView; + if(DALI_UNLIKELY(mProjectionDirection == DevelCameraActor::HORIZONTAL)) + { + verticalFieldOfView = ConvertFovFromHorizontalToVertical(mAspectRatio, mFieldOfView); + } + // sceneObject is being used in a separate thread; queue a message to set - SetFieldOfViewMessage(GetEventThreadServices(), *mSceneObject, mFieldOfView); + SetFieldOfViewMessage(GetEventThreadServices(), *mSceneObject, verticalFieldOfView); } } @@ -295,6 +345,14 @@ void CameraActor::SetAspectRatio(float aspectRatio) // sceneObject is being used in a separate thread; queue a message to set SetAspectRatioMessage(GetEventThreadServices(), *mSceneObject, mAspectRatio); + + if(DALI_UNLIKELY(mProjectionDirection == DevelCameraActor::HORIZONTAL)) + { + float verticalFieldOfView = ConvertFovFromHorizontalToVertical(mAspectRatio, mFieldOfView); + + // sceneObject is being used in a separate thread; queue a message to set + SetFieldOfViewMessage(GetEventThreadServices(), *mSceneObject, verticalFieldOfView); + } } } @@ -660,6 +718,12 @@ void CameraActor::SetDefaultProperty(Property::Index index, const Property::Valu SetReflectByPlane(propertyValue.Get()); break; } + case Dali::DevelCameraActor::Property::PROJECTION_DIRECTION: + { + Dali::DevelCameraActor::ProjectionDirection projectionDirection = Dali::DevelCameraActor::ProjectionDirection(propertyValue.Get()); + SetProjectionDirection(projectionDirection); + break; + } default: { @@ -752,6 +816,11 @@ Property::Value CameraActor::GetDefaultProperty(Property::Index index) const ret = mInvertYAxis; break; } + case Dali::DevelCameraActor::Property::PROJECTION_DIRECTION: + { + ret = mProjectionDirection; + break; + } } // switch(index) } diff --git a/dali/internal/event/actors/camera-actor-impl.h b/dali/internal/event/actors/camera-actor-impl.h index 2869b59..a817811 100644 --- a/dali/internal/event/actors/camera-actor-impl.h +++ b/dali/internal/event/actors/camera-actor-impl.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_CAMERA_ACTOR_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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 @@ */ // INTERNAL INCLUES +#include #include #include #include @@ -89,6 +90,13 @@ public: Dali::Camera::ProjectionMode GetProjectionMode() const; /** + * @brief Set the projection direction + * + * @param[in] direction Direction of projection + */ + void SetProjectionDirection(Dali::DevelCameraActor::ProjectionDirection direction); + + /** * @copydoc Dali::CameraActor::SetFieldOfView */ void SetFieldOfView(float fieldOfView); @@ -259,20 +267,21 @@ private: private: // Data const SceneGraph::Camera* mSceneObject; ///< Not owned - Vector3 mTarget; - Vector2 mCanvasSize; - Dali::Camera::Type mType; - Dali::Camera::ProjectionMode mProjectionMode; - float mFieldOfView; - float mAspectRatio; - float mNearClippingPlane; - float mFarClippingPlane; - float mLeftClippingPlane; - float mRightClippingPlane; - float mTopClippingPlane; - float mBottomClippingPlane; - bool mInvertYAxis; - bool mPropertyChanged; + Vector3 mTarget; + Vector2 mCanvasSize; + Dali::Camera::Type mType; + Dali::Camera::ProjectionMode mProjectionMode; + Dali::DevelCameraActor::ProjectionDirection mProjectionDirection; + float mFieldOfView; + float mAspectRatio; + float mNearClippingPlane; + float mFarClippingPlane; + float mLeftClippingPlane; + float mRightClippingPlane; + float mTopClippingPlane; + float mBottomClippingPlane; + bool mInvertYAxis; + bool mPropertyChanged; }; } // namespace Internal -- 2.7.4