(CameraActor) Use scene's size as the canvas size when a ZERO size is used in SetPers... 84/213384/3
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Wed, 4 Sep 2019 16:41:54 +0000 (17:41 +0100)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Wed, 4 Sep 2019 17:02:18 +0000 (18:02 +0100)
Change-Id: I9546b190e84f65bed91907acb1a71923abe2f567

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

index ac726f7..de0cb29 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
@@ -177,6 +177,47 @@ int UtcDaliCameraActorNewP(void)
   END_TEST;
 }
 
+int UtcDaliCameraActorNewDefaultPerspectiveProjection(void)
+{
+  TestApplication application;
+  tet_infoline( "Test the perspective projection of a camera actor is set appropriately when not passing in a size" );
+
+  CameraActor actor = CameraActor::New();
+  DALI_TEST_CHECK( actor );
+
+  // All the properties should still be the default values
+  // Defaults taken from scene-graph-camera.cpp
+  DALI_TEST_EQUALS( 4.0f/3.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( 0.0f, actor.GetProperty( Actor::Property::POSITION_Z ).Get< float >(), TEST_LOCATION );
+  DALI_TEST_EQUALS( actor.GetProjectionMode(), Dali::Camera::PERSPECTIVE_PROJECTION, TEST_LOCATION );
+
+  // Add it to the stage, then the values should be updated to reflect a 480.0f by 800.0f scene (default stage size)
+  Stage::GetCurrent().Add( actor );
+
+  DALI_TEST_EQUALS( 0.6f, actor.GetProperty( CameraActor::Property::ASPECT_RATIO ).Get< float >(), FLOAT_EPSILON, TEST_LOCATION );
+  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( 1600.0f, actor.GetProperty( Actor::Property::POSITION_Z ).Get< float >(), TEST_LOCATION );
+  DALI_TEST_EQUALS( actor.GetProjectionMode(), Dali::Camera::PERSPECTIVE_PROJECTION, TEST_LOCATION );
+
+  // Ensure the values stay the same after update/render
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( 0.6f, actor.GetProperty( CameraActor::Property::ASPECT_RATIO ).Get< float >(), FLOAT_EPSILON, TEST_LOCATION );
+  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( 1600.0f, actor.GetProperty( Actor::Property::POSITION_Z ).Get< float >(), TEST_LOCATION );
+  DALI_TEST_EQUALS( actor.GetProjectionMode(), Dali::Camera::PERSPECTIVE_PROJECTION, TEST_LOCATION );
+
+  END_TEST;
+}
+
 // Note: No negative test for UtcDaliCameraActorNew.
 
 int UtcDaliCameraActorDownCastP(void)
@@ -797,6 +838,30 @@ int UtcDaliCameraActorSetPerspectiveProjectionP(void)
 
   DALI_TEST_EQUALS( actor.GetProjectionMode(), Dali::Camera::PERSPECTIVE_PROJECTION, TEST_LOCATION );
 
+  // Ensure these values persist after adding to the stage and an update/render pass
+  Stage::GetCurrent().Add( actor );
+  application.SendNotification();
+  application.Render();
+
+  actor.GetProperty( CameraActor::Property::ASPECT_RATIO ).Get( value );
+  DALI_TEST_EQUALS( 0.666666f, value, FLOAT_EPSILON, TEST_LOCATION );
+  actor.GetProperty( CameraActor::Property::FIELD_OF_VIEW ).Get( value );
+  DALI_TEST_EQUALS( 0.489957f, value, FLOAT_EPSILON, TEST_LOCATION );
+  actor.GetProperty( CameraActor::Property::NEAR_PLANE_DISTANCE ).Get( value );
+  DALI_TEST_EQUALS( 150.f, value, FLOAT_EPSILON, TEST_LOCATION );
+  actor.GetProperty( CameraActor::Property::FAR_PLANE_DISTANCE ).Get( value );
+  DALI_TEST_EQUALS( 4245.f, value, FLOAT_EPSILON, TEST_LOCATION );
+
+  // Call method with a ZERO size, this should reset the perspective projection using the size of the scene we've been added to
+  actor.SetPerspectiveProjection( Vector2::ZERO );
+
+  DALI_TEST_EQUALS( 0.6f, actor.GetProperty( CameraActor::Property::ASPECT_RATIO ).Get< float >(), FLOAT_EPSILON, TEST_LOCATION );
+  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( 1600.0f, actor.GetProperty( Actor::Property::POSITION_Z ).Get< float >(), TEST_LOCATION );
+  DALI_TEST_EQUALS( actor.GetProjectionMode(), Dali::Camera::PERSPECTIVE_PROJECTION, TEST_LOCATION );
+
   END_TEST;
 }
 
