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);
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);
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;
END_TEST;
}
-
int UtcDaliCameraActorSetProperty(void)
{
TestApplication application;
#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.
{
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
* @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
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)
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),
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;
{
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);
}
}
// 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);
+ }
}
}
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:
{
ret = mInvertYAxis;
break;
}
+ case Dali::DevelCameraActor::Property::PROJECTION_DIRECTION:
+ {
+ ret = mProjectionDirection;
+ break;
+ }
} // switch(index)
}
#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.
*/
// 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>
*/
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
*/
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