Deprecate Plane Distance setter + Implement OrthographicSize + Animatable AspectRatio 15/283315/14
authorEunki, Hong <eunkiki.hong@samsung.com>
Mon, 24 Oct 2022 06:04:28 +0000 (15:04 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Tue, 15 Nov 2022 07:31:09 +0000 (16:31 +0900)
Deprecate API s.t Left/Right/Top/Bottom value setter directly.
Instead of these things, let we use OrthographicSize.
It will make that each plane distnaces symmetric so that center of camera.

Due to we can disconnect dependency of plane distance parameters,
now we can make AspectRatio animatable.

Change-Id: I7e18af1871d1efc805c11e2f6b7f12d0ee47d47a
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali/utc-Dali-CameraActor.cpp
automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp
dali/devel-api/actors/camera-actor-devel.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
dali/internal/update/manager/render-instruction-processor.cpp
dali/internal/update/render-tasks/scene-graph-camera.cpp
dali/internal/update/render-tasks/scene-graph-camera.h
dali/public-api/actors/camera-actor.cpp
dali/public-api/actors/camera-actor.h

index 72ae59e..ce1421e 100644 (file)
@@ -186,10 +186,11 @@ int UtcDaliCameraActorNewDefaultPerspectiveProjection(void)
 
   // All the properties should still be the default values
   // Defaults taken from scene-graph-camera.cpp
-  DALI_TEST_EQUALS(800.0f / 480.0f, actor.GetProperty(CameraActor::Property::ASPECT_RATIO).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
+  DALI_TEST_EQUALS(480.0f / 800.0f, actor.GetProperty(CameraActor::Property::ASPECT_RATIO).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
   DALI_TEST_EQUALS(45.0f * (Math::PI / 180.0f), actor.GetProperty(CameraActor::Property::FIELD_OF_VIEW).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
   DALI_TEST_EQUALS(800.0f, actor.GetProperty(CameraActor::Property::NEAR_PLANE_DISTANCE).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
   DALI_TEST_EQUALS(3.0f * 800.0f, actor.GetProperty(CameraActor::Property::FAR_PLANE_DISTANCE).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
+  DALI_TEST_EQUALS(400.0f, actor.GetProperty(DevelCameraActor::Property::ORTHOGRAPHIC_SIZE).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
   DALI_TEST_EQUALS(0.0f, actor.GetProperty(Actor::Property::POSITION_Z).Get<float>(), TEST_LOCATION);
   DALI_TEST_EQUALS(actor.GetProjectionMode(), Dali::Camera::PERSPECTIVE_PROJECTION, TEST_LOCATION);
 
@@ -200,6 +201,7 @@ int UtcDaliCameraActorNewDefaultPerspectiveProjection(void)
   DALI_TEST_EQUALS(0.489957f, actor.GetProperty(CameraActor::Property::FIELD_OF_VIEW).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
   DALI_TEST_EQUALS(800.0f, actor.GetProperty(CameraActor::Property::NEAR_PLANE_DISTANCE).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
   DALI_TEST_EQUALS(4895.0f, actor.GetProperty(CameraActor::Property::FAR_PLANE_DISTANCE).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
+  DALI_TEST_EQUALS(400.0f, actor.GetProperty(DevelCameraActor::Property::ORTHOGRAPHIC_SIZE).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
   DALI_TEST_EQUALS(1600.0f, actor.GetProperty(Actor::Property::POSITION_Z).Get<float>(), TEST_LOCATION);
   DALI_TEST_EQUALS(actor.GetProjectionMode(), Dali::Camera::PERSPECTIVE_PROJECTION, TEST_LOCATION);
 
@@ -211,6 +213,7 @@ int UtcDaliCameraActorNewDefaultPerspectiveProjection(void)
   DALI_TEST_EQUALS(0.489957f, actor.GetProperty(CameraActor::Property::FIELD_OF_VIEW).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
   DALI_TEST_EQUALS(800.0f, actor.GetProperty(CameraActor::Property::NEAR_PLANE_DISTANCE).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
   DALI_TEST_EQUALS(4895.0f, actor.GetProperty(CameraActor::Property::FAR_PLANE_DISTANCE).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
+  DALI_TEST_EQUALS(400.0f, actor.GetProperty(DevelCameraActor::Property::ORTHOGRAPHIC_SIZE).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
   DALI_TEST_EQUALS(1600.0f, actor.GetProperty(Actor::Property::POSITION_Z).Get<float>(), TEST_LOCATION);
   DALI_TEST_EQUALS(actor.GetProjectionMode(), Dali::Camera::PERSPECTIVE_PROJECTION, TEST_LOCATION);
 
@@ -817,6 +820,46 @@ int UtcDaliCameraActorGetInvertYAxisN(void)
   END_TEST;
 }
 
+int UtcDaliCameraActorSetGetOthographicSizeP(void)
+{
+  TestApplication application;
+  tet_infoline("Testing Dali::CameraActor Set Orthographic Size (P)");
+
+  CameraActor actor = CameraActor::New(Size(TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT));
+  actor.SetProjectionMode(Dali::Camera::ORTHOGRAPHIC_PROJECTION);
+
+  // Get default orthographic size by inputed size
+  DALI_TEST_EQUALS(actor.GetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE).Get<float>(), static_cast<float>(TestApplication::DEFAULT_SURFACE_HEIGHT) * 0.5f, TEST_LOCATION);
+
+  float value = 0.0f;
+
+  // Set an initial value to confirm a further set changes it.
+  float size = 300.0f;
+  actor.SetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, size);
+
+  value = 0.0f;
+  DALI_TEST_CHECK(actor.GetProperty(DevelCameraActor::Property::ORTHOGRAPHIC_SIZE).Get(value));
+  DALI_TEST_EQUALS(value, size, TEST_LOCATION);
+
+  size = 1600.0f;
+  actor.SetProperty(DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, size);
+
+  value = 0.0f;
+  DALI_TEST_CHECK(actor.GetProperty(DevelCameraActor::Property::ORTHOGRAPHIC_SIZE).Get(value));
+  DALI_TEST_EQUALS(value, size, TEST_LOCATION);
+
+  actor.SetProperty(DevelCameraActor::Property::PROJECTION_DIRECTION, DevelCameraActor::ProjectionDirection::HORIZONTAL);
+
+  size = 600.0f;
+  actor.SetProperty(DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, size);
+
+  value = 0.0f;
+  DALI_TEST_CHECK(actor.GetProperty(DevelCameraActor::Property::ORTHOGRAPHIC_SIZE).Get(value));
+  DALI_TEST_EQUALS(value, size, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliCameraActorSetPerspectiveProjectionP(void)
 {
   TestApplication application;
@@ -898,51 +941,57 @@ int UtcDaliCameraActorSetOrthographicProjectionP1(void)
   application.GetScene().Add(actor);
 
   actor.SetOrthographicProjection(Size(1080.0f, 1920.0f));
+
   application.SendNotification();
   application.Render(0);
   application.Render();
   application.SendNotification();
 
   float defaultAspectRatio;
-  float defaultFieldOfView;
   float defaultNearPlaneDistance;
   float defaultFarPlaneDistance;
   actor.GetProperty(CameraActor::Property::ASPECT_RATIO).Get(defaultAspectRatio);
-  actor.GetProperty(CameraActor::Property::FIELD_OF_VIEW).Get(defaultFieldOfView);
   actor.GetProperty(CameraActor::Property::NEAR_PLANE_DISTANCE).Get(defaultNearPlaneDistance);
   actor.GetProperty(CameraActor::Property::FAR_PLANE_DISTANCE).Get(defaultFarPlaneDistance);
   Vector3 defaultPos = actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION);
 
-  actor.SetOrthographicProjection(Size(1080.0f, 1920.0f));
-
-  application.SendNotification();
-  application.Render(0);
-  application.Render();
-  application.SendNotification();
+  auto TestOrthographicPlaneDistance = [&](float width, float height, float expectOrthographicSize) {
+    actor.SetOrthographicProjection(Size(width, height));
 
-  float value;
-  actor.GetProperty(CameraActor::Property::ASPECT_RATIO).Get(value);
-  DALI_TEST_EQUALS(defaultAspectRatio, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::FIELD_OF_VIEW).Get(value);
-  DALI_TEST_EQUALS(defaultFieldOfView, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::NEAR_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(defaultNearPlaneDistance, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::FAR_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(defaultFarPlaneDistance, value, FLOAT_EPSILON, TEST_LOCATION);
+    DALI_TEST_EQUALS(expectOrthographicSize, actor.GetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE).Get<float>(), TEST_LOCATION);
 
-  actor.GetProperty(CameraActor::Property::LEFT_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(-540.0f, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::RIGHT_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(540.0f, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::TOP_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(960.0f, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::BOTTOM_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(-960.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+    application.SendNotification();
+    application.Render(0);
+    application.Render();
+    application.SendNotification();
 
-  Vector3 pos = actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION);
-  DALI_TEST_EQUALS(defaultPos.z, pos.z, 0.001f, TEST_LOCATION);
+    float value;
+    actor.GetProperty(CameraActor::Property::ASPECT_RATIO).Get(value);
+    DALI_TEST_EQUALS(defaultAspectRatio, value, FLOAT_EPSILON, TEST_LOCATION);
+    actor.GetProperty(CameraActor::Property::NEAR_PLANE_DISTANCE).Get(value);
+    DALI_TEST_EQUALS(defaultNearPlaneDistance, value, FLOAT_EPSILON, TEST_LOCATION);
+    actor.GetProperty(CameraActor::Property::FAR_PLANE_DISTANCE).Get(value);
+    DALI_TEST_EQUALS(defaultFarPlaneDistance, value, FLOAT_EPSILON, TEST_LOCATION);
+
+    actor.GetProperty(CameraActor::Property::LEFT_PLANE_DISTANCE).Get(value);
+    DALI_TEST_EQUALS(-540.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+    actor.GetProperty(CameraActor::Property::RIGHT_PLANE_DISTANCE).Get(value);
+    DALI_TEST_EQUALS(540.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+    actor.GetProperty(CameraActor::Property::TOP_PLANE_DISTANCE).Get(value);
+    DALI_TEST_EQUALS(960.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+    actor.GetProperty(CameraActor::Property::BOTTOM_PLANE_DISTANCE).Get(value);
+    DALI_TEST_EQUALS(-960.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+
+    Vector3 pos = actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION);
+    DALI_TEST_EQUALS(defaultPos.z, pos.z, 0.001f, TEST_LOCATION);
+
+    DALI_TEST_EQUALS(actor.GetProjectionMode(), Dali::Camera::ORTHOGRAPHIC_PROJECTION, TEST_LOCATION);
+  };
 
-  DALI_TEST_EQUALS(actor.GetProjectionMode(), Dali::Camera::ORTHOGRAPHIC_PROJECTION, TEST_LOCATION);
+  TestOrthographicPlaneDistance(1080.0f, 1920.0f, 960.0f);
+  // Change projection direction
+  actor.SetProperty(DevelCameraActor::Property::PROJECTION_DIRECTION, DevelCameraActor::ProjectionDirection::HORIZONTAL);
+  TestOrthographicPlaneDistance(1080.0f, 1920.0f, 540.0f);
   END_TEST;
 }
 
@@ -967,102 +1016,6 @@ int UtcDaliCameraActorSetOrthographicProjectionN(void)
   END_TEST;
 }
 
-int UtcDaliCameraActorSetOrthographicProjectionP2(void)
-{
-  TestApplication application;
-  tet_infoline("Testing Dali::CameraActor::SetOrthographicProjection (P,2)");
-
-  CameraActor actor = CameraActor::New();
-  DALI_TEST_CHECK(actor);
-
-  float defaultAspectRatio;
-  float defaultFieldOfView;
-  float defaultNearPlaneDistance;
-  float defaultFarPlaneDistance;
-  actor.GetProperty(CameraActor::Property::ASPECT_RATIO).Get(defaultAspectRatio);
-  actor.GetProperty(CameraActor::Property::FIELD_OF_VIEW).Get(defaultFieldOfView);
-  actor.GetProperty(CameraActor::Property::NEAR_PLANE_DISTANCE).Get(defaultNearPlaneDistance);
-  actor.GetProperty(CameraActor::Property::FAR_PLANE_DISTANCE).Get(defaultFarPlaneDistance);
-
-  // Check setting with specific near and far plane distances.
-  actor.SetOrthographicProjection(-100.0f, 200.0f, -300.0f, 500.0f, 400.0f, 4000.0f);
-
-  float value;
-  actor.GetProperty(CameraActor::Property::ASPECT_RATIO).Get(value);
-  DALI_TEST_EQUALS(defaultAspectRatio, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::FIELD_OF_VIEW).Get(value);
-  DALI_TEST_EQUALS(defaultFieldOfView, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::NEAR_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(400.0f, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::FAR_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(4000.0f, value, FLOAT_EPSILON, TEST_LOCATION);
-
-  actor.GetProperty(CameraActor::Property::LEFT_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(-100.0f, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::RIGHT_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(200.0f, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::TOP_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(-300.0f, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::BOTTOM_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(500.0f, value, FLOAT_EPSILON, TEST_LOCATION);
-
-  DALI_TEST_EQUALS(actor.GetProjectionMode(), Dali::Camera::ORTHOGRAPHIC_PROJECTION, TEST_LOCATION);
-
-  END_TEST;
-}
-
-int UtcDaliCameraActorSetOrthographicProjectionP3(void)
-{
-  TestApplication application;
-  tet_infoline("Testing Dali::CameraActor::SetOrthographicProjection (P,3)");
-
-  CameraActor actor = CameraActor::New();
-  DALI_TEST_CHECK(actor);
-
-  float defaultAspectRatio;
-  float defaultFieldOfView;
-  float defaultNearPlaneDistance;
-  float defaultFarPlaneDistance;
-  actor.GetProperty(CameraActor::Property::ASPECT_RATIO).Get(defaultAspectRatio);
-  actor.GetProperty(CameraActor::Property::FIELD_OF_VIEW).Get(defaultFieldOfView);
-  actor.GetProperty(CameraActor::Property::NEAR_PLANE_DISTANCE).Get(defaultNearPlaneDistance);
-  actor.GetProperty(CameraActor::Property::FAR_PLANE_DISTANCE).Get(defaultFarPlaneDistance);
-
-  actor.SetProjectionMode(Dali::Camera::ORTHOGRAPHIC_PROJECTION);
-
-  actor.SetProperty(CameraActor::Property::LEFT_PLANE_DISTANCE, -100.0f);
-  actor.SetProperty(CameraActor::Property::RIGHT_PLANE_DISTANCE, 200.0f);
-  actor.SetProperty(CameraActor::Property::TOP_PLANE_DISTANCE, -300.0f);
-  actor.SetProperty(CameraActor::Property::BOTTOM_PLANE_DISTANCE, 500.0f);
-  actor.SetNearClippingPlane(400.0f);
-  actor.SetFarClippingPlane(4000.0f);
-
-  float value;
-  actor.GetProperty(CameraActor::Property::ASPECT_RATIO).Get(value);
-  DALI_TEST_EQUALS(defaultAspectRatio, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::FIELD_OF_VIEW).Get(value);
-  DALI_TEST_EQUALS(defaultFieldOfView, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::NEAR_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(400.0f, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::FAR_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(4000.0f, value, FLOAT_EPSILON, TEST_LOCATION);
-
-  actor.GetProperty(CameraActor::Property::LEFT_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(-100.0f, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::RIGHT_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(200.0f, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::TOP_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(-300.0f, value, FLOAT_EPSILON, TEST_LOCATION);
-  actor.GetProperty(CameraActor::Property::BOTTOM_PLANE_DISTANCE).Get(value);
-  DALI_TEST_EQUALS(500.0f, value, FLOAT_EPSILON, TEST_LOCATION);
-
-  DALI_TEST_EQUALS(actor.GetProjectionMode(), Dali::Camera::ORTHOGRAPHIC_PROJECTION, TEST_LOCATION);
-
-  Dali::Camera::ProjectionMode projectionMode = actor.GetProperty<Dali::Camera::ProjectionMode>(CameraActor::Property::PROJECTION_MODE);
-  DALI_TEST_EQUALS(projectionMode, Dali::Camera::ORTHOGRAPHIC_PROJECTION, TEST_LOCATION);
-  END_TEST;
-}
-
 int UtcDaliCameraActorSetProjectionModeP(void)
 {
   TestApplication application;
@@ -1306,6 +1259,8 @@ int UtcDaliCameraActorDefaultProperties(void)
   indices.push_back(CameraActor::Property::PROJECTION_MATRIX);
   indices.push_back(CameraActor::Property::VIEW_MATRIX);
   indices.push_back(CameraActor::Property::INVERT_Y_AXIS);
+  indices.push_back(DevelCameraActor::Property::ORTHOGRAPHIC_SIZE);
+  indices.push_back(DevelCameraActor::Property::PROJECTION_DIRECTION);
 
   DALI_TEST_CHECK(actor.GetPropertyCount() == (Actor::New().GetPropertyCount() + indices.size()));
 
@@ -1313,7 +1268,7 @@ int UtcDaliCameraActorDefaultProperties(void)
   {
     DALI_TEST_EQUALS(*iter, actor.GetPropertyIndex(actor.GetPropertyName(*iter)), TEST_LOCATION);
 
-    if(*iter == CameraActor::Property::FIELD_OF_VIEW)
+    if(*iter == CameraActor::Property::FIELD_OF_VIEW || *iter == CameraActor::Property::ASPECT_RATIO || *iter == DevelCameraActor::Property::ORTHOGRAPHIC_SIZE)
     {
       DALI_TEST_CHECK(actor.IsPropertyAnimatable(*iter));
     }
@@ -1322,7 +1277,11 @@ int UtcDaliCameraActorDefaultProperties(void)
       DALI_TEST_CHECK(!actor.IsPropertyAnimatable(*iter));
     }
 
-    if((*iter == CameraActor::Property::PROJECTION_MATRIX) ||
+    if((*iter == CameraActor::Property::LEFT_PLANE_DISTANCE) ||
+       (*iter == CameraActor::Property::RIGHT_PLANE_DISTANCE) ||
+       (*iter == CameraActor::Property::TOP_PLANE_DISTANCE) ||
+       (*iter == CameraActor::Property::BOTTOM_PLANE_DISTANCE) ||
+       (*iter == CameraActor::Property::PROJECTION_MATRIX) ||
        (*iter == CameraActor::Property::VIEW_MATRIX))
     {
       DALI_TEST_CHECK(!actor.IsPropertyWritable(*iter));
@@ -1444,17 +1403,19 @@ int UtcDaliCameraActorDefaultPropertiesInherited(void)
       {"type", Property::INTEGER, true, false, true, Dali::CameraActor::Property::TYPE},
       {"projectionMode", Property::INTEGER, true, false, true, Dali::CameraActor::Property::PROJECTION_MODE},
       {"fieldOfView", Property::FLOAT, true, true, true, Dali::CameraActor::Property::FIELD_OF_VIEW},
-      {"aspectRatio", Property::FLOAT, true, false, true, Dali::CameraActor::Property::ASPECT_RATIO},
+      {"aspectRatio", Property::FLOAT, true, true, true, Dali::CameraActor::Property::ASPECT_RATIO},
       {"nearPlaneDistance", Property::FLOAT, true, false, true, Dali::CameraActor::Property::NEAR_PLANE_DISTANCE},
       {"farPlaneDistance", Property::FLOAT, true, false, true, Dali::CameraActor::Property::FAR_PLANE_DISTANCE},
-      {"leftPlaneDistance", Property::FLOAT, true, false, true, Dali::CameraActor::Property::LEFT_PLANE_DISTANCE},
-      {"rightPlaneDistance", Property::FLOAT, true, false, true, Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE},
-      {"topPlaneDistance", Property::FLOAT, true, false, true, Dali::CameraActor::Property::TOP_PLANE_DISTANCE},
-      {"bottomPlaneDistance", Property::FLOAT, true, false, true, Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE},
+      {"leftPlaneDistance", Property::FLOAT, false, false, true, Dali::CameraActor::Property::LEFT_PLANE_DISTANCE},
+      {"rightPlaneDistance", Property::FLOAT, false, false, true, Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE},
+      {"topPlaneDistance", Property::FLOAT, false, false, true, Dali::CameraActor::Property::TOP_PLANE_DISTANCE},
+      {"bottomPlaneDistance", Property::FLOAT, false, false, true, Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE},
       {"targetPosition", Property::VECTOR3, true, false, true, Dali::CameraActor::Property::TARGET_POSITION},
       {"projectionMatrix", Property::MATRIX, false, false, true, Dali::CameraActor::Property::PROJECTION_MATRIX},
       {"viewMatrix", Property::MATRIX, false, false, true, Dali::CameraActor::Property::VIEW_MATRIX},
-      {"invertYAxis", Property::BOOLEAN, true, false, true, Dali::CameraActor::Property::INVERT_Y_AXIS}};
+      {"invertYAxis", Property::BOOLEAN, true, false, true, Dali::CameraActor::Property::INVERT_Y_AXIS},
+      {"orthographicSize", Property::FLOAT, true, true, true, Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE},
+      {"projectionDirection", Property::INTEGER, true, false, true, Dali::DevelCameraActor::Property::PROJECTION_DIRECTION}};
 
   for(uint32_t index = 0; index < (sizeof(CAMERA_DEFAULT_PROPERTY) / sizeof(PropertyDetails)); ++index)
   {
@@ -1579,22 +1540,38 @@ int UtcDaliCameraActorAnimatedProperties02(void)
   application.GetScene().Add(actor);
 
   camera.SetFieldOfView(0.1f);
+  camera.SetAspectRatio(0.5f);
+  camera.SetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, 200.0f);
 
-  Constraint constraint = Constraint::New<float>(actor, Actor::Property::POSITION_X, EqualToConstraint());
-  constraint.AddSource(Source(camera, CameraActor::Property::FIELD_OF_VIEW));
-  constraint.Apply();
+  Constraint constraintX = Constraint::New<float>(actor, Actor::Property::POSITION_X, EqualToConstraint());
+  constraintX.AddSource(Source(camera, CameraActor::Property::FIELD_OF_VIEW));
+  constraintX.Apply();
+
+  Constraint constraintY = Constraint::New<float>(actor, Actor::Property::POSITION_Y, EqualToConstraint());
+  constraintY.AddSource(Source(camera, CameraActor::Property::ASPECT_RATIO));
+  constraintY.Apply();
+
+  Constraint constraintZ = Constraint::New<float>(actor, Actor::Property::POSITION_Z, EqualToConstraint());
+  constraintZ.AddSource(Source(camera, DevelCameraActor::Property::ORTHOGRAPHIC_SIZE));
+  constraintZ.Apply();
 
   application.SendNotification();
   application.Render();
 
   DALI_TEST_EQUALS(actor.GetCurrentProperty<float>(Actor::Property::POSITION_X), 0.1f, TEST_LOCATION);
+  DALI_TEST_EQUALS(actor.GetCurrentProperty<float>(Actor::Property::POSITION_Y), 0.5f, TEST_LOCATION);
+  DALI_TEST_EQUALS(actor.GetCurrentProperty<float>(Actor::Property::POSITION_Z), 200.0f, TEST_LOCATION);
 
   camera.SetFieldOfView(0.5f);
+  camera.SetAspectRatio(0.2f);
+  camera.SetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, 100.0f);
 
   application.SendNotification();
   application.Render();
 
   DALI_TEST_EQUALS(actor.GetCurrentProperty<float>(Actor::Property::POSITION_X), 0.5f, TEST_LOCATION);
+  DALI_TEST_EQUALS(actor.GetCurrentProperty<float>(Actor::Property::POSITION_Y), 0.2f, TEST_LOCATION);
+  DALI_TEST_EQUALS(actor.GetCurrentProperty<float>(Actor::Property::POSITION_Z), 100.0f, TEST_LOCATION);
   END_TEST;
 }
 
@@ -1611,8 +1588,11 @@ int UtcDaliCameraActorAnimatedProperties03(void)
   actor.SetProperty(Actor::Property::POSITION, Vector2(0.1f, 0.0f));
   application.GetScene().Add(actor);
 
-  Radian sourceFoV = Radian(0.6f);
-  Radian targetFoV = Radian(0.1f);
+  Radian sourceFoV    = Radian(0.6f);
+  float  sourceAspect = 0.7f;
+
+  Radian targetFoV    = Radian(0.1f);
+  float  targetAspect = 1.3f;
 
   Matrix expectedProjectionMatrix1;
   Matrix expectedProjectionMatrix2;
@@ -1624,16 +1604,19 @@ int UtcDaliCameraActorAnimatedProperties03(void)
 
   // Build expect projection matrix
   camera.SetFieldOfView(sourceFoV.radian);
+  camera.SetAspectRatio(sourceAspect);
   application.SendNotification();
   application.Render();
   camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(expectedProjectionMatrix1);
 
   camera.SetFieldOfView(sourceFoV.radian * 0.6f + targetFoV.radian * 0.4f);
+  camera.SetAspectRatio(sourceAspect * 0.6f + targetAspect * 0.4f);
   application.SendNotification();
   application.Render();
   camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(expectedProjectionMatrix2);
 
   camera.SetFieldOfView(targetFoV.radian);
+  camera.SetAspectRatio(targetAspect);
   application.SendNotification();
   application.Render();
   camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(expectedProjectionMatrix3);
@@ -1646,6 +1629,7 @@ int UtcDaliCameraActorAnimatedProperties03(void)
 
     // progress 0.0
     DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::FIELD_OF_VIEW), sourceFoV.radian, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::ASPECT_RATIO), sourceAspect, TEST_LOCATION);
 
     camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(projectionMatrix);
     DALI_TEST_EQUALS(projectionMatrix, expectedProjectionMatrix1, Epsilon<100000>::value, TEST_LOCATION);
@@ -1655,6 +1639,7 @@ int UtcDaliCameraActorAnimatedProperties03(void)
 
     // progress 0.4
     DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::FIELD_OF_VIEW), sourceFoV.radian * 0.6f + targetFoV.radian * 0.4f, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::ASPECT_RATIO), sourceAspect * 0.6f + targetAspect * 0.4f, TEST_LOCATION);
 
     camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(projectionMatrix);
     DALI_TEST_EQUALS(projectionMatrix, expectedProjectionMatrix2, Epsilon<100000>::value, TEST_LOCATION);
@@ -1664,6 +1649,7 @@ int UtcDaliCameraActorAnimatedProperties03(void)
 
     // progress 1.0
     DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::FIELD_OF_VIEW), targetFoV.radian, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::ASPECT_RATIO), targetAspect, TEST_LOCATION);
 
     camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(projectionMatrix);
     DALI_TEST_EQUALS(projectionMatrix, expectedProjectionMatrix3, Epsilon<100000>::value, TEST_LOCATION);
@@ -1677,8 +1663,10 @@ int UtcDaliCameraActorAnimatedProperties03(void)
   {
     tet_printf("AnimateTo\n");
     camera.SetProperty(CameraActor::Property::FIELD_OF_VIEW, sourceFoV.radian);
+    camera.SetProperty(CameraActor::Property::ASPECT_RATIO, sourceAspect);
     Animation animation = Animation::New(1.0f);
     animation.AnimateTo(Property(camera, CameraActor::Property::FIELD_OF_VIEW), targetFoV.radian);
+    animation.AnimateTo(Property(camera, CameraActor::Property::ASPECT_RATIO), targetAspect);
     animation.AnimateTo(Property(camera, Actor::Property::POSITION_X), 0.0f); ///< For line coverage.
     animation.Play();
 
@@ -1689,10 +1677,18 @@ int UtcDaliCameraActorAnimatedProperties03(void)
   {
     tet_printf("AnimateBetween\n");
     Animation animation = Animation::New(1.0f);
-    KeyFrames keyFrames = KeyFrames::New();
-    keyFrames.Add(0.0f, sourceFoV.radian);
-    keyFrames.Add(1.0f, targetFoV.radian);
-    animation.AnimateBetween(Property(camera, CameraActor::Property::FIELD_OF_VIEW), keyFrames);
+
+    KeyFrames keyFrames1 = KeyFrames::New();
+    keyFrames1.Add(0.0f, sourceFoV.radian);
+    keyFrames1.Add(1.0f, targetFoV.radian);
+
+    KeyFrames keyFrames2 = KeyFrames::New();
+    keyFrames2.Add(0.0f, sourceAspect);
+    keyFrames2.Add(1.0f, targetAspect);
+
+    animation.AnimateBetween(Property(camera, CameraActor::Property::FIELD_OF_VIEW), keyFrames1);
+    animation.AnimateBetween(Property(camera, CameraActor::Property::ASPECT_RATIO), keyFrames2);
+
     animation.Play();
 
     TestAnimationProgress();
@@ -1702,10 +1698,353 @@ int UtcDaliCameraActorAnimatedProperties03(void)
   {
     tet_printf("AnimateBy\n");
     camera.SetProperty(CameraActor::Property::FIELD_OF_VIEW, sourceFoV.radian);
+    camera.SetProperty(CameraActor::Property::ASPECT_RATIO, sourceAspect);
     Animation animation = Animation::New(1.0f);
     animation.AnimateBy(Property(camera, CameraActor::Property::FIELD_OF_VIEW), targetFoV.radian - sourceFoV.radian);
+    animation.AnimateBy(Property(camera, CameraActor::Property::ASPECT_RATIO), targetAspect - sourceAspect);
+    animation.Play();
+
+    TestAnimationProgress();
+  }
+
+  END_TEST;
+}
+
+int UtcDaliCameraActorAnimatedProperties04(void)
+{
+  TestApplication application;
+  tet_infoline("Testing Dali::Internal::CameraActor::GetSceneObjectAnimatableProperty()");
+
+  CameraActor camera = application.GetScene().GetRenderTaskList().GetTask(0u).GetCameraActor();
+
+  // Make camera as orthographic mode
+  camera.SetProjectionMode(Dali::Camera::ORTHOGRAPHIC_PROJECTION);
+
+  // Add dummy actor
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  actor.SetProperty(Actor::Property::POSITION, Vector2(0.1f, 0.0f));
+  application.GetScene().Add(actor);
+
+  float sourceOrthographic = 2.0f;
+  float sourceAspect       = 0.7f;
+
+  float targetOrthographic = 4.0f;
+  float targetAspect       = 1.3f;
+
+  Matrix expectedProjectionMatrix1;
+  Matrix expectedProjectionMatrix2;
+  Matrix expectedProjectionMatrix3;
+
+  // Reduce near-far value for projection matrix epsilon
+  camera.SetNearClippingPlane(1.0f);
+  camera.SetFarClippingPlane(3.0f);
+
+  // Build expect projection matrix
+  camera.SetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, sourceOrthographic);
+  camera.SetAspectRatio(sourceAspect);
+  application.SendNotification();
+  application.Render();
+  camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(expectedProjectionMatrix1);
+
+  camera.SetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, sourceOrthographic * 0.6f + targetOrthographic * 0.4f);
+  camera.SetAspectRatio(sourceAspect * 0.6f + targetAspect * 0.4f);
+  application.SendNotification();
+  application.Render();
+  camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(expectedProjectionMatrix2);
+
+  camera.SetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, targetOrthographic);
+  camera.SetAspectRatio(targetAspect);
+  application.SendNotification();
+  application.Render();
+  camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(expectedProjectionMatrix3);
+
+  auto TestAnimationProgress = [&]() {
+    Matrix projectionMatrix;
+
+    application.SendNotification();
+    application.Render(0);
+
+    float expectOrthographic;
+    float expectAspect;
+    float expectLeft;
+    float expectRight;
+    float expectTop;
+    float expectBottom;
+
+    auto UpdateExpectPlaneDistance = [&]() {
+      bool isVertical = camera.GetProperty<int>(DevelCameraActor::Property::PROJECTION_DIRECTION) == static_cast<int>(DevelCameraActor::ProjectionDirection::VERTICAL);
+      expectLeft      = -(isVertical ? expectOrthographic * expectAspect : expectOrthographic);
+      expectRight     = (isVertical ? expectOrthographic * expectAspect : expectOrthographic);
+      expectTop       = (isVertical ? expectOrthographic : expectOrthographic / expectAspect);
+      expectBottom    = -(isVertical ? expectOrthographic : expectOrthographic / expectAspect);
+    };
+
+    // progress 0.0
+    expectOrthographic = sourceOrthographic;
+    expectAspect       = sourceAspect;
+    UpdateExpectPlaneDistance();
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(DevelCameraActor::Property::ORTHOGRAPHIC_SIZE), expectOrthographic, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::ASPECT_RATIO), expectAspect, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::LEFT_PLANE_DISTANCE), expectLeft, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::RIGHT_PLANE_DISTANCE), expectRight, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::TOP_PLANE_DISTANCE), expectTop, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::BOTTOM_PLANE_DISTANCE), expectBottom, TEST_LOCATION);
+
+    camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(projectionMatrix);
+    DALI_TEST_EQUALS(projectionMatrix, expectedProjectionMatrix1, Epsilon<100000>::value, TEST_LOCATION);
+
+    application.SendNotification();
+    application.Render(400);
+
+    // progress 0.4
+    expectOrthographic = sourceOrthographic * 0.6f + targetOrthographic * 0.4f;
+    expectAspect       = sourceAspect * 0.6f + targetAspect * 0.4f;
+    UpdateExpectPlaneDistance();
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(DevelCameraActor::Property::ORTHOGRAPHIC_SIZE), expectOrthographic, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::ASPECT_RATIO), expectAspect, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::LEFT_PLANE_DISTANCE), expectLeft, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::RIGHT_PLANE_DISTANCE), expectRight, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::TOP_PLANE_DISTANCE), expectTop, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::BOTTOM_PLANE_DISTANCE), expectBottom, TEST_LOCATION);
+
+    camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(projectionMatrix);
+    DALI_TEST_EQUALS(projectionMatrix, expectedProjectionMatrix2, Epsilon<100000>::value, TEST_LOCATION);
+
+    application.SendNotification();
+    application.Render(600);
+
+    // progress 1.0
+    expectOrthographic = targetOrthographic;
+    expectAspect       = targetAspect;
+    UpdateExpectPlaneDistance();
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(DevelCameraActor::Property::ORTHOGRAPHIC_SIZE), expectOrthographic, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::ASPECT_RATIO), expectAspect, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::LEFT_PLANE_DISTANCE), expectLeft, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::RIGHT_PLANE_DISTANCE), expectRight, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::TOP_PLANE_DISTANCE), expectTop, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::BOTTOM_PLANE_DISTANCE), expectBottom, TEST_LOCATION);
+
+    camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(projectionMatrix);
+    DALI_TEST_EQUALS(projectionMatrix, expectedProjectionMatrix3, Epsilon<100000>::value, TEST_LOCATION);
+
+    // Ensure Animate finished.
+    application.SendNotification();
+    application.Render(16);
+  };
+
+  // AnimateTo
+  {
+    tet_printf("AnimateTo - vertical\n");
+    camera.SetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, sourceOrthographic);
+    camera.SetProperty(CameraActor::Property::ASPECT_RATIO, sourceAspect);
+    Animation animation = Animation::New(1.0f);
+    animation.AnimateTo(Property(camera, DevelCameraActor::Property::ORTHOGRAPHIC_SIZE), targetOrthographic);
+    animation.AnimateTo(Property(camera, CameraActor::Property::ASPECT_RATIO), targetAspect);
+    animation.Play();
+    TestAnimationProgress();
+  }
+
+  // AnimateBetween
+  {
+    tet_printf("AnimateBetween - vertical\n");
+    Animation animation = Animation::New(1.0f);
+
+    KeyFrames keyFrames1 = KeyFrames::New();
+    keyFrames1.Add(0.0f, sourceOrthographic);
+    keyFrames1.Add(1.0f, targetOrthographic);
+
+    KeyFrames keyFrames2 = KeyFrames::New();
+    keyFrames2.Add(0.0f, sourceAspect);
+    keyFrames2.Add(1.0f, targetAspect);
+
+    animation.AnimateBetween(Property(camera, DevelCameraActor::Property::ORTHOGRAPHIC_SIZE), keyFrames1);
+    animation.AnimateBetween(Property(camera, CameraActor::Property::ASPECT_RATIO), keyFrames2);
+
     animation.Play();
+    TestAnimationProgress();
+  }
 
+  // AnimateBy
+  {
+    tet_printf("AnimateBy - vertical\n");
+    camera.SetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, sourceOrthographic);
+    camera.SetProperty(CameraActor::Property::ASPECT_RATIO, sourceAspect);
+    Animation animation = Animation::New(1.0f);
+    animation.AnimateBy(Property(camera, DevelCameraActor::Property::ORTHOGRAPHIC_SIZE), targetOrthographic - sourceOrthographic);
+    animation.AnimateBy(Property(camera, CameraActor::Property::ASPECT_RATIO), targetAspect - sourceAspect);
+    animation.Play();
+    TestAnimationProgress();
+  }
+
+  END_TEST;
+}
+
+int UtcDaliCameraActorAnimatedProperties05(void)
+{
+  TestApplication application;
+  tet_infoline("Testing Dali::Internal::CameraActor::GetSceneObjectAnimatableProperty()");
+
+  CameraActor camera = application.GetScene().GetRenderTaskList().GetTask(0u).GetCameraActor();
+
+  // Make camera as orthographic mode and horizontal
+  camera.SetProjectionMode(Dali::Camera::ORTHOGRAPHIC_PROJECTION);
+  camera.SetProperty(DevelCameraActor::Property::PROJECTION_DIRECTION, DevelCameraActor::ProjectionDirection::HORIZONTAL);
+
+  // Add dummy actor
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  actor.SetProperty(Actor::Property::POSITION, Vector2(0.1f, 0.0f));
+  application.GetScene().Add(actor);
+
+  float sourceOrthographic = 2.0f;
+  float sourceAspect       = 0.7f;
+
+  float targetOrthographic = 4.0f;
+  float targetAspect       = 1.3f;
+
+  Matrix expectedProjectionMatrix1;
+  Matrix expectedProjectionMatrix2;
+  Matrix expectedProjectionMatrix3;
+
+  // Reduce near-far value for projection matrix epsilon
+  camera.SetNearClippingPlane(1.0f);
+  camera.SetFarClippingPlane(3.0f);
+
+  // Build expect projection matrix
+  camera.SetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, sourceOrthographic);
+  camera.SetAspectRatio(sourceAspect);
+  application.SendNotification();
+  application.Render();
+  camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(expectedProjectionMatrix1);
+
+  camera.SetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, sourceOrthographic * 0.6f + targetOrthographic * 0.4f);
+  camera.SetAspectRatio(sourceAspect * 0.6f + targetAspect * 0.4f);
+  application.SendNotification();
+  application.Render();
+  camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(expectedProjectionMatrix2);
+
+  camera.SetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, targetOrthographic);
+  camera.SetAspectRatio(targetAspect);
+  application.SendNotification();
+  application.Render();
+  camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(expectedProjectionMatrix3);
+
+  auto TestAnimationProgress = [&]() {
+    Matrix projectionMatrix;
+
+    application.SendNotification();
+    application.Render(0);
+
+    float expectOrthographic;
+    float expectAspect;
+    float expectLeft;
+    float expectRight;
+    float expectTop;
+    float expectBottom;
+
+    auto UpdateExpectPlaneDistance = [&]() {
+      bool isVertical = camera.GetProperty<int>(DevelCameraActor::Property::PROJECTION_DIRECTION) == static_cast<int>(DevelCameraActor::ProjectionDirection::VERTICAL);
+      expectLeft      = -(isVertical ? expectOrthographic * expectAspect : expectOrthographic);
+      expectRight     = (isVertical ? expectOrthographic * expectAspect : expectOrthographic);
+      expectTop       = (isVertical ? expectOrthographic : expectOrthographic / expectAspect);
+      expectBottom    = -(isVertical ? expectOrthographic : expectOrthographic / expectAspect);
+    };
+
+    // progress 0.0
+    expectOrthographic = sourceOrthographic;
+    expectAspect       = sourceAspect;
+    UpdateExpectPlaneDistance();
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(DevelCameraActor::Property::ORTHOGRAPHIC_SIZE), expectOrthographic, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::ASPECT_RATIO), expectAspect, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::LEFT_PLANE_DISTANCE), expectLeft, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::RIGHT_PLANE_DISTANCE), expectRight, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::TOP_PLANE_DISTANCE), expectTop, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::BOTTOM_PLANE_DISTANCE), expectBottom, TEST_LOCATION);
+
+    camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(projectionMatrix);
+    DALI_TEST_EQUALS(projectionMatrix, expectedProjectionMatrix1, Epsilon<100000>::value, TEST_LOCATION);
+
+    application.SendNotification();
+    application.Render(400);
+
+    // progress 0.4
+    expectOrthographic = sourceOrthographic * 0.6f + targetOrthographic * 0.4f;
+    expectAspect       = sourceAspect * 0.6f + targetAspect * 0.4f;
+    UpdateExpectPlaneDistance();
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(DevelCameraActor::Property::ORTHOGRAPHIC_SIZE), expectOrthographic, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::ASPECT_RATIO), expectAspect, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::LEFT_PLANE_DISTANCE), expectLeft, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::RIGHT_PLANE_DISTANCE), expectRight, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::TOP_PLANE_DISTANCE), expectTop, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::BOTTOM_PLANE_DISTANCE), expectBottom, TEST_LOCATION);
+
+    camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(projectionMatrix);
+    DALI_TEST_EQUALS(projectionMatrix, expectedProjectionMatrix2, Epsilon<100000>::value, TEST_LOCATION);
+
+    application.SendNotification();
+    application.Render(600);
+
+    // progress 1.0
+    expectOrthographic = targetOrthographic;
+    expectAspect       = targetAspect;
+    UpdateExpectPlaneDistance();
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(DevelCameraActor::Property::ORTHOGRAPHIC_SIZE), expectOrthographic, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::ASPECT_RATIO), expectAspect, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::LEFT_PLANE_DISTANCE), expectLeft, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::RIGHT_PLANE_DISTANCE), expectRight, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::TOP_PLANE_DISTANCE), expectTop, TEST_LOCATION);
+    DALI_TEST_EQUALS(camera.GetCurrentProperty<float>(CameraActor::Property::BOTTOM_PLANE_DISTANCE), expectBottom, TEST_LOCATION);
+
+    camera.GetProperty(CameraActor::Property::PROJECTION_MATRIX).Get(projectionMatrix);
+    DALI_TEST_EQUALS(projectionMatrix, expectedProjectionMatrix3, Epsilon<100000>::value, TEST_LOCATION);
+
+    // Ensure Animate finished.
+    application.SendNotification();
+    application.Render(16);
+  };
+
+  // AnimateTo
+  {
+    tet_printf("AnimateTo - horizontal\n");
+    camera.SetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, sourceOrthographic);
+    camera.SetProperty(CameraActor::Property::ASPECT_RATIO, sourceAspect);
+    Animation animation = Animation::New(1.0f);
+    animation.AnimateTo(Property(camera, DevelCameraActor::Property::ORTHOGRAPHIC_SIZE), targetOrthographic);
+    animation.AnimateTo(Property(camera, CameraActor::Property::ASPECT_RATIO), targetAspect);
+    animation.Play();
+    TestAnimationProgress();
+  }
+
+  // AnimateBetween
+  {
+    tet_printf("AnimateBetween - horizontal\n");
+    Animation animation = Animation::New(1.0f);
+
+    KeyFrames keyFrames1 = KeyFrames::New();
+    keyFrames1.Add(0.0f, sourceOrthographic);
+    keyFrames1.Add(1.0f, targetOrthographic);
+
+    KeyFrames keyFrames2 = KeyFrames::New();
+    keyFrames2.Add(0.0f, sourceAspect);
+    keyFrames2.Add(1.0f, targetAspect);
+
+    animation.AnimateBetween(Property(camera, DevelCameraActor::Property::ORTHOGRAPHIC_SIZE), keyFrames1);
+    animation.AnimateBetween(Property(camera, CameraActor::Property::ASPECT_RATIO), keyFrames2);
+
+    animation.Play();
+    TestAnimationProgress();
+  }
+
+  // AnimateBy
+  {
+    tet_printf("AnimateBy - horizontal\n");
+    camera.SetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, sourceOrthographic);
+    camera.SetProperty(CameraActor::Property::ASPECT_RATIO, sourceAspect);
+    Animation animation = Animation::New(1.0f);
+    animation.AnimateBy(Property(camera, DevelCameraActor::Property::ORTHOGRAPHIC_SIZE), targetOrthographic - sourceOrthographic);
+    animation.AnimateBy(Property(camera, CameraActor::Property::ASPECT_RATIO), targetAspect - sourceAspect);
+    animation.Play();
     TestAnimationProgress();
   }
 
@@ -2288,28 +2627,6 @@ int UtcDaliCameraActorSetPerspectiveProjectionNegative(void)
   END_TEST;
 }
 
-int UtcDaliCameraActorSetOrthographicProjectionNegative01(void)
-{
-  TestApplication   application;
-  Dali::CameraActor instance;
-  try
-  {
-    float arg1(0.0f);
-    float arg2(0.0f);
-    float arg3(0.0f);
-    float arg4(0.0f);
-    float arg5(0.0f);
-    float arg6(0.0f);
-    instance.SetOrthographicProjection(arg1, arg2, arg3, arg4, arg5, arg6);
-    DALI_TEST_CHECK(false); // Should not get here
-  }
-  catch(...)
-  {
-    DALI_TEST_CHECK(true); // We expect an assert
-  }
-  END_TEST;
-}
-
 int UtcDaliCameraActorSetOrthographicProjectionNegative02(void)
 {
   TestApplication   application;
@@ -2407,7 +2724,7 @@ int UtcDaliCameraActorNewDefaultOrthogonalProjection01(void)
   // Check that the properties match to that screen size
   float value;
   actor.GetProperty(CameraActor::Property::ASPECT_RATIO).Get(value);
-  DALI_TEST_EQUALS(800.0f / 480.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+  DALI_TEST_EQUALS(480.0f / 800.0f, value, FLOAT_EPSILON, TEST_LOCATION);
 
   actor.GetProperty(CameraActor::Property::NEAR_PLANE_DISTANCE).Get(value);
   DALI_TEST_EQUALS(800.0f, value, FLOAT_EPSILON, TEST_LOCATION);
@@ -2447,7 +2764,7 @@ int UtcDaliCameraActorNewDefaultOrthogonalProjection02(void)
   // Check that the properties match to that screen size
   float value;
   actor.GetProperty(CameraActor::Property::ASPECT_RATIO).Get(value);
-  DALI_TEST_EQUALS(800.0f / 480.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+  DALI_TEST_EQUALS(480.0f / 800.0f, value, FLOAT_EPSILON, TEST_LOCATION);
 
   actor.GetProperty(CameraActor::Property::NEAR_PLANE_DISTANCE).Get(value);
   DALI_TEST_EQUALS(800.0f, value, FLOAT_EPSILON, TEST_LOCATION);
@@ -2542,34 +2859,6 @@ int UtcDaliCameraActorSetProperty(void)
   camera.Reset();
 
   camera = CameraActor::New();
-  camera.SetProperty(Dali::CameraActor::Property::LEFT_PLANE_DISTANCE, 1.0f);
-  application.GetScene().Add(camera);
-  DALI_TEST_EQUALS(1.0f, camera.GetProperty<float>(Dali::CameraActor::Property::LEFT_PLANE_DISTANCE), TEST_LOCATION);
-  camera.Unparent();
-  camera.Reset();
-
-  camera = CameraActor::New();
-  camera.SetProperty(Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE, 1.0f);
-  application.GetScene().Add(camera);
-  DALI_TEST_EQUALS(1.0f, camera.GetProperty<float>(Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE), TEST_LOCATION);
-  camera.Unparent();
-  camera.Reset();
-
-  camera = CameraActor::New();
-  camera.SetProperty(Dali::CameraActor::Property::TOP_PLANE_DISTANCE, 1.0f);
-  application.GetScene().Add(camera);
-  DALI_TEST_EQUALS(1.0f, camera.GetProperty<float>(Dali::CameraActor::Property::TOP_PLANE_DISTANCE), TEST_LOCATION);
-  camera.Unparent();
-  camera.Reset();
-
-  camera = CameraActor::New();
-  camera.SetProperty(Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE, 1.0f);
-  application.GetScene().Add(camera);
-  DALI_TEST_EQUALS(1.0f, camera.GetProperty<float>(Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE), TEST_LOCATION);
-  camera.Unparent();
-  camera.Reset();
-
-  camera = CameraActor::New();
   camera.SetProperty(Dali::Actor::Property::POSITION, Vector3(100.0f, 100.0f, 100.0f));
   application.GetScene().Add(camera);
   DALI_TEST_EQUALS(Vector3(100.0f, 100.0f, 100.0f), camera.GetProperty<Vector3>(Dali::Actor::Property::POSITION), TEST_LOCATION);
index e62406a..4d17b65 100644 (file)
@@ -214,8 +214,12 @@ int UtcDaliHitTestAlgorithmOrtho02(void)
   Dali::CameraActor cameraActor       = defaultRenderTask.GetCameraActor();
 
   Vector2 stageSize(stage.GetSize());
-  cameraActor.SetOrthographicProjection(-stageSize.x * 0.3f, stageSize.x * 0.7f, stageSize.y * 0.3f, -stageSize.y * 0.7f, 800.0f, 4895.0f);
-  cameraActor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 1600.0f));
+  cameraActor.SetOrthographicProjection(stageSize);
+  cameraActor.SetNearClippingPlane(800.0f);
+  cameraActor.SetFarClippingPlane(4895.0f);
+
+  // Move camera not centered position.
+  cameraActor.SetProperty(Actor::Property::POSITION, Vector3(stageSize.x * 0.2f, stageSize.y * 0.2f, 1600.0f));
 
   Vector2 actorSize(stageSize * 0.5f);
   // Create two actors with half the size of the stage and set them to be partially overlapping
@@ -579,18 +583,18 @@ int UtcDaliHitTestAlgorithmOrder(void)
   Stage   stage = Stage::GetCurrent();
   Vector2 stageSize(stage.GetSize());
 
-  Actor blue = Actor::New();
-  blue[Dali::Actor::Property::NAME] = "Blue";
-  blue[Dali::Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER;
-  blue[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
-  blue[Dali::Actor::Property::WIDTH_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT;
+  Actor blue                                        = Actor::New();
+  blue[Dali::Actor::Property::NAME]                 = "Blue";
+  blue[Dali::Actor::Property::ANCHOR_POINT]         = AnchorPoint::CENTER;
+  blue[Dali::Actor::Property::PARENT_ORIGIN]        = ParentOrigin::CENTER;
+  blue[Dali::Actor::Property::WIDTH_RESIZE_POLICY]  = ResizePolicy::FILL_TO_PARENT;
   blue[Dali::Actor::Property::HEIGHT_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT;
 
-  Actor green = Actor::New();
-  green[Dali::Actor::Property::NAME] = "Green";
-  green[Dali::Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER;
-  green[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
-  green[Dali::Actor::Property::WIDTH_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT;
+  Actor green                                        = Actor::New();
+  green[Dali::Actor::Property::NAME]                 = "Green";
+  green[Dali::Actor::Property::ANCHOR_POINT]         = AnchorPoint::CENTER;
+  green[Dali::Actor::Property::PARENT_ORIGIN]        = ParentOrigin::CENTER;
+  green[Dali::Actor::Property::WIDTH_RESIZE_POLICY]  = ResizePolicy::FILL_TO_PARENT;
   green[Dali::Actor::Property::HEIGHT_RESIZE_POLICY] = ResizePolicy::FILL_TO_PARENT;
 
   stage.Add(blue);
@@ -599,8 +603,8 @@ int UtcDaliHitTestAlgorithmOrder(void)
   RenderTaskList renderTaskList = stage.GetRenderTaskList();
   RenderTask     offRenderTask  = renderTaskList.CreateTask();
 
-  Dali::CameraActor cameraActor = Dali::CameraActor::New(stageSize);
-  cameraActor[Dali::Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER;
+  Dali::CameraActor cameraActor                     = Dali::CameraActor::New(stageSize);
+  cameraActor[Dali::Actor::Property::ANCHOR_POINT]  = AnchorPoint::CENTER;
   cameraActor[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
   stage.Add(cameraActor);
 
@@ -610,8 +614,8 @@ int UtcDaliHitTestAlgorithmOrder(void)
   offRenderTask.SetSourceActor(green);
   offRenderTask.SetScreenToFrameBufferMappingActor(green);
 
-  Dali::Texture texture = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGB888, unsigned(stageSize.width), unsigned(stageSize.height));
-  FrameBuffer renderTarget         = FrameBuffer::New(stageSize.width, stageSize.height, FrameBuffer::Attachment::DEPTH);
+  Dali::Texture texture      = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGB888, unsigned(stageSize.width), unsigned(stageSize.height));
+  FrameBuffer   renderTarget = FrameBuffer::New(stageSize.width, stageSize.height, FrameBuffer::Attachment::DEPTH);
   renderTarget.AttachColorTexture(texture);
   offRenderTask.SetFrameBuffer(renderTarget);
 
index ed942e6..99a098f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -23,12 +23,11 @@ namespace Dali
 {
 namespace DevelCameraActor
 {
-
 void RotateProjection(Dali::CameraActor camera, int32_t rotationAngle)
 {
   Dali::GetImplementation(camera).RotateProjection(rotationAngle);
 }
 
-} // namespace DevelCustomActor
+} // namespace DevelCameraActor
 
 } // namespace Dali
index 3951ca4..93d4e60 100644 (file)
@@ -38,25 +38,40 @@ namespace Property
 enum
 {
   /**
-   * @brief Defines reflection plane for the camera
-   * @details Type Property::VECTOR4
-   * @note Optional
+   * @brief Orthographic Size of this camera.
+   * If ProjectionDirection is Vertical, OrthographicSize is height/2 of viewing cube of Orthographic projection.
+   * If ProjectionDirection is Horizontal, OrthographicSize is width/2 of viewing cube of Orthographic projection.
+   * Remained Width or Height of viewing cube is internally computed by using aspect ratio.
+   *
+   * @details Name "orthographicSize", type Property::FLOAT, animatable, constraint-input
+   * @note Default is 400.0f
    */
-  REFLECTION_PLANE = CameraActor::Property::INVERT_Y_AXIS + 1,
+  ORTHOGRAPHIC_SIZE = 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
+   *  - ProjectionDirection::VERTICAL : basic direction is vertical. so, FoV of horizontal direction become ~75.2 degree
+   *  - ProjectionDirection::HORIZONTAL : basic direction is horizontal. so, FoV of vertical direction become ~46.8 degree
+   *
+   * Another example, if aspect ratio is 4:3 and set orthographicSize as 400.0f.
+   *  - ProjectionDirection::VERTICAL : basic direction is vertical. so, topPlaneDistance become 400.0f, rightPlaneDistance value become 533.3f.
+   *  - ProjectionDirection::HORIZONTAL : basic direction is horizontal. so, topPlaneDistance become 300.0f, rightPlaneDistance value become 400.0f.
    *
    * @details Type Property::INT
-   * @note This property doesn't change FieldOfView value automatically. So result scene might be changed.
+   * @note This property doesn't change FieldOfView and OrthographicSize value automatically. So result scene might be changed.
    * @note Default is ProjectionDirection::VERTICAL.
    */
   PROJECTION_DIRECTION,
+
+  /**
+   * @brief Defines reflection plane for the camera
+   * @details Type Property::VECTOR4
+   * @note Optional
+   */
+  REFLECTION_PLANE,
 };
 
 } // Namespace Property
@@ -68,6 +83,7 @@ enum
  * @param [in] rotationAngle The rotation angle (0, 90, 180, and 270. See Dali::WindowOrientation.)
  */
 DALI_CORE_API void RotateProjection(Dali::CameraActor camera, int32_t rotationAngle);
+
 } // namespace DevelCameraActor
 } // Namespace Dali
 
index 9fc8ead..1c6bb33 100644 (file)
@@ -48,20 +48,22 @@ namespace
  */
 // clang-format off
 DALI_PROPERTY_TABLE_BEGIN
-DALI_PROPERTY( "type",                   INTEGER,  true,    false,   true,   Dali::CameraActor::Property::TYPE                  )
-DALI_PROPERTY( "projectionMode",         INTEGER,  true,    false,   true,   Dali::CameraActor::Property::PROJECTION_MODE       )
-DALI_PROPERTY( "fieldOfView",            FLOAT,    true,    true,    true,   Dali::CameraActor::Property::FIELD_OF_VIEW         )
-DALI_PROPERTY( "aspectRatio",            FLOAT,    true,    false,   true,   Dali::CameraActor::Property::ASPECT_RATIO          )
-DALI_PROPERTY( "nearPlaneDistance",      FLOAT,    true,    false,   true,   Dali::CameraActor::Property::NEAR_PLANE_DISTANCE   )
-DALI_PROPERTY( "farPlaneDistance",       FLOAT,    true,    false,   true,   Dali::CameraActor::Property::FAR_PLANE_DISTANCE    )
-DALI_PROPERTY( "leftPlaneDistance",      FLOAT,    true,    false,   true,   Dali::CameraActor::Property::LEFT_PLANE_DISTANCE   )
-DALI_PROPERTY( "rightPlaneDistance",     FLOAT,    true,    false,   true,   Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE  )
-DALI_PROPERTY( "topPlaneDistance",       FLOAT,    true,    false,   true,   Dali::CameraActor::Property::TOP_PLANE_DISTANCE    )
-DALI_PROPERTY( "bottomPlaneDistance",    FLOAT,    true,    false,   true,   Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE )
-DALI_PROPERTY( "targetPosition",         VECTOR3,  true,    false,   true,   Dali::CameraActor::Property::TARGET_POSITION       )
-DALI_PROPERTY( "projectionMatrix",       MATRIX,   false,   false,   true,   Dali::CameraActor::Property::PROJECTION_MATRIX     )
-DALI_PROPERTY( "viewMatrix",             MATRIX,   false,   false,   true,   Dali::CameraActor::Property::VIEW_MATRIX           )
-DALI_PROPERTY( "invertYAxis",            BOOLEAN,  true,    false,   true,   Dali::CameraActor::Property::INVERT_Y_AXIS         )
+DALI_PROPERTY( "type",                   INTEGER,  true,    false,   true,   Dali::CameraActor::Property::TYPE                      )
+DALI_PROPERTY( "projectionMode",         INTEGER,  true,    false,   true,   Dali::CameraActor::Property::PROJECTION_MODE           )
+DALI_PROPERTY( "fieldOfView",            FLOAT,    true,    true,    true,   Dali::CameraActor::Property::FIELD_OF_VIEW             )
+DALI_PROPERTY( "aspectRatio",            FLOAT,    true,    true,    true,   Dali::CameraActor::Property::ASPECT_RATIO              )
+DALI_PROPERTY( "nearPlaneDistance",      FLOAT,    true,    false,   true,   Dali::CameraActor::Property::NEAR_PLANE_DISTANCE       )
+DALI_PROPERTY( "farPlaneDistance",       FLOAT,    true,    false,   true,   Dali::CameraActor::Property::FAR_PLANE_DISTANCE        )
+DALI_PROPERTY( "leftPlaneDistance",      FLOAT,    false,   false,   true,   Dali::CameraActor::Property::LEFT_PLANE_DISTANCE       )
+DALI_PROPERTY( "rightPlaneDistance",     FLOAT,    false,   false,   true,   Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE      )
+DALI_PROPERTY( "topPlaneDistance",       FLOAT,    false,   false,   true,   Dali::CameraActor::Property::TOP_PLANE_DISTANCE        )
+DALI_PROPERTY( "bottomPlaneDistance",    FLOAT,    false,   false,   true,   Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE     )
+DALI_PROPERTY( "targetPosition",         VECTOR3,  true,    false,   true,   Dali::CameraActor::Property::TARGET_POSITION           )
+DALI_PROPERTY( "projectionMatrix",       MATRIX,   false,   false,   true,   Dali::CameraActor::Property::PROJECTION_MATRIX         )
+DALI_PROPERTY( "viewMatrix",             MATRIX,   false,   false,   true,   Dali::CameraActor::Property::VIEW_MATRIX               )
+DALI_PROPERTY( "invertYAxis",            BOOLEAN,  true,    false,   true,   Dali::CameraActor::Property::INVERT_Y_AXIS             )
+DALI_PROPERTY( "orthographicSize",       FLOAT,    true,    true,    true,   Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE    )
+DALI_PROPERTY( "projectionDirection",    INTEGER,  true,    false,   true,   Dali::DevelCameraActor::Property::PROJECTION_DIRECTION )
 DALI_PROPERTY_TABLE_END( DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX, CameraDefaultProperties )
 // clang-format on
 
@@ -136,6 +138,45 @@ void BuildOrthoPickingRay(const Matrix&   viewMatrix,
   rayDir.w = 1.0f;
 }
 
+/**
+ * @brief Helper class to calculate left/right/top/bottom plane distance by orthographicSize and something other info.
+ * It will resolve some confuse case of plane distance value.
+ * (Something like, Is top plane distance is positive or negative? is aspect ratio is width/height or height/width?)
+ */
+struct OrthographicSizeConverter
+{
+  constexpr OrthographicSizeConverter(float orthographicSize, float aspectRatio, Dali::DevelCameraActor::ProjectionDirection projectionDirection)
+  : mOrthographicSize(orthographicSize),
+    mAspectRatio(aspectRatio),
+    mProjectionDirection(projectionDirection)
+  {
+  }
+
+  inline float LeftPlaneDistance() const
+  {
+    return -(mProjectionDirection == DevelCameraActor::ProjectionDirection::VERTICAL ? mOrthographicSize * mAspectRatio : mOrthographicSize);
+  }
+
+  inline float RightPlaneDistance() const
+  {
+    return (mProjectionDirection == DevelCameraActor::ProjectionDirection::VERTICAL ? mOrthographicSize * mAspectRatio : mOrthographicSize);
+  }
+
+  inline float TopPlaneDistance() const
+  {
+    return (mProjectionDirection == DevelCameraActor::ProjectionDirection::VERTICAL ? mOrthographicSize : mOrthographicSize / mAspectRatio);
+  }
+
+  inline float BottomPlaneDistance() const
+  {
+    return -(mProjectionDirection == DevelCameraActor::ProjectionDirection::VERTICAL ? mOrthographicSize : mOrthographicSize / mAspectRatio);
+  }
+
+  float                                       mOrthographicSize;
+  float                                       mAspectRatio;
+  Dali::DevelCameraActor::ProjectionDirection mProjectionDirection;
+};
+
 } // namespace
 
 CameraActorPtr CameraActor::New(const Size& size)
@@ -172,13 +213,10 @@ CameraActor::CameraActor(const SceneGraph::Node& node)
   mProjectionMode(SceneGraph::Camera::DEFAULT_MODE),
   mProjectionDirection(SceneGraph::Camera::DEFAULT_PROJECTION_DIRECTION),
   mFieldOfView(SceneGraph::Camera::DEFAULT_FIELD_OF_VIEW),
+  mOrthographicSize(SceneGraph::Camera::DEFAULT_ORTHOGRAPHIC_SIZE),
   mAspectRatio(SceneGraph::Camera::DEFAULT_ASPECT_RATIO),
   mNearClippingPlane(SceneGraph::Camera::DEFAULT_NEAR_CLIPPING_PLANE),
   mFarClippingPlane(SceneGraph::Camera::DEFAULT_FAR_CLIPPING_PLANE),
-  mLeftClippingPlane(SceneGraph::Camera::DEFAULT_LEFT_CLIPPING_PLANE),
-  mRightClippingPlane(SceneGraph::Camera::DEFAULT_RIGHT_CLIPPING_PLANE),
-  mTopClippingPlane(SceneGraph::Camera::DEFAULT_TOP_CLIPPING_PLANE),
-  mBottomClippingPlane(SceneGraph::Camera::DEFAULT_BOTTOM_CLIPPING_PLANE),
   mInvertYAxis(SceneGraph::Camera::DEFAULT_INVERT_Y_AXIS),
   mPropertyChanged(false)
 {
@@ -293,6 +331,29 @@ float CameraActor::GetCurrentFieldOfView() const
   return GetCameraSceneObject().GetFieldOfView(GetEventThreadServices().GetEventBufferIndex());
 }
 
+void CameraActor::SetOrthographicSize(float orthographicSize)
+{
+  mPropertyChanged = true;
+  if(!Equals(orthographicSize, mOrthographicSize))
+  {
+    mOrthographicSize = orthographicSize;
+
+    // sceneObject is being used in a separate thread; queue a message to set
+    BakeOrthographicSizeMessage(GetEventThreadServices(), GetCameraSceneObject(), mOrthographicSize);
+  }
+}
+
+float CameraActor::GetOrthographicSize() const
+{
+  return mOrthographicSize;
+}
+
+float CameraActor::GetCurrentOrthographicSize() const
+{
+  // node is being used in a separate thread; copy the value from the previous update
+  return GetCameraSceneObject().GetOrthographicSize(GetEventThreadServices().GetEventBufferIndex());
+}
+
 void CameraActor::SetAspectRatio(float aspectRatio)
 {
   mPropertyChanged = true;
@@ -301,7 +362,7 @@ void CameraActor::SetAspectRatio(float aspectRatio)
     mAspectRatio = aspectRatio;
 
     // sceneObject is being used in a separate thread; queue a message to set
-    SetAspectRatioMessage(GetEventThreadServices(), GetCameraSceneObject(), mAspectRatio);
+    BakeAspectRatioMessage(GetEventThreadServices(), GetCameraSceneObject(), mAspectRatio);
   }
 }
 
@@ -310,6 +371,12 @@ float CameraActor::GetAspectRatio() const
   return mAspectRatio;
 }
 
+float CameraActor::GetCurrentAspectRatio() const
+{
+  // node is being used in a separate thread; copy the value from the previous update
+  return GetCameraSceneObject().GetAspectRatio(GetEventThreadServices().GetEventBufferIndex());
+}
+
 void CameraActor::SetNearClippingPlane(float nearClippingPlane)
 {
   mPropertyChanged = true;
@@ -344,54 +411,6 @@ float CameraActor::GetFarClippingPlane() const
   return mFarClippingPlane;
 }
 
-void CameraActor::SetLeftClippingPlane(float leftClippingPlane)
-{
-  mPropertyChanged = true;
-  if(!Equals(leftClippingPlane, mLeftClippingPlane))
-  {
-    mLeftClippingPlane = leftClippingPlane;
-
-    // sceneObject is being used in a separate thread; queue a message to set
-    SetLeftClippingPlaneMessage(GetEventThreadServices(), GetCameraSceneObject(), mLeftClippingPlane);
-  }
-}
-
-void CameraActor::SetRightClippingPlane(float rightClippingPlane)
-{
-  mPropertyChanged = true;
-  if(!Equals(rightClippingPlane, mRightClippingPlane))
-  {
-    mRightClippingPlane = rightClippingPlane;
-
-    // sceneObject is being used in a separate thread; queue a message to set
-    SetRightClippingPlaneMessage(GetEventThreadServices(), GetCameraSceneObject(), mRightClippingPlane);
-  }
-}
-
-void CameraActor::SetTopClippingPlane(float topClippingPlane)
-{
-  mPropertyChanged = true;
-  if(!Equals(topClippingPlane, mTopClippingPlane))
-  {
-    mTopClippingPlane = topClippingPlane;
-
-    // sceneObject is being used in a separate thread; queue a message to set
-    SetTopClippingPlaneMessage(GetEventThreadServices(), GetCameraSceneObject(), mTopClippingPlane);
-  }
-}
-
-void CameraActor::SetBottomClippingPlane(float bottomClippingPlane)
-{
-  mPropertyChanged = true;
-  if(!Equals(bottomClippingPlane, mBottomClippingPlane))
-  {
-    mBottomClippingPlane = bottomClippingPlane;
-
-    // sceneObject is being used in a separate thread; queue a message to set
-    SetBottomClippingPlaneMessage(GetEventThreadServices(), GetCameraSceneObject(), mBottomClippingPlane);
-  }
-}
-
 void CameraActor::SetInvertYAxis(bool invertYAxis)
 {
   if(invertYAxis != mInvertYAxis)
@@ -411,7 +430,7 @@ bool CameraActor::GetInvertYAxis() const
 void CameraActor::SetPerspectiveProjection(const Size& size)
 {
   SetProjectionMode(Dali::Camera::PERSPECTIVE_PROJECTION);
-  mCanvasSize = size;
+  mCanvasSize = static_cast<const Vector2>(size);
 
   if((size.width < Math::MACHINE_EPSILON_1000) || (size.height < Math::MACHINE_EPSILON_1000))
   {
@@ -428,43 +447,13 @@ void CameraActor::SetPerspectiveProjection(const Size& size)
       return;
     }
   }
-
-  float width  = mCanvasSize.width;
-  float height = mCanvasSize.height;
-
-  float nearClippingPlane;
-  float farClippingPlane;
-  float cameraZ;
-  CalculateClippingAndZ(width, height, nearClippingPlane, farClippingPlane, cameraZ);
-
-  // calculate the position of the camera to have the desired aspect ratio
-  const float fieldOfView = 2.0f * std::atan((mProjectionDirection == DevelCameraActor::ProjectionDirection::VERTICAL ? height : width) * 0.5f / cameraZ);
-
-  // unless it is too small, we want at least as much space to the back as we have torwards the front
-  const float minClippingFarPlane = 2.f * nearClippingPlane;
-  if(farClippingPlane < minClippingFarPlane)
-  {
-    farClippingPlane = minClippingFarPlane;
-  }
-
-  const float aspectRatio = width / height;
-
-  // sceneObject is being used in a separate thread; queue a message to set
-  SetFieldOfView(fieldOfView);
-  SetNearClippingPlane(nearClippingPlane);
-  SetFarClippingPlane(farClippingPlane);
-  SetLeftClippingPlane(width * -0.5f);
-  SetRightClippingPlane(width * 0.5f);
-  SetTopClippingPlane(height * 0.5f);     // Top is +ve to keep consistency with orthographic values
-  SetBottomClippingPlane(height * -0.5f); // Bottom is -ve to keep consistency with orthographic values
-  SetAspectRatio(aspectRatio);
-  SetZ(cameraZ);
+  ApplyDefaultProjection();
 }
 
-void CameraActor::SetOrthographicProjection(const Vector2& size)
+void CameraActor::SetOrthographicProjection(const Size& size)
 {
   SetProjectionMode(Dali::Camera::ORTHOGRAPHIC_PROJECTION);
-  mCanvasSize = size;
+  mCanvasSize = static_cast<const Vector2>(size);
 
   if((size.width < Math::MACHINE_EPSILON_1000) || (size.height < Math::MACHINE_EPSILON_1000))
   {
@@ -482,24 +471,42 @@ void CameraActor::SetOrthographicProjection(const Vector2& size)
     }
   }
 
+  ApplyDefaultProjection();
+}
+
+void CameraActor::ApplyDefaultProjection()
+{
+  const float width  = mCanvasSize.width;
+  const float height = mCanvasSize.height;
+
   // Choose near, far and Z parameters to match the SetPerspectiveProjection above.
   float nearClippingPlane;
   float farClippingPlane;
   float cameraZ;
-  CalculateClippingAndZ(size.width, size.height, nearClippingPlane, farClippingPlane, cameraZ);
-  SetOrthographicProjection(-size.x * 0.5f, size.x * 0.5f, size.y * 0.5f, size.y * -0.5f, nearClippingPlane, farClippingPlane);
-  SetZ(cameraZ);
-}
+  CalculateClippingAndZ(width, height, nearClippingPlane, farClippingPlane, cameraZ);
 
-void CameraActor::SetOrthographicProjection(float left, float right, float top, float bottom, float near, float far)
-{
-  SetProjectionMode(Dali::Camera::ORTHOGRAPHIC_PROJECTION);
-  SetLeftClippingPlane(left);
-  SetRightClippingPlane(right);
-  SetTopClippingPlane(top);
-  SetBottomClippingPlane(bottom);
-  SetNearClippingPlane(near);
-  SetFarClippingPlane(far);
+  // calculate orthographic size.
+  const float orthographicSize = (mProjectionDirection == DevelCameraActor::ProjectionDirection::VERTICAL ? height : width) * 0.5f;
+
+  // calculate the position of the camera to have the desired aspect ratio
+  const float fieldOfView = 2.0f * std::atan(orthographicSize / cameraZ);
+
+  // unless it is too small, we want at least as much space to the back as we have torwards the front
+  const float minClippingFarPlane = 2.f * nearClippingPlane;
+  if(farClippingPlane < minClippingFarPlane)
+  {
+    farClippingPlane = minClippingFarPlane;
+  }
+
+  const float aspectRatio = width / height;
+
+  // sceneObject is being used in a separate thread; queue a message to set
+  SetFieldOfView(fieldOfView);
+  SetNearClippingPlane(nearClippingPlane);
+  SetFarClippingPlane(farClippingPlane);
+  SetAspectRatio(aspectRatio);
+  SetOrthographicSize(orthographicSize);
+  SetZ(cameraZ);
 }
 
 bool CameraActor::BuildPickingRay(const Vector2&  screenCoordinates,
@@ -607,6 +614,11 @@ void CameraActor::SetDefaultProperty(Property::Index index, const Property::Valu
         SetFieldOfView(propertyValue.Get<float>()); // set to 0 in case property is not float
         break;
       }
+      case Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE:
+      {
+        SetOrthographicSize(propertyValue.Get<float>()); // set to 0 in case property is not float
+        break;
+      }
       case Dali::CameraActor::Property::ASPECT_RATIO:
       {
         SetAspectRatio(propertyValue.Get<float>()); // set to 0 in case property is not float
@@ -624,22 +636,22 @@ void CameraActor::SetDefaultProperty(Property::Index index, const Property::Valu
       }
       case Dali::CameraActor::Property::LEFT_PLANE_DISTANCE:
       {
-        SetLeftClippingPlane(propertyValue.Get<float>()); // set to 0 in case property is not float
+        DALI_LOG_WARNING("LEFT_PLANE_DISTANCE is read-only\n");
         break;
       }
       case Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE:
       {
-        SetRightClippingPlane(propertyValue.Get<float>()); // set to 0 in case property is not float
+        DALI_LOG_WARNING("RIGHT_PLANE_DISTANCE is read-only\n");
         break;
       }
       case Dali::CameraActor::Property::TOP_PLANE_DISTANCE:
       {
-        SetTopClippingPlane(propertyValue.Get<float>()); // set to 0 in case property is not float
+        DALI_LOG_WARNING("TOP_PLANE_DISTANCE is read-only\n");
         break;
       }
       case Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE:
       {
-        SetBottomClippingPlane(propertyValue.Get<float>()); // set to 0 in case property is not float
+        DALI_LOG_WARNING("BOTTOM_PLANE_DISTANCE is read-only\n");
         break;
       }
       case Dali::CameraActor::Property::TARGET_POSITION:
@@ -710,6 +722,11 @@ Property::Value CameraActor::GetDefaultProperty(Property::Index index) const
         ret = mFieldOfView;
         break;
       }
+      case Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE:
+      {
+        ret = mOrthographicSize;
+        break;
+      }
       case Dali::CameraActor::Property::ASPECT_RATIO:
       {
         ret = mAspectRatio;
@@ -727,22 +744,22 @@ Property::Value CameraActor::GetDefaultProperty(Property::Index index) const
       }
       case Dali::CameraActor::Property::LEFT_PLANE_DISTANCE:
       {
-        ret = mLeftClippingPlane;
+        ret = OrthographicSizeConverter(mOrthographicSize, mAspectRatio, mProjectionDirection).LeftPlaneDistance();
         break;
       }
       case Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE:
       {
-        ret = mRightClippingPlane;
+        ret = OrthographicSizeConverter(mOrthographicSize, mAspectRatio, mProjectionDirection).RightPlaneDistance();
         break;
       }
       case Dali::CameraActor::Property::TOP_PLANE_DISTANCE:
       {
-        ret = mTopClippingPlane;
+        ret = OrthographicSizeConverter(mOrthographicSize, mAspectRatio, mProjectionDirection).TopPlaneDistance();
         break;
       }
       case Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE:
       {
-        ret = mBottomClippingPlane;
+        ret = OrthographicSizeConverter(mOrthographicSize, mAspectRatio, mProjectionDirection).BottomPlaneDistance();
         break;
       }
       case Dali::CameraActor::Property::TARGET_POSITION:
@@ -792,6 +809,36 @@ Property::Value CameraActor::GetDefaultPropertyCurrentValue(Property::Index inde
         ret = GetCurrentFieldOfView();
         break;
       }
+      case Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE:
+      {
+        ret = GetCurrentOrthographicSize();
+        break;
+      }
+      case Dali::CameraActor::Property::ASPECT_RATIO:
+      {
+        ret = GetCurrentAspectRatio();
+        break;
+      }
+      case Dali::CameraActor::Property::LEFT_PLANE_DISTANCE:
+      {
+        ret = OrthographicSizeConverter(GetCurrentOrthographicSize(), GetCurrentAspectRatio(), mProjectionDirection).LeftPlaneDistance();
+        break;
+      }
+      case Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE:
+      {
+        ret = OrthographicSizeConverter(GetCurrentOrthographicSize(), GetCurrentAspectRatio(), mProjectionDirection).RightPlaneDistance();
+        break;
+      }
+      case Dali::CameraActor::Property::TOP_PLANE_DISTANCE:
+      {
+        ret = OrthographicSizeConverter(GetCurrentOrthographicSize(), GetCurrentAspectRatio(), mProjectionDirection).TopPlaneDistance();
+        break;
+      }
+      case Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE:
+      {
+        ret = OrthographicSizeConverter(GetCurrentOrthographicSize(), GetCurrentAspectRatio(), mProjectionDirection).BottomPlaneDistance();
+        break;
+      }
       default:
       {
         ret = GetDefaultProperty(index); // Most are event-side properties, the scene-graph properties are only on the scene-graph
@@ -822,6 +869,16 @@ void CameraActor::OnNotifyDefaultPropertyAnimation(Animation& animation, Propert
             value.Get(mFieldOfView);
             break;
           }
+          case Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE:
+          {
+            value.Get(mOrthographicSize);
+            break;
+          }
+          case Dali::CameraActor::Property::ASPECT_RATIO:
+          {
+            value.Get(mAspectRatio);
+            break;
+          }
         }
         break;
       }
@@ -834,6 +891,16 @@ void CameraActor::OnNotifyDefaultPropertyAnimation(Animation& animation, Propert
             AdjustValue<float>(mFieldOfView, value);
             break;
           }
+          case Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE:
+          {
+            AdjustValue<float>(mOrthographicSize, value);
+            break;
+          }
+          case Dali::CameraActor::Property::ASPECT_RATIO:
+          {
+            AdjustValue<float>(mAspectRatio, value);
+            break;
+          }
         }
         break;
       }
@@ -851,6 +918,16 @@ const SceneGraph::PropertyBase* CameraActor::GetSceneObjectAnimatableProperty(Pr
       property = GetCameraSceneObject().GetFieldOfView();
       break;
     }
+    case Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE:
+    {
+      property = GetCameraSceneObject().GetOrthographicSize();
+      break;
+    }
+    case Dali::CameraActor::Property::ASPECT_RATIO:
+    {
+      property = GetCameraSceneObject().GetAspectRatio();
+      break;
+    }
       // no default on purpose as we chain method up to actor
   }
   if(!property)
@@ -861,6 +938,7 @@ const SceneGraph::PropertyBase* CameraActor::GetSceneObjectAnimatableProperty(Pr
 
   return property;
 }
+
 const PropertyInputImpl* CameraActor::GetSceneObjectInputProperty(Property::Index index) const
 {
   const PropertyInputImpl* property(nullptr);
@@ -872,6 +950,16 @@ const PropertyInputImpl* CameraActor::GetSceneObjectInputProperty(Property::Inde
       property = GetCameraSceneObject().GetFieldOfView();
       break;
     }
+    case Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE:
+    {
+      property = GetCameraSceneObject().GetOrthographicSize();
+      break;
+    }
+    case Dali::CameraActor::Property::ASPECT_RATIO:
+    {
+      property = GetCameraSceneObject().GetAspectRatio();
+      break;
+    }
     case Dali::CameraActor::Property::PROJECTION_MATRIX:
     {
       property = GetCameraSceneObject().GetProjectionMatrix();
index 407dc18..6ecb3ed 100644 (file)
@@ -107,11 +107,20 @@ public:
   float GetFieldOfView() const;
 
   /**
-   * @brief Retrieve the CameraActor's field of view from update side.
-   * This field of view will be the fov set or animating but will be a frame behind.
-   * @return The field of view.
+   * @brief Sets the orthographic size.
+   * Orthographic size will be used when ProjectoinMode is ORTHOGRAPHIC_PROJECTION.
+   *
+   * @param[in] orthographicSize The orthographic size.
    */
-  float GetCurrentFieldOfView() const;
+  void SetOrthographicSize(float orthographicSize);
+
+  /**
+   * @brief Gets the orthographic size.
+   *
+   * The default orthographic size is 400.0f.
+   * @return The orthographic size.
+   */
+  float GetOrthographicSize() const;
 
   /**
    * @copydoc Dali::CameraActor::SetAspectRatio
@@ -144,26 +153,6 @@ public:
   float GetFarClippingPlane() const;
 
   /**
-   * @param leftClippingPlane to use
-   */
-  void SetLeftClippingPlane(float leftClippingPlane);
-
-  /**
-   * @param rightClippingPlane to use
-   */
-  void SetRightClippingPlane(float rightClippingPlane);
-
-  /**
-   * @param topClippingPlane to use
-   */
-  void SetTopClippingPlane(float topClippingPlane);
-
-  /**
-   * @param bottomClippingPlane to use
-   */
-  void SetBottomClippingPlane(float bottomClippingPlane);
-
-  /**
    * @copydoc Dali::CameraActor::SetInvertYAxis
    */
   void SetInvertYAxis(bool invertYAxis);
@@ -179,14 +168,9 @@ public:
   void SetPerspectiveProjection(const Size& size);
 
   /**
-   * @copydoc Dali::CameraActor::SetOrthographicProjection(const Vector2& size);
+   * @copydoc Dali::CameraActor::SetOrthographicProjection(const Size& size);
    */
-  void SetOrthographicProjection(const Vector2& size);
-
-  /**
-   * @copydoc Dali::CameraActor::SetOrthographicProjection(float left, float right, float top, float bottom, float near, float far);
-   */
-  void SetOrthographicProjection(float left, float right, float top, float bottom, float near, float far);
+  void SetOrthographicProjection(const Size& size);
 
   /**
    * Build a picking ray with this camera and given screen coordinates
@@ -276,6 +260,36 @@ private:
    */
   void OnPropertySet(Property::Index index, const Property::Value& propertyValue) override;
 
+  /**
+   * @brief Set the camera projection values with mCanvasSize
+   */
+  void ApplyDefaultProjection();
+
+private:
+  /**
+   * @brief Retrieve the CameraActor's field of view from update side.
+   * This is either the last value set, or the currently animating value.
+   * It may be defferent to GetFieldOfView() if the set message hasn't been processed yet.
+   * @return The field of view.
+   */
+  float GetCurrentFieldOfView() const;
+
+  /**
+   * @brief Retrieve the CameraActor's orthographic size from update side.
+   * This is either the last value set, or the currently animating value.
+   * It may be defferent to GetOrthographicSize() if the set message hasn't been processed yet.
+   * @return The orthographic size.
+   */
+  float GetCurrentOrthographicSize() const;
+
+  /**
+   * @brief Retrieve the CameraActor's aspect ratio from update side.
+   * This is either the last value set, or the currently animating value.
+   * It may be defferent to GetAspectRatio() if the set message hasn't been processed yet.
+   * @return The aspect ratio.
+   */
+  float GetCurrentAspectRatio() const;
+
 private: // Data
   Vector3                                     mTarget;
   Vector2                                     mCanvasSize;
@@ -283,13 +297,10 @@ private: // Data
   Dali::Camera::ProjectionMode                mProjectionMode;
   Dali::DevelCameraActor::ProjectionDirection mProjectionDirection;
   float                                       mFieldOfView;
+  float                                       mOrthographicSize;
   float                                       mAspectRatio;
   float                                       mNearClippingPlane;
   float                                       mFarClippingPlane;
-  float                                       mLeftClippingPlane;
-  float                                       mRightClippingPlane;
-  float                                       mTopClippingPlane;
-  float                                       mBottomClippingPlane;
   bool                                        mInvertYAxis;
   bool                                        mPropertyChanged;
 };
index cd7ccb2..aae62bd 100644 (file)
@@ -227,9 +227,13 @@ inline void AddRendererToRenderList(BufferIndex               updateBufferIndex,
         // Assume actors are at z=0, compute AABB in view space & test rect intersection
         // against z=0 plane boundaries for frustum. (NOT viewport). This should take into account
         // magnification due to FOV etc.
+
+        // TODO : Below logic might need to refactor it.
+        // If camera is Perspective, we need to calculate clipping box by FoV. Currently, we just believe default camera setup OrthographicSize well.
+        //  - If then, It must use math calculate like tan(fov) internally. So, we might need calculate it only one times, and cache.
         ClippingBox boundingBox = RenderItem::CalculateTransformSpaceAABB(nodeModelViewMatrix, Vector3(nodeUpdateArea.x, nodeUpdateArea.y, 0.0f), Vector3(nodeUpdateArea.z, nodeUpdateArea.w, 0.0f));
-        ClippingBox clippingBox(camera.mLeftClippingPlane, camera.mBottomClippingPlane, camera.mRightClippingPlane - camera.mLeftClippingPlane, fabsf(camera.mBottomClippingPlane - camera.mTopClippingPlane));
-        inside = clippingBox.Intersects(boundingBox);
+        ClippingBox clippingBox = camera.GetOrthographicClippingBox(updateBufferIndex);
+        inside                  = clippingBox.Intersects(boundingBox);
       }
     }
     /*
index 3995388..586d7cc 100644 (file)
@@ -119,27 +119,39 @@ void Perspective(Matrix& result, Dali::DevelCameraActor::ProjectionDirection fov
   Frustum(result, -frustumW, frustumW, -frustumH, frustumH, near, far, invertYAxis);
 }
 
-void Orthographic(Matrix& result, float left, float right, float bottom, float top, float near, float far, bool invertYAxis)
+void Orthographic(Matrix& result, Dali::DevelCameraActor::ProjectionDirection orthographicDir, float orthographicSize, float aspect, float near, float far, bool invertYAxis)
 {
-  if(Equals(right, left) || Equals(top, bottom) || Equals(far, near))
+  if(EqualsZero(orthographicSize) || EqualsZero(aspect) || Equals(far, near))
   {
     DALI_LOG_ERROR("Cannot create orthographic projection matrix with a zero dimension.\n");
     DALI_ASSERT_DEBUG("Cannot create orthographic projection matrix with a zero dimension.");
     return;
   }
 
-  float deltaX = right - left;
-  float deltaY = invertYAxis ? bottom - top : top - bottom;
+  float halfDeltaX;
+  float halfDeltaY;
+  if(orthographicDir == Dali::DevelCameraActor::ProjectionDirection::VERTICAL)
+  {
+    halfDeltaY = orthographicSize;
+    halfDeltaX = halfDeltaY * aspect;
+  }
+  else
+  {
+    halfDeltaX = orthographicSize;
+    halfDeltaY = halfDeltaX / aspect;
+  }
+
   float deltaZ = far - near;
 
   float* m = result.AsFloat();
-  m[0]     = -2.0f / deltaX;
-  m[1]     = 0.0f;
-  m[2]     = 0.0f;
-  m[3]     = 0.0f;
+
+  m[0] = -1.0f / halfDeltaX;
+  m[1] = 0.0f;
+  m[2] = 0.0f;
+  m[3] = 0.0f;
 
   m[4] = 0.0f;
-  m[5] = -2.0f / deltaY;
+  m[5] = (invertYAxis ? 1.0f : -1.0f) / halfDeltaY;
   m[6] = 0.0f;
   m[7] = 0.0f;
 
@@ -147,8 +159,9 @@ void Orthographic(Matrix& result, float left, float right, float bottom, float t
   m[9]  = 0.0f;
   m[10] = 2.0f / deltaZ;
   m[11] = 0.0f;
-  m[12] = -(right + left) / deltaX;
-  m[13] = -(top + bottom) / deltaY;
+
+  m[12] = 0.0f;
+  m[13] = 0.0f;
   m[14] = -(near + far) / deltaZ;
   m[15] = 1.0f;
 }
@@ -160,12 +173,9 @@ const Dali::Camera::ProjectionMode                Camera::DEFAULT_MODE(Dali::Cam
 const Dali::DevelCameraActor::ProjectionDirection Camera::DEFAULT_PROJECTION_DIRECTION(Dali::DevelCameraActor::VERTICAL);
 const bool                                        Camera::DEFAULT_INVERT_Y_AXIS(false);
 const float                                       Camera::DEFAULT_FIELD_OF_VIEW(45.0f * (Math::PI / 180.0f));
-const float                                       Camera::DEFAULT_ASPECT_RATIO(800.0f / 480.0f);
-const float                                       Camera::DEFAULT_LEFT_CLIPPING_PLANE(-240.0f);
-const float                                       Camera::DEFAULT_RIGHT_CLIPPING_PLANE(240.0f);
-const float                                       Camera::DEFAULT_TOP_CLIPPING_PLANE(-400.0f);
-const float                                       Camera::DEFAULT_BOTTOM_CLIPPING_PLANE(400.0f);
-const float                                       Camera::DEFAULT_NEAR_CLIPPING_PLANE(800.0f); // default height of the screen
+const float                                       Camera::DEFAULT_ORTHOGRAPHIC_SIZE(400.0f);     // half of default height of the screen
+const float                                       Camera::DEFAULT_ASPECT_RATIO(480.0f / 800.0f); // default width / default height of the screen
+const float                                       Camera::DEFAULT_NEAR_CLIPPING_PLANE(800.0f);   // default height of the screen
 const float                                       Camera::DEFAULT_FAR_CLIPPING_PLANE(DEFAULT_NEAR_CLIPPING_PLANE + 2.f * DEFAULT_NEAR_CLIPPING_PLANE);
 const Vector3                                     Camera::DEFAULT_TARGET_POSITION(0.0f, 0.0f, 0.0f);
 
@@ -179,11 +189,8 @@ Camera::Camera()
   mProjectionDirection(DEFAULT_PROJECTION_DIRECTION),
   mInvertYAxis(DEFAULT_INVERT_Y_AXIS),
   mFieldOfView(DEFAULT_FIELD_OF_VIEW),
+  mOrthographicSize(DEFAULT_ORTHOGRAPHIC_SIZE),
   mAspectRatio(DEFAULT_ASPECT_RATIO),
-  mLeftClippingPlane(DEFAULT_LEFT_CLIPPING_PLANE),
-  mRightClippingPlane(DEFAULT_RIGHT_CLIPPING_PLANE),
-  mTopClippingPlane(DEFAULT_TOP_CLIPPING_PLANE),
-  mBottomClippingPlane(DEFAULT_BOTTOM_CLIPPING_PLANE),
   mNearClippingPlane(DEFAULT_NEAR_CLIPPING_PLANE),
   mFarClippingPlane(DEFAULT_FAR_CLIPPING_PLANE),
   mTargetPosition(DEFAULT_TARGET_POSITION),
@@ -237,33 +244,15 @@ void Camera::BakeFieldOfView(BufferIndex updateBufferIndex, float fieldOfView)
   mUpdateProjectionFlag = UPDATE_COUNT;
 }
 
-void Camera::SetAspectRatio(float aspectRatio)
-{
-  mAspectRatio          = aspectRatio;
-  mUpdateProjectionFlag = UPDATE_COUNT;
-}
-
-void Camera::SetLeftClippingPlane(float leftClippingPlane)
-{
-  mLeftClippingPlane    = leftClippingPlane;
-  mUpdateProjectionFlag = UPDATE_COUNT;
-}
-
-void Camera::SetRightClippingPlane(float rightClippingPlane)
-{
-  mRightClippingPlane   = rightClippingPlane;
-  mUpdateProjectionFlag = UPDATE_COUNT;
-}
-
-void Camera::SetTopClippingPlane(float topClippingPlane)
+void Camera::BakeOrthographicSize(BufferIndex updateBufferIndex, float orthographicSize)
 {
-  mTopClippingPlane     = topClippingPlane;
+  mOrthographicSize.Bake(updateBufferIndex, orthographicSize);
   mUpdateProjectionFlag = UPDATE_COUNT;
 }
 
-void Camera::SetBottomClippingPlane(float bottomClippingPlane)
+void Camera::BakeAspectRatio(BufferIndex updateBufferIndex, float aspectRatio)
 {
-  mBottomClippingPlane  = bottomClippingPlane;
+  mAspectRatio.Bake(updateBufferIndex, aspectRatio);
   mUpdateProjectionFlag = UPDATE_COUNT;
 }
 
@@ -377,6 +366,16 @@ const PropertyBase* Camera::GetFieldOfView() const
   return &mFieldOfView;
 }
 
+const PropertyBase* Camera::GetOrthographicSize() const
+{
+  return &mOrthographicSize;
+}
+
+const PropertyBase* Camera::GetAspectRatio() const
+{
+  return &mAspectRatio;
+}
+
 const PropertyInputImpl* Camera::GetProjectionMatrix() const
 {
   return &mProjectionMatrix;
@@ -439,7 +438,9 @@ bool Camera::ViewMatrixUpdated() const
 
 bool Camera::IsProjectionMatrixAnimated() const
 {
-  return !mFieldOfView.IsClean();
+  return !mFieldOfView.IsClean() ||
+         !mOrthographicSize.IsClean() ||
+         !mAspectRatio.IsClean();
 }
 
 uint32_t Camera::UpdateViewMatrix(BufferIndex updateBufferIndex)
@@ -630,6 +631,16 @@ bool Camera::CheckAABBInFrustum(BufferIndex bufferIndex, const Vector3& origin,
   }
   return true;
 }
+Dali::Rect<int32_t> Camera::GetOrthographicClippingBox(BufferIndex bufferIndex) const
+{
+  const float orthographicSize = mOrthographicSize[bufferIndex];
+  const float aspect           = mAspectRatio[bufferIndex];
+
+  const float halfWidth  = mProjectionDirection == DevelCameraActor::ProjectionDirection::VERTICAL ? orthographicSize * aspect : orthographicSize;
+  const float halfHeight = mProjectionDirection == DevelCameraActor::ProjectionDirection::VERTICAL ? orthographicSize : orthographicSize / aspect;
+
+  return Dali::Rect<int32_t>(-halfWidth, -halfHeight, halfWidth * 2.0f, halfHeight * 2.0f);
+}
 
 uint32_t Camera::UpdateProjection(BufferIndex updateBufferIndex)
 {
@@ -657,7 +668,7 @@ uint32_t Camera::UpdateProjection(BufferIndex updateBufferIndex)
           Perspective(projectionMatrix,
                       mProjectionDirection,
                       mFieldOfView[updateBufferIndex],
-                      mAspectRatio,
+                      mAspectRatio[updateBufferIndex],
                       mNearClippingPlane,
                       mFarClippingPlane,
                       mInvertYAxis);
@@ -693,10 +704,9 @@ uint32_t Camera::UpdateProjection(BufferIndex updateBufferIndex)
         {
           Matrix& projectionMatrix = mProjectionMatrix.Get(updateBufferIndex);
           Orthographic(projectionMatrix,
-                       mLeftClippingPlane,
-                       mRightClippingPlane,
-                       mBottomClippingPlane,
-                       mTopClippingPlane,
+                       mProjectionDirection,
+                       mOrthographicSize[updateBufferIndex],
+                       mAspectRatio[updateBufferIndex],
                        mNearClippingPlane,
                        mFarClippingPlane,
                        mInvertYAxis);
index e1bac63..6604fb9 100644 (file)
@@ -61,6 +61,7 @@ public:
   static const Dali::DevelCameraActor::ProjectionDirection DEFAULT_PROJECTION_DIRECTION;
   static const bool                                        DEFAULT_INVERT_Y_AXIS;
   static const float                                       DEFAULT_FIELD_OF_VIEW;
+  static const float                                       DEFAULT_ORTHOGRAPHIC_SIZE;
   static const float                                       DEFAULT_ASPECT_RATIO;
   static const float                                       DEFAULT_LEFT_CLIPPING_PLANE;
   static const float                                       DEFAULT_RIGHT_CLIPPING_PLANE;
@@ -136,11 +137,6 @@ public:
   void SetProjectionDirection(Dali::DevelCameraActor::ProjectionDirection direction);
 
   /**
-   * @copydoc Dali::Internal::CameraActor::SetAspectRatio
-   */
-  void SetAspectRatio(float aspectRatio);
-
-  /**
    * @copydoc Dali::Internal::CameraActor::SetLeftClippingPlane
    */
   void SetLeftClippingPlane(float leftClippingPlane);
@@ -183,7 +179,7 @@ public:
   /**
    * @brief Bakes the field of view.
    * @param[in] updateBufferIndex The current update buffer index.
-   * @param[in] opacity The field of view.
+   * @param[in] fieldOfView The field of view.
    */
   void BakeFieldOfView(BufferIndex updateBufferIndex, float fieldOfView);
 
@@ -198,6 +194,40 @@ public:
   }
 
   /**
+   * @brief Bakes the orthographic size.
+   * @param[in] updateBufferIndex The current update buffer index.
+   * @param[in] orthographicSize The orthographic size.
+   */
+  void BakeOrthographicSize(BufferIndex updateBufferIndex, float orthographicSize);
+
+  /**
+   * @brief Retrieve the orthographic size.
+   * @param[in] bufferIndex The buffer to read from.
+   * @return The orthographic size.
+   */
+  float GetOrthographicSize(BufferIndex bufferIndex) const
+  {
+    return mOrthographicSize[bufferIndex];
+  }
+
+  /**
+   * @brief Bakes the aspect ratio.
+   * @param[in] updateBufferIndex The current update buffer index.
+   * @param[in] aspectRatio The aspect ratio.
+   */
+  void BakeAspectRatio(BufferIndex updateBufferIndex, float aspectRatio);
+
+  /**
+   * @brief Retrieve the aspect ratio.
+   * @param[in] bufferIndex The buffer to read from.
+   * @return The aspect ratio.
+   */
+  float GetAspectRatio(BufferIndex bufferIndex) const
+  {
+    return mAspectRatio[bufferIndex];
+  }
+
+  /**
    * Sets the reflection plane
    * @param[in] plane reflection plane
    */
@@ -242,6 +272,11 @@ public:
   bool CheckAABBInFrustum(BufferIndex bufferIndex, const Vector3& origin, const Vector3& halfExtents) const;
 
   /**
+   * @brief Calculate orthographic clipping box by this camera's orthographic size.
+   */
+  Dali::Rect<int32_t> GetOrthographicClippingBox(BufferIndex bufferIndex) const;
+
+  /**
    * Retrieve the projection-matrix; this is double buffered for input handling.
    * @param[in] bufferIndex The buffer to read from.
    * @return The projection-matrix.
@@ -270,6 +305,20 @@ public:
   const PropertyBase* GetFieldOfView() const;
 
   /**
+   * Retrieve the orthographic size property querying interface.
+   * @pre The camera is on-stage.
+   * @return The orthographic size property querying interface.
+   */
+  const PropertyBase* GetOrthographicSize() const;
+
+  /**
+   * Retrieve the aspect ratio property querying interface.
+   * @pre The camera is on-stage.
+   * @return The aspect ratio property querying interface.
+   */
+  const PropertyBase* GetAspectRatio() const;
+
+  /**
    * Retrieve the projection-matrix property querying interface.
    * @pre The camera is on-stage.
    * @return The projection-matrix property querying interface.
@@ -352,13 +401,10 @@ public:                                                             // PROPERTIE
   Dali::DevelCameraActor::ProjectionDirection mProjectionDirection; // Non-animatable
   bool                                        mInvertYAxis;         // Non-animatable
 
-  AnimatableProperty<float> mFieldOfView; // Animatable
+  AnimatableProperty<float> mFieldOfView;      // Animatable
+  AnimatableProperty<float> mOrthographicSize; // Animatable
+  AnimatableProperty<float> mAspectRatio;      // Animatable
 
-  float   mAspectRatio;
-  float   mLeftClippingPlane;
-  float   mRightClippingPlane;
-  float   mTopClippingPlane;
-  float   mBottomClippingPlane;
   float   mNearClippingPlane;
   float   mFarClippingPlane;
   Vector3 mTargetPosition;
@@ -423,59 +469,26 @@ inline void BakeFieldOfViewMessage(EventThreadServices& eventThreadServices, con
   new(slot) LocalType(&camera, &Camera::BakeFieldOfView, parameter);
 }
 
-inline void SetAspectRatioMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
-{
-  using LocalType = MessageValue1<Camera, float>;
-
-  // Reserve some memory inside the message queue
-  uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
-
-  // Construct message in the message queue memory; note that delete should not be called on the return value
-  new(slot) LocalType(&camera, &Camera::SetAspectRatio, parameter);
-}
-
-inline void SetLeftClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
-{
-  using LocalType = MessageValue1<Camera, float>;
-
-  // Reserve some memory inside the message queue
-  uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
-
-  // Construct message in the message queue memory; note that delete should not be called on the return value
-  new(slot) LocalType(&camera, &Camera::SetLeftClippingPlane, parameter);
-}
-
-inline void SetRightClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
-{
-  using LocalType = MessageValue1<Camera, float>;
-
-  // Reserve some memory inside the message queue
-  uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
-
-  // Construct message in the message queue memory; note that delete should not be called on the return value
-  new(slot) LocalType(&camera, &Camera::SetRightClippingPlane, parameter);
-}
-
-inline void SetTopClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
+inline void BakeOrthographicSizeMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
 {
-  using LocalType = MessageValue1<Camera, float>;
+  using LocalType = MessageDoubleBuffered1<Camera, float>;
 
   // Reserve some memory inside the message queue
   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
-  new(slot) LocalType(&camera, &Camera::SetTopClippingPlane, parameter);
+  new(slot) LocalType(&camera, &Camera::BakeOrthographicSize, parameter);
 }
 
-inline void SetBottomClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
+inline void BakeAspectRatioMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
 {
-  using LocalType = MessageValue1<Camera, float>;
+  using LocalType = MessageDoubleBuffered1<Camera, float>;
 
   // Reserve some memory inside the message queue
   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
-  new(slot) LocalType(&camera, &Camera::SetBottomClippingPlane, parameter);
+  new(slot) LocalType(&camera, &Camera::BakeAspectRatio, parameter);
 }
 
 inline void SetNearClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
index 93c1cfd..5222c0d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -144,14 +144,9 @@ void CameraActor::SetPerspectiveProjection(const Size& size)
   GetImplementation(*this).SetPerspectiveProjection(size);
 }
 
-void CameraActor::SetOrthographicProjection(const Vector2& size)
+void CameraActor::SetOrthographicProjection(const Size& size)
 {
   GetImplementation(*this).SetOrthographicProjection(size);
 }
 
-void CameraActor::SetOrthographicProjection(float left, float right, float top, float bottom, float near, float far)
-{
-  GetImplementation(*this).SetOrthographicProjection(left, right, top, bottom, near, far);
-}
-
 } // namespace Dali
index 25c6db7..754b70e 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_CAMERA_ACTOR_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.
@@ -223,6 +223,7 @@ public:
 
   /**
    * @brief Sets the field of view.
+   * Field of view will be used when ProjectionMode is PERSPECTIVE_PROJECTION.
    *
    * @SINCE_1_0.0
    * @param[in] fieldOfView The field of view in radians
@@ -332,6 +333,7 @@ public:
    * Sets the near and far clipping planes, the field of view, the aspect ratio,
    * and the Z position of the actor based on the canvas size so that 1 unit in
    * XY (z=0) plane is 1 pixel on screen.
+   * Also, It will set orthographic size be fitted as XY plane.
    *
    * @SINCE_1_0.0
    * @param[in] size The canvas size
@@ -357,21 +359,6 @@ public:
    */
   void SetOrthographicProjection(const Size& size);
 
-  /**
-   * @brief Sets the camera projection to use orthographic projection with the given clip planes.
-   *
-   * This does not change the Z value of the camera actor.
-   *
-   * @SINCE_1_0.0
-   * @param[in] left Distance to left clip plane (normal to camera axis)
-   * @param[in] right Distance to right clip plane (normal to camera axis)
-   * @param[in] top Distance to top clip plane (normal to camera axis)
-   * @param[in] bottom Distance to bottom clip plane (normal to camera axis)
-   * @param[in] near Distance to the near clip plane (along camera axis)
-   * @param[in] far Distance to the far clip plane (along camera axis)
-   */
-  void SetOrthographicProjection(float left, float right, float top, float bottom, float near, float far);
-
 public: // Not intended for use by Application developers
   /// @cond internal
   /**