index f305cf7..a4ec104 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
@@ -602,7 +602,7 @@ int UtcDaliScriptingNewActorChildren(void)
   map[ "position" ] = Vector3::XAXIS;
 
   Property::Map child1Map;
-  child1Map[ "type" ] = "CameraActor";
+  child1Map[ "type" ] = "Layer";
   child1Map[ "position" ] = Vector3::YAXIS;
 
   Property::Array childArray;
@@ -622,7 +622,7 @@ int UtcDaliScriptingNewActorChildren(void)
 
   Actor child1 = handle.GetChildAt(0);
   DALI_TEST_CHECK( child1 );
-  DALI_TEST_CHECK( CameraActor::DownCast( child1 ) );
+  DALI_TEST_CHECK( Layer::DownCast( child1 ) );
   DALI_TEST_EQUALS( child1.GetCurrentPosition(), Vector3::YAXIS, TEST_LOCATION );
   DALI_TEST_EQUALS( child1.GetChildCount(), 0u, TEST_LOCATION );
 
index ae63c9f..b531ab6 100644 (file)
@@ -199,6 +199,15 @@ void CameraActor::OnInitialize()
   AddCameraMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphCameraOwner );
 }
 
+void CameraActor::OnStageConnectionInternal()
+{
+  // If the canvas size has not been set, then use the size of the scene we've been added to to set up the perspective projection
+  if( ( mCanvasSize.width < Math::MACHINE_EPSILON_1000 ) || ( mCanvasSize.height < Math::MACHINE_EPSILON_1000 ) )
+  {
+    SetPerspectiveProjection( GetScene().GetSize() );
+  }
+}
+
 void CameraActor::SetTarget( const Vector3& target )
 {
   if( target != mTarget ) // using range epsilon
@@ -372,15 +381,26 @@ bool CameraActor::GetInvertYAxis() const
 
 void CameraActor::SetPerspectiveProjection( const Size& size )
 {
+  mCanvasSize = size;
+
   if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
   {
-    // Not allowed to set the canvas size to be 0.
-    DALI_LOG_ERROR( "Canvas size can not be 0\n" );
-    return;
+    // If the size given is invalid, i.e. ZERO, then check if we've been added to a scene
+    if( OnStage() )
+    {
+      // We've been added to a scene already, set the canvas size to the scene's size
+      mCanvasSize = GetScene().GetSize();
+    }
+    else
+    {
+      // We've not been added to a scene yet, so just return.
+      // We'll set the canvas size when we get added to a scene later
+      return;
+    }
   }
 
-  float width = size.width;
-  float height = size.height;
+  float width = mCanvasSize.width;
+  float height = mCanvasSize.height;
 
   float nearClippingPlane;
   float farClippingPlane;
index 1694ba3..ecc3638 100644 (file)
@@ -234,14 +234,19 @@ private:
   /**
    * @copydoc Dali::Internal::Actor::OnInitialize()
    */
-  virtual void OnInitialize();
+  void OnInitialize() override;
 
+  /**
+   * @copydoc Dali::Internal::Actor::OnStageConnectionInternal()
+   */
+  void OnStageConnectionInternal() override;
 
 private: // Data
 
   const SceneGraph::Camera* mSceneObject; ///< Not owned
 
   Vector3            mTarget;
+  Vector2            mCanvasSize;
   Dali::Camera::Type mType;
   Dali::Camera::ProjectionMode mProjectionMode;
   float              mFieldOfView;
index 731bf29..c1ceef5 100644 (file)
@@ -135,7 +135,8 @@ public:
   /**
    * @brief Creates a CameraActor object.
    *
-   * @note No default camera perspective projection is set by this method. @see SetPerspectiveProjection().
+   * @note Sets the default camera perspective projection for the size of the scene this is added to. @see SetPerspectiveProjection().
+   * @note When this actor gets added to a scene, then it's Z position will be modified according to the required perspective projection.
    *
    * @SINCE_1_0.0
    * @return The newly created camera actor
@@ -336,7 +337,8 @@ public:
    * @SINCE_1_0.0
    * @param[in] size The canvas size
    * @pre The canvas size must be greater than zero.
-   *
+   * @note If either of the values of size is 0.0f, then we use the default perspective projection for the size of the scene this actor is added to.
+   * @note This modifies the Z position property of this actor as well.
    */
   void SetPerspectiveProjection( const Size& size );