[Tizen] Create ProjectionDirection property at CameraActor accepted/tizen_7.0_unified_hotfix tizen_7.0_hotfix accepted/tizen/7.0/unified/hotfix/20221116.105933 accepted/tizen/unified/20221005.144442 tizen_7.0_m2_release
authorEunki, Hong <eunkiki.hong@samsung.com>
Tue, 4 Oct 2022 09:17:53 +0000 (18:17 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Tue, 4 Oct 2022 09:17:58 +0000 (18:17 +0900)
This reverts commit da848111d06ada79d78b1b26aaf49746e1e37ae6.

Change-Id: I30b4e5ad9a110347bacec5850d14a0bb122f96c6

automated-tests/src/dali/utc-Dali-CameraActor.cpp
dali/devel-api/actors/camera-actor-devel.h
dali/internal/event/actors/camera-actor-impl.cpp
dali/internal/event/actors/camera-actor-impl.h

index 7063dca..7a37225 100644 (file)
@@ -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<Dali::Camera::Type>(CameraActor::Property::TYPE);
+  Dali::Camera::Type cameraType        = actor.GetProperty<Dali::Camera::Type>(CameraActor::Property::TYPE);
   Dali::Camera::Type currentCameraType = actor.GetCurrentProperty<Dali::Camera::Type>(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<Dali::Camera::Type>(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<int>(Dali::DevelCameraActor::Property::PROJECTION_DIRECTION), static_cast<int>(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<int>(Dali::DevelCameraActor::Property::PROJECTION_DIRECTION), static_cast<int>(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<int>(Dali::DevelCameraActor::Property::PROJECTION_DIRECTION), static_cast<int>(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;
index 563118e..e1a0a4c 100644 (file)
@@ -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
index 79971ff..b444d9f 100644 (file)
@@ -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<Vector4>());
         break;
       }
+      case Dali::DevelCameraActor::Property::PROJECTION_DIRECTION:
+      {
+        Dali::DevelCameraActor::ProjectionDirection projectionDirection = Dali::DevelCameraActor::ProjectionDirection(propertyValue.Get<int>());
+        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)
   }
 
index 2869b59..a817811 100644 (file)
@@ -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 <dali/devel-api/actors/camera-actor-devel.h>
 #include <dali/internal/event/actors/actor-declarations.h>
 #include <dali/internal/event/actors/actor-impl.h>
 #include <dali/public-api/actors/camera-actor.h>
@@ -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