/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
// EXTERNAL INCLUDES
#include <cmath>
+#include <cstring> // for strcmp
// INTERNAL INCLUDES
-#include <dali/public-api/common/stage.h>
-#include <dali/public-api/object/type-registry.h>
-#include <dali/internal/event/actor-attachments/camera-attachment-impl.h>
-#include <dali/internal/event/common/property-helper.h>
-#include <dali/internal/event/common/stage-impl.h>
-#include <dali/internal/event/render-tasks/render-task-impl.h>
-#include <dali/internal/event/render-tasks/render-task-list-impl.h>
+#include <dali/devel-api/actors/camera-actor-devel.h>
+#include <dali/internal/common/matrix-utils.h>
#include <dali/internal/event/common/projection.h>
-#include <dali/integration-api/debug.h>
+#include <dali/internal/event/common/property-helper.h>
+#include <dali/internal/event/common/thread-local-storage.h>
+#include <dali/public-api/object/type-registry.h>
+
+#include <dali/internal/update/common/property-base.h>
+#include <dali/internal/update/manager/update-manager.h>
+#include <dali/internal/update/render-tasks/scene-graph-camera-messages.h>
namespace Dali
{
-
namespace Internal
{
-
namespace
{
-
// Properties
/**
* particularly for the default properties.
* Name Type writable animatable constraint-input enum for index-checking
*/
+// clang-format off
DALI_PROPERTY_TABLE_BEGIN
-DALI_PROPERTY( "type", STRING, true, false, true, Dali::CameraActor::Property::TYPE )
-DALI_PROPERTY( "projection-mode", STRING, true, false, true, Dali::CameraActor::Property::PROJECTION_MODE )
-DALI_PROPERTY( "field-of-view", FLOAT, true, false, true, Dali::CameraActor::Property::FIELD_OF_VIEW )
-DALI_PROPERTY( "aspect-ratio", FLOAT, true, false, true, Dali::CameraActor::Property::ASPECT_RATIO )
-DALI_PROPERTY( "near-plane-distance", FLOAT, true, false, true, Dali::CameraActor::Property::NEAR_PLANE_DISTANCE )
-DALI_PROPERTY( "far-plane-distance", FLOAT, true, false, true, Dali::CameraActor::Property::FAR_PLANE_DISTANCE )
-DALI_PROPERTY( "left-plane-distance", FLOAT, true, false, true, Dali::CameraActor::Property::LEFT_PLANE_DISTANCE )
-DALI_PROPERTY( "right-plane-distance", FLOAT, true, false, true, Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE )
-DALI_PROPERTY( "top-plane-distance", FLOAT, true, false, true, Dali::CameraActor::Property::TOP_PLANE_DISTANCE )
-DALI_PROPERTY( "bottom-plane-distance", FLOAT, true, false, true, Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE )
-DALI_PROPERTY( "target-position", VECTOR3, true, false, true, Dali::CameraActor::Property::TARGET_POSITION )
-DALI_PROPERTY( "projection-matrix", MATRIX, false, false, true, Dali::CameraActor::Property::PROJECTION_MATRIX )
-DALI_PROPERTY( "view-matrix", MATRIX, false, false, true, Dali::CameraActor::Property::VIEW_MATRIX )
-DALI_PROPERTY( "invert-y-axis", BOOLEAN, true, false, true, Dali::CameraActor::Property::INVERT_Y_AXIS )
-DALI_PROPERTY_TABLE_END( DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX )
+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
// calculate the far plane distance for a 16bit depth buffer with 4 bits per unit precision
-void CalculateClippingAndZ( float width, float height, float& nearClippingPlane, float& farClippingPlane, float& cameraZ )
+void CalculateClippingAndZ(float width, float height, float& nearClippingPlane, float& farClippingPlane, float& cameraZ)
{
- nearClippingPlane = std::max( width, height );
- farClippingPlane = nearClippingPlane + static_cast<float>( 0xFFFF >> 4 );
- cameraZ = 2.0f * nearClippingPlane;
+ nearClippingPlane = std::max(width, height);
+ farClippingPlane = nearClippingPlane + static_cast<float>(0xFFFF >> 4);
+ cameraZ = 2.0f * nearClippingPlane;
}
BaseHandle Create()
return Dali::CameraActor::New();
}
-TypeRegistration mType( typeid( Dali::CameraActor ), typeid( Dali::Actor ), Create );
+TypeRegistration mType(typeid(Dali::CameraActor), typeid(Dali::Actor), Create, CameraDefaultProperties);
/**
* Builds the picking ray in the world reference system from an orthographic camera
* plane at the camera origin. The ray direction is the direction the camera is facing
* (i.e. Z=-1 in view space).
*/
-void BuildOrthoPickingRay( const Matrix& viewMatrix,
- const Matrix& projectionMatrix,
- const Viewport& viewport,
- float screenX,
- float screenY,
- Vector4& rayOrigin,
- Vector4& rayDir,
- float nearPlaneDistance )
+void BuildOrthoPickingRay(const Matrix& viewMatrix,
+ const Matrix& projectionMatrix,
+ const Viewport& viewport,
+ float screenX,
+ float screenY,
+ Vector4& rayOrigin,
+ Vector4& rayDir,
+ float nearPlaneDistance)
{
// inv( modelMatrix ) inv( viewMatrix ) inv( projectionMatrix ) normalize
// <----------------- <----------------- <-------------- <-------------
// modelMatrix viewMatrix projectionMatrix viewport
// Transforms the touch point from the screen reference system to the world reference system.
- Matrix invViewProjection( false ); // Don't initialize.
- Matrix::Multiply( invViewProjection, viewMatrix, projectionMatrix );
- if( !invViewProjection.Invert() )
+ Matrix invViewProjection(false); // Don't initialize.
+ MatrixUtils::MultiplyProjectionMatrix(invViewProjection, viewMatrix, projectionMatrix);
+ if(!invViewProjection.Invert())
{
- DALI_ASSERT_DEBUG( false );
+ DALI_ASSERT_DEBUG(false);
}
- Vector4 near( screenX - viewport.x, viewport.height - (screenY - viewport.y), 0.f, 1.f );
- if( !Unproject( near, invViewProjection, viewport.width, viewport.height, rayOrigin ) )
+ Vector4 near(screenX - static_cast<float>(viewport.x),
+ static_cast<float>(viewport.height) - (screenY - static_cast<float>(viewport.y)),
+ 0.f,
+ 1.f);
+ if(!Unproject(near, invViewProjection, static_cast<float>(viewport.width), static_cast<float>(viewport.height), rayOrigin))
{
- DALI_ASSERT_DEBUG( false );
+ DALI_ASSERT_DEBUG(false);
}
Matrix invView = viewMatrix;
- if( !invView.Invert() )
+ if(!invView.Invert())
{
- DALI_ASSERT_DEBUG( false );
+ DALI_ASSERT_DEBUG(false);
}
- Vector4 cameraOrigin = invView * Vector4( 0.f, 0.f, 0.f, 1.f );
- Vector4 nearPlaneOrigin = invView * Vector4( 0.0f, 0.0f, -nearPlaneDistance, 1.0f);
+ Vector4 cameraOrigin = invView * Vector4(0.f, 0.f, 0.f, 1.f);
+ Vector4 nearPlaneOrigin = invView * Vector4(0.0f, 0.0f, -nearPlaneDistance, 1.0f);
// Vector pointing from the camera to the near plane
rayDir = cameraOrigin - nearPlaneOrigin;
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;
+};
+
+static const float DEFAULT_NEAR_CLIPPING_PLANE_FOR_3D = 0.1f;
+static const float DEFAULT_FAR_CLIPPING_PLANE_FOR_3D = 100.0f;
+
+static const Dali::Camera::ProjectionMode DEFAULT_MODE_FOR_3D = SceneGraph::Camera::DEFAULT_MODE;
+static const Dali::DevelCameraActor::ProjectionDirection DEFAULT_PROJECTION_DIRECTION_FOR_3D = SceneGraph::Camera::DEFAULT_PROJECTION_DIRECTION;
+
+static const float DEFAULT_FIELD_OF_VIEW_FOR_3D = SceneGraph::Camera::DEFAULT_FIELD_OF_VIEW;
+static const float DEFAULT_POSITIN_Z_FOR_3D = 5.0f;
+static const Quaternion DEFAULT_ORIENTATION_FOR_3D = Quaternion(Dali::ANGLE_180, Vector3::YAXIS);
+static const float DEFAULT_ORTHOGRAPHIC_SIZE_FOR_3D = 2.071068f; // DEFAULT_POSITIN_Z_FOR_3D * std::tan(DEFAULT_FIELD_OF_VIEW_FOR_3D * 0.5f); // Rectangle size of z=0.
+
+/**
+ * @brief Setup CameraActor's parameters for 3D apps.
+ * Conceptually, We can must see 1 world unit cube at world origin.
+ * Detail value can be changed by UX.
+ *
+ * @param[in,out] cameraActorObject CameraActor who need to apply default camera parameters.
+ */
+void SetupDefault3DCameraProperties(Internal::CameraActor& cameraActorObject)
+{
+ cameraActorObject.SetNearClippingPlane(DEFAULT_NEAR_CLIPPING_PLANE_FOR_3D);
+ cameraActorObject.SetFarClippingPlane(DEFAULT_FAR_CLIPPING_PLANE_FOR_3D);
+
+ cameraActorObject.SetProjectionMode(DEFAULT_MODE_FOR_3D);
+ cameraActorObject.SetProjectionDirection(DEFAULT_PROJECTION_DIRECTION_FOR_3D);
+ cameraActorObject.SetFieldOfView(DEFAULT_FIELD_OF_VIEW_FOR_3D);
+ cameraActorObject.SetZ(DEFAULT_POSITIN_Z_FOR_3D);
+ cameraActorObject.SetOrientation(DEFAULT_ORIENTATION_FOR_3D);
+
+ cameraActorObject.SetOrthographicSize(DEFAULT_ORTHOGRAPHIC_SIZE_FOR_3D);
+}
+
} // namespace
-CameraActorPtr CameraActor::New( const Size& size )
+CameraActorPtr CameraActor::New(const Size& size, bool hintFor3D)
{
- CameraActorPtr actor(new CameraActor());
+ // create camera. Cameras are owned by the update manager
+ SceneGraph::Camera* camera = SceneGraph::Camera::New();
+ OwnerPointer<SceneGraph::Node> transferOwnership(camera);
+ Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal();
- // Second-phase construction
+ DALI_ASSERT_ALWAYS(tls && "ThreadLocalStorage is null");
+
+ // Send ownership of camera.
+ AddNodeMessage(tls->GetUpdateManager(), transferOwnership);
+
+ CameraActorPtr actor(new CameraActor(*camera));
+ // Second-phase construction
actor->Initialize();
actor->SetName("DefaultCamera");
+ if(hintFor3D)
+ {
+ // Initialize camera property for 3D case.
+ SetupDefault3DCameraProperties(*actor);
+ }
+ else
+ {
+ actor->SetPerspectiveProjection(size);
- // Create the attachment
- actor->mCameraAttachment = CameraAttachment::New( actor->GetEventThreadServices(), *actor->mNode );
+ // By default Actors face in the positive Z direction in world space
+ // CameraActors should face in the negative Z direction, towards the other actors
+ actor->SetOrientation(Quaternion(Dali::ANGLE_180, Vector3::YAXIS));
+ }
- actor->Attach(*actor->mCameraAttachment);
+ return actor;
+}
- actor->SetPerspectiveProjection( size );
+CameraActor::CameraActor(const SceneGraph::Node& node)
+: Actor(Actor::BASIC, node),
+ mTarget(SceneGraph::Camera::DEFAULT_TARGET_POSITION),
+ mType(SceneGraph::Camera::DEFAULT_TYPE),
+ 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),
+ mInvertYAxis(SceneGraph::Camera::DEFAULT_INVERT_Y_AXIS),
+ mPropertyChanged(false)
+{
+}
- // By default Actors face in the positive Z direction in world space
- // CameraActors should face in the negative Z direction, towards the other actors
- actor->SetOrientation( Quaternion( Math::PI, Vector3::YAXIS ) );
+CameraActor::~CameraActor()
+{
+}
- return actor;
+void CameraActor::OnSceneConnectionInternal()
+{
+ // If the canvas size has not been set, then use the size of the scene to which we've been added
+ // in order to set up the current projection
+ if(!mPropertyChanged && ((mCanvasSize.width < Math::MACHINE_EPSILON_1000) || (mCanvasSize.height < Math::MACHINE_EPSILON_1000)))
+ {
+ if(mProjectionMode == Dali::Camera::ORTHOGRAPHIC_PROJECTION)
+ {
+ SetOrthographicProjection(GetScene().GetSize());
+ }
+ else //if(mProjectionMode == Dali::Camera::PERSPECTIVE_PROJECTION)
+ {
+ SetPerspectiveProjection(GetScene().GetSize());
+ }
+ }
}
-void CameraActor::OnInitialize()
+void CameraActor::SetReflectByPlane(const Vector4& plane)
{
+ SetReflectByPlaneMessage(GetEventThreadServices(), GetCameraSceneObject(), plane);
}
-CameraActor::CameraActor()
-: Actor( Actor::BASIC )
+void CameraActor::SetTarget(const Vector3& target)
{
+ mPropertyChanged = true;
+ if(target != mTarget) // using range epsilon
+ {
+ mTarget = target;
+
+ SetTargetPositionMessage(GetEventThreadServices(), GetCameraSceneObject(), mTarget);
+ }
}
-CameraActor::~CameraActor()
+Vector3 CameraActor::GetTarget() const
{
+ return mTarget;
}
-void CameraActor::SetType( Dali::Camera::Type type )
+void CameraActor::SetType(Dali::Camera::Type type)
{
- mCameraAttachment->SetType(type);
+ if(type != mType)
+ {
+ mType = type;
+
+ // sceneObject is being used in a separate thread; queue a message to set
+ SetTypeMessage(GetEventThreadServices(), GetCameraSceneObject(), mType);
+ }
}
Dali::Camera::Type CameraActor::GetType() const
{
- return mCameraAttachment->GetType();
+ return mType;
}
-void CameraActor::SetProjectionMode( Dali::Camera::ProjectionMode mode )
+void CameraActor::SetProjectionMode(Dali::Camera::ProjectionMode mode)
{
- mCameraAttachment->SetProjectionMode(mode);
+ if(mode != mProjectionMode)
+ {
+ mProjectionMode = mode;
+
+ // sceneObject is being used in a separate thread; queue a message to set
+ SetProjectionModeMessage(GetEventThreadServices(), GetCameraSceneObject(), mProjectionMode);
+ }
}
Dali::Camera::ProjectionMode CameraActor::GetProjectionMode() const
{
- return mCameraAttachment->GetProjectionMode();
+ return mProjectionMode;
+}
+
+void CameraActor::SetProjectionDirection(Dali::DevelCameraActor::ProjectionDirection direction)
+{
+ mPropertyChanged = true;
+ if(direction != mProjectionDirection)
+ {
+ mProjectionDirection = direction;
+
+ // sceneObject is being used in a separate thread; queue a message to set
+ SetProjectionDirectionMessage(GetEventThreadServices(), GetCameraSceneObject(), mProjectionDirection);
+ }
}
-void CameraActor::SetFieldOfView( float fieldOfView )
+void CameraActor::SetFieldOfView(float fieldOfView)
{
- mCameraAttachment->SetFieldOfView(fieldOfView);
+ mPropertyChanged = true;
+ if(!Equals(fieldOfView, mFieldOfView))
+ {
+ mFieldOfView = fieldOfView;
+
+ // sceneObject is being used in a separate thread; queue a message to set
+ BakeFieldOfViewMessage(GetEventThreadServices(), GetCameraSceneObject(), mFieldOfView);
+ }
+}
+
+float CameraActor::GetFieldOfView() const
+{
+ return mFieldOfView;
+}
+
+float CameraActor::GetCurrentFieldOfView() const
+{
+ // node is being used in a separate thread; copy the value from the previous update
+ 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::GetFieldOfView( ) const
+float CameraActor::GetOrthographicSize() const
{
- return mCameraAttachment->GetFieldOfView();
+ return mOrthographicSize;
}
-void CameraActor::SetAspectRatio( float aspectRatio )
+float CameraActor::GetCurrentOrthographicSize() const
{
- mCameraAttachment->SetAspectRatio(aspectRatio);
+ // node is being used in a separate thread; copy the value from the previous update
+ return GetCameraSceneObject().GetOrthographicSize(GetEventThreadServices().GetEventBufferIndex());
}
-float CameraActor::GetAspectRatio( ) const
+void CameraActor::SetAspectRatio(float aspectRatio)
{
- return mCameraAttachment->GetAspectRatio();
+ mPropertyChanged = true;
+ if(!Equals(aspectRatio, mAspectRatio))
+ {
+ mAspectRatio = aspectRatio;
+
+ // sceneObject is being used in a separate thread; queue a message to set
+ BakeAspectRatioMessage(GetEventThreadServices(), GetCameraSceneObject(), mAspectRatio);
+ }
}
-void CameraActor::SetNearClippingPlane( float nearClippingPlane )
+float CameraActor::GetAspectRatio() const
{
- mCameraAttachment->SetNearClippingPlane(nearClippingPlane);
+ return mAspectRatio;
}
-float CameraActor::GetNearClippingPlane( ) const
+float CameraActor::GetCurrentAspectRatio() const
{
- return mCameraAttachment->GetNearClippingPlane();
+ // node is being used in a separate thread; copy the value from the previous update
+ return GetCameraSceneObject().GetAspectRatio(GetEventThreadServices().GetEventBufferIndex());
}
-void CameraActor::SetFarClippingPlane( float farClippingPlane )
+void CameraActor::SetNearClippingPlane(float nearClippingPlane)
{
- mCameraAttachment->SetFarClippingPlane(farClippingPlane);
+ mPropertyChanged = true;
+ if(!Equals(nearClippingPlane, mNearClippingPlane))
+ {
+ mNearClippingPlane = nearClippingPlane;
+
+ // sceneObject is being used in a separate thread; queue a message to set
+ SetNearClippingPlaneMessage(GetEventThreadServices(), GetCameraSceneObject(), mNearClippingPlane);
+ }
}
-float CameraActor::GetFarClippingPlane( ) const
+float CameraActor::GetNearClippingPlane() const
{
- return mCameraAttachment->GetFarClippingPlane();
+ return mNearClippingPlane;
}
-void CameraActor::SetTargetPosition(const Vector3& target)
+void CameraActor::SetFarClippingPlane(float farClippingPlane)
{
- mCameraAttachment->SetTargetPosition(target);
+ mPropertyChanged = true;
+ if(!Equals(farClippingPlane, mFarClippingPlane))
+ {
+ mFarClippingPlane = farClippingPlane;
+
+ // sceneObject is being used in a separate thread; queue a message to set
+ SetFarClippingPlaneMessage(GetEventThreadServices(), GetCameraSceneObject(), mFarClippingPlane);
+ }
}
-Vector3 CameraActor::GetTargetPosition() const
+float CameraActor::GetFarClippingPlane() const
{
- return mCameraAttachment->GetTargetPosition();
+ return mFarClippingPlane;
}
void CameraActor::SetInvertYAxis(bool invertYAxis)
{
- mCameraAttachment->SetInvertYAxis(invertYAxis);
+ if(invertYAxis != mInvertYAxis)
+ {
+ mInvertYAxis = invertYAxis;
+
+ // sceneObject is being used in a separate thread; queue a message to set
+ SetInvertYAxisMessage(GetEventThreadServices(), GetCameraSceneObject(), mInvertYAxis);
+ }
}
bool CameraActor::GetInvertYAxis() const
{
- return mCameraAttachment->GetInvertYAxis();
+ return mInvertYAxis;
}
-void CameraActor::SetPerspectiveProjection( const Size& size, const Vector2& stereoBias /* = Vector2::ZERO */ )
+void CameraActor::SetPerspectiveProjection(const Size& size)
{
- float width = size.width;
- float height = size.height;
+ SetProjectionMode(Dali::Camera::PERSPECTIVE_PROJECTION);
+ mCanvasSize = static_cast<const Vector2>(size);
- if( Size::ZERO == size )
+ if((size.width < Math::MACHINE_EPSILON_1000) || (size.height < Math::MACHINE_EPSILON_1000))
{
- if( Stage::IsInstalled() )
+ // If the size given is invalid, i.e. ZERO, then check if we've been added to a scene
+ if(OnScene())
{
- const Size& stageSize = Stage::GetCurrent()->GetSize();
-
- width = stageSize.width;
- height = stageSize.height;
+ // 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;
}
}
+ ApplyDefaultProjection();
+}
- if( ( width < Math::MACHINE_EPSILON_1000 ) || ( height < Math::MACHINE_EPSILON_1000 ) )
+void CameraActor::SetOrthographicProjection(const Size& size)
+{
+ SetProjectionMode(Dali::Camera::ORTHOGRAPHIC_PROJECTION);
+ mCanvasSize = static_cast<const Vector2>(size);
+
+ if((size.width < Math::MACHINE_EPSILON_1000) || (size.height < Math::MACHINE_EPSILON_1000))
{
- // On the stage initialization this method is called but the size has not been set.
- // There is no point to set any value if width or height is zero.
- return;
+ // If the size given is invalid, i.e. ZERO, then check if we've been added to a scene
+ if(OnScene())
+ {
+ // 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;
+ }
}
+ 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( width, height, nearClippingPlane, farClippingPlane, cameraZ );
+ CalculateClippingAndZ(width, height, nearClippingPlane, farClippingPlane, cameraZ);
+
+ // 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( height * 0.5f / cameraZ );
+ 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 )
+ if(farClippingPlane < minClippingFarPlane)
{
farClippingPlane = minClippingFarPlane;
}
const float aspectRatio = width / height;
- SetProjectionMode(Dali::Camera::PERSPECTIVE_PROJECTION);
- SetFieldOfView( fieldOfView );
- SetNearClippingPlane( nearClippingPlane );
- SetFarClippingPlane( farClippingPlane );
- SetAspectRatio( aspectRatio );
- mCameraAttachment->SetStereoBias( stereoBias );
- SetZ( cameraZ );
-}
-
-
-void CameraActor::SetOrthographicProjection( const Vector2& size )
-{
- // 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 );
-}
-
-void CameraActor::SetOrthographicProjection( float left, float right, float top, float bottom, float near, float far )
-{
- mCameraAttachment->SetLeftClippingPlane(left);
- mCameraAttachment->SetRightClippingPlane(right);
- mCameraAttachment->SetTopClippingPlane(top);
- mCameraAttachment->SetBottomClippingPlane(bottom);
- SetNearClippingPlane( near );
- SetFarClippingPlane( far );
- SetProjectionMode(Dali::Camera::ORTHOGRAPHIC_PROJECTION);
+ // 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,
- const Viewport& viewport,
- Vector4& rayOrigin,
- Vector4& rayDirection )
+bool CameraActor::BuildPickingRay(const Vector2& screenCoordinates,
+ const Viewport& viewport,
+ Vector4& rayOrigin,
+ Vector4& rayDirection)
{
bool success = true;
- if( GetProjectionMode() == Dali::Camera::PERSPECTIVE_PROJECTION )
+ if(mProjectionMode == Dali::Camera::PERSPECTIVE_PROJECTION)
{
// Build a picking ray in the world reference system.
// ray starts from the camera world position
- rayOrigin = mNode->GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() );
+ rayOrigin = GetNode().GetWorldMatrix(0).GetTranslation();
rayOrigin.w = 1.0f;
// Transform the touch point from the screen coordinate system to the world coordinates system.
- Vector4 near( screenCoordinates.x - viewport.x, viewport.height - (screenCoordinates.y - viewport.y), 0.f, 1.f );
- if( !Unproject( near, mCameraAttachment->GetInverseViewProjectionMatrix(), viewport.width, viewport.height, near ) )
- {
- // unproject failed so no picking ray possible
- success = false;
- }
+ Vector4 near(screenCoordinates.x - static_cast<float>(viewport.x),
+ static_cast<float>(viewport.height) - (screenCoordinates.y - static_cast<float>(viewport.y)),
+ 0.f,
+ 1.f);
+ const Matrix& inverseViewProjection = GetCameraSceneObject().GetInverseViewProjectionMatrix(GetEventThreadServices().GetEventBufferIndex());
+ success = Unproject(near, inverseViewProjection, static_cast<float>(viewport.width), static_cast<float>(viewport.height), near);
// Compute the ray's director vector.
rayDirection.x = near.x - rayOrigin.x;
else
{
float nearPlaneDistance = GetNearClippingPlane();
- BuildOrthoPickingRay( GetViewMatrix(),
- GetProjectionMatrix(),
- viewport, screenCoordinates.x,
- screenCoordinates.y,
- rayOrigin,
- rayDirection,
- nearPlaneDistance );
+ BuildOrthoPickingRay(GetViewMatrix(),
+ GetProjectionMatrix(),
+ viewport,
+ screenCoordinates.x,
+ screenCoordinates.y,
+ rayOrigin,
+ rayDirection,
+ nearPlaneDistance);
}
return success;
const Matrix& CameraActor::GetViewMatrix() const
{
- if ( OnStage() )
+ if(OnScene())
{
- return mCameraAttachment->GetViewMatrix();
+ return GetCameraSceneObject().GetViewMatrix(GetEventThreadServices().GetEventBufferIndex());
}
else
{
const Matrix& CameraActor::GetProjectionMatrix() const
{
- if ( OnStage() )
+ if(OnScene())
{
- return mCameraAttachment->GetProjectionMatrix();
+ return GetCameraSceneObject().GetProjectionMatrix(GetEventThreadServices().GetEventBufferIndex());
}
else
{
return Matrix::IDENTITY;
}
}
-
-unsigned int CameraActor::GetDefaultPropertyCount() const
-{
- return Actor::GetDefaultPropertyCount() + DEFAULT_PROPERTY_COUNT;
-}
-
-void CameraActor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
-{
- Actor::GetDefaultPropertyIndices( indices ); // Actor class properties
-
- indices.reserve( indices.size() + DEFAULT_PROPERTY_COUNT );
-
- int index = DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
- for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i, ++index )
- {
- indices.push_back( index );
- }
-}
-
-bool CameraActor::IsDefaultPropertyWritable( Property::Index index ) const
-{
- if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
- {
- return Actor::IsDefaultPropertyWritable( index );
- }
-
- return DEFAULT_PROPERTY_DETAILS[index - DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX].writable;
-}
-
-bool CameraActor::IsDefaultPropertyAnimatable( Property::Index index ) const
-{
- if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
- {
- return Actor::IsDefaultPropertyAnimatable( index );
- }
-
- return DEFAULT_PROPERTY_DETAILS[index - DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX].animatable;
-}
-
-bool CameraActor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
-{
- if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
- {
- return Actor::IsDefaultPropertyAConstraintInput( index );
- }
-
- return DEFAULT_PROPERTY_DETAILS[index - DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX].constraintInput;
-}
-
-Property::Type CameraActor::GetDefaultPropertyType( Property::Index index ) const
+const SceneGraph::Camera& CameraActor::GetCameraSceneObject() const
{
- if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
- {
- return Actor::GetDefaultPropertyType( index );
- }
- else
- {
- index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
-
- if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
- {
- return DEFAULT_PROPERTY_DETAILS[index].type;
- }
- else
- {
- // index out-of-bounds
- return Property::NONE;
- }
- }
-}
-
-const char* CameraActor::GetDefaultPropertyName( Property::Index index ) const
-{
- if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
- {
- return Actor::GetDefaultPropertyName(index);
- }
- else
- {
- index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
-
- if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
- {
- return DEFAULT_PROPERTY_DETAILS[index].name;
- }
- return NULL;
- }
+ return static_cast<const SceneGraph::Camera&>(GetNode());
}
-Property::Index CameraActor::GetDefaultPropertyIndex(const std::string& name) const
+void CameraActor::RotateProjection(int rotationAngle)
{
- Property::Index index = Property::INVALID_INDEX;
-
- // Look for name in current class' default properties
- for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
- {
- if( 0 == strcmp( name.c_str(), DEFAULT_PROPERTY_DETAILS[i].name ) ) // dont want to convert rhs to string
- {
- index = i + DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
- break;
- }
- }
-
- // If not found, check in base class
- if( Property::INVALID_INDEX == index )
- {
- index = Actor::GetDefaultPropertyIndex( name );
- }
-
- return index;
+ // sceneObject is being used in a separate thread; queue a message to set
+ RotateProjectionMessage(GetEventThreadServices(), GetCameraSceneObject(), rotationAngle);
}
-void CameraActor::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
+void CameraActor::SetDefaultProperty(Property::Index index, const Property::Value& propertyValue)
{
if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
{
}
else
{
- DALI_ASSERT_DEBUG(mCameraAttachment && "where is the camera?");
switch(index)
{
case Dali::CameraActor::Property::TYPE:
{
- std::string s( propertyValue.Get<std::string>() );
- if(s == "LOOK_AT_TARGET")
- {
- mCameraAttachment->SetType(Dali::Camera::LOOK_AT_TARGET);
- }
- else if(s == "FREE_LOOK")
- {
- mCameraAttachment->SetType(Dali::Camera::FREE_LOOK);
- }
- else
- {
- DALI_LOG_WARNING("Unknown camera type\n");
- }
+ Dali::Camera::Type cameraType = Dali::Camera::Type(propertyValue.Get<int>());
+ SetType(cameraType);
break;
}
case Dali::CameraActor::Property::PROJECTION_MODE:
{
- std::string s(propertyValue.Get<std::string>());
- if(s == "PERSPECTIVE_PROJECTION")
- {
- mCameraAttachment->SetProjectionMode(Dali::Camera::PERSPECTIVE_PROJECTION);
- }
- else if(s == "ORTHOGRAPHIC_PROJECTION")
- {
- mCameraAttachment->SetProjectionMode(Dali::Camera::ORTHOGRAPHIC_PROJECTION);
- }
- else
- {
- DALI_LOG_WARNING("Unknown projection mode\n");
- }
+ Dali::Camera::ProjectionMode projectionMode = Dali::Camera::ProjectionMode(propertyValue.Get<int>());
+ SetProjectionMode(projectionMode);
break;
}
case Dali::CameraActor::Property::FIELD_OF_VIEW:
{
- mCameraAttachment->SetFieldOfView(propertyValue.Get<float>());
+ 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:
{
- mCameraAttachment->SetAspectRatio(propertyValue.Get<float>());
+ SetAspectRatio(propertyValue.Get<float>()); // set to 0 in case property is not float
break;
}
- case Dali::CameraActor::Property::LEFT_PLANE_DISTANCE:
+ case Dali::CameraActor::Property::NEAR_PLANE_DISTANCE:
{
- mCameraAttachment->SetLeftClippingPlane(propertyValue.Get<float>());
+ SetNearClippingPlane(propertyValue.Get<float>()); // set to 0 in case property is not float
break;
}
- case Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE:
+ case Dali::CameraActor::Property::FAR_PLANE_DISTANCE:
{
- mCameraAttachment->SetRightClippingPlane(propertyValue.Get<float>());
+ SetFarClippingPlane(propertyValue.Get<float>()); // set to 0 in case property is not float
break;
}
- case Dali::CameraActor::Property::TOP_PLANE_DISTANCE:
+ case Dali::CameraActor::Property::LEFT_PLANE_DISTANCE:
{
- mCameraAttachment->SetTopClippingPlane(propertyValue.Get<float>());
+ DALI_LOG_WARNING("LEFT_PLANE_DISTANCE is read-only\n");
break;
}
- case Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE:
+ case Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE:
{
- mCameraAttachment->SetBottomClippingPlane(propertyValue.Get<float>());
+ DALI_LOG_WARNING("RIGHT_PLANE_DISTANCE is read-only\n");
break;
}
- case Dali::CameraActor::Property::NEAR_PLANE_DISTANCE:
+ case Dali::CameraActor::Property::TOP_PLANE_DISTANCE:
{
- mCameraAttachment->SetNearClippingPlane(propertyValue.Get<float>());
+ DALI_LOG_WARNING("TOP_PLANE_DISTANCE is read-only\n");
break;
}
- case Dali::CameraActor::Property::FAR_PLANE_DISTANCE:
+ case Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE:
{
- mCameraAttachment->SetFarClippingPlane(propertyValue.Get<float>());
+ DALI_LOG_WARNING("BOTTOM_PLANE_DISTANCE is read-only\n");
break;
}
case Dali::CameraActor::Property::TARGET_POSITION:
{
- mCameraAttachment->SetTargetPosition(propertyValue.Get<Vector3>());
+ SetTarget(propertyValue.Get<Vector3>()); // set to 0 in case property is not Vector3
break;
}
case Dali::CameraActor::Property::PROJECTION_MATRIX:
{
- DALI_LOG_WARNING("projection-matrix property is not animatable \n");
+ DALI_LOG_WARNING("projection-matrix is read-only\n");
break;
}
case Dali::CameraActor::Property::VIEW_MATRIX:
{
- DALI_LOG_WARNING("view-matrix property is not animatable \n");
+ DALI_LOG_WARNING("view-matrix is read-only\n");
break;
}
case Dali::CameraActor::Property::INVERT_Y_AXIS:
{
- mCameraAttachment->SetInvertYAxis(propertyValue.Get<bool>());
+ SetInvertYAxis(propertyValue.Get<bool>()); // set to false in case property is not bool
+ break;
+ }
+ case Dali::DevelCameraActor::Property::REFLECTION_PLANE:
+ {
+ SetReflectByPlane(propertyValue.Get<Vector4>());
+ break;
+ }
+ case Dali::DevelCameraActor::Property::PROJECTION_DIRECTION:
+ {
+ Dali::DevelCameraActor::ProjectionDirection projectionDirection = Dali::DevelCameraActor::ProjectionDirection(propertyValue.Get<int>());
+ SetProjectionDirection(projectionDirection);
break;
}
+
default:
{
DALI_LOG_WARNING("Unknown property (%d)\n", index);
} // else
}
-Property::Value CameraActor::GetDefaultProperty( Property::Index index ) const
+Property::Value CameraActor::GetDefaultProperty(Property::Index index) const
{
Property::Value ret;
if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
}
else
{
- DALI_ASSERT_DEBUG(mCameraAttachment && "where is the camera?");
switch(index)
{
case Dali::CameraActor::Property::TYPE:
{
- if(mCameraAttachment->GetType() == Dali::Camera::LOOK_AT_TARGET)
- {
- ret = "LOOK_AT_TARGET";
- }
- else if(mCameraAttachment->GetType() == Dali::Camera::FREE_LOOK)
- {
- ret = "FREE_LOOK";
- }
- else
- {
- ret = "";
- DALI_ASSERT_DEBUG("Unknown camera type\n");
- }
+ ret = mType;
break;
}
case Dali::CameraActor::Property::PROJECTION_MODE:
{
- if(mCameraAttachment->GetProjectionMode() == Dali::Camera::PERSPECTIVE_PROJECTION)
- {
- ret = "PERSPECTIVE_PROJECTION";
- }
- else if(mCameraAttachment->GetProjectionMode() == Dali::Camera::ORTHOGRAPHIC_PROJECTION)
- {
- ret = "ORTHOGRAPHIC_PROJECTION";
- }
- else
- {
- ret = "";
- DALI_ASSERT_DEBUG("Unknown projection mode\n");
- }
+ ret = mProjectionMode;
break;
}
case Dali::CameraActor::Property::FIELD_OF_VIEW:
{
- ret = mCameraAttachment->GetFieldOfView();
+ ret = mFieldOfView;
+ break;
+ }
+ case Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE:
+ {
+ ret = mOrthographicSize;
break;
}
case Dali::CameraActor::Property::ASPECT_RATIO:
{
- ret = mCameraAttachment->GetAspectRatio();
+ ret = mAspectRatio;
break;
}
- case Dali::CameraActor::Property::LEFT_PLANE_DISTANCE:
+ case Dali::CameraActor::Property::NEAR_PLANE_DISTANCE:
{
- ret = mCameraAttachment->GetLeftClippingPlane();
+ ret = mNearClippingPlane;
break;
}
- case Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE:
+ case Dali::CameraActor::Property::FAR_PLANE_DISTANCE:
{
- ret = mCameraAttachment->GetRightClippingPlane();
+ ret = mFarClippingPlane;
break;
}
- case Dali::CameraActor::Property::TOP_PLANE_DISTANCE:
+ case Dali::CameraActor::Property::LEFT_PLANE_DISTANCE:
{
- ret = mCameraAttachment->GetTopClippingPlane();
+ ret = OrthographicSizeConverter(mOrthographicSize, mAspectRatio, mProjectionDirection).LeftPlaneDistance();
break;
}
- case Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE:
+ case Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE:
{
- ret = mCameraAttachment->GetBottomClippingPlane();
+ ret = OrthographicSizeConverter(mOrthographicSize, mAspectRatio, mProjectionDirection).RightPlaneDistance();
break;
}
- case Dali::CameraActor::Property::NEAR_PLANE_DISTANCE:
+ case Dali::CameraActor::Property::TOP_PLANE_DISTANCE:
{
- ret = mCameraAttachment->GetNearClippingPlane();
+ ret = OrthographicSizeConverter(mOrthographicSize, mAspectRatio, mProjectionDirection).TopPlaneDistance();
break;
}
- case Dali::CameraActor::Property::FAR_PLANE_DISTANCE:
+ case Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE:
{
- ret = mCameraAttachment->GetFarClippingPlane();
+ ret = OrthographicSizeConverter(mOrthographicSize, mAspectRatio, mProjectionDirection).BottomPlaneDistance();
break;
}
case Dali::CameraActor::Property::TARGET_POSITION:
{
- ret = mCameraAttachment->GetTargetPosition();
+ ret = mTarget;
break;
}
case Dali::CameraActor::Property::PROJECTION_MATRIX:
{
- ret = mCameraAttachment->GetProjectionMatrix();
+ ret = GetProjectionMatrix(); // Only on scene-graph
break;
}
case Dali::CameraActor::Property::VIEW_MATRIX:
{
- ret = mCameraAttachment->GetViewMatrix();
+ ret = GetViewMatrix(); // Only on scene-graph
break;
}
case Dali::CameraActor::Property::INVERT_Y_AXIS:
{
- ret = mCameraAttachment->GetInvertYAxis();
+ ret = mInvertYAxis;
break;
}
- default:
+ case Dali::DevelCameraActor::Property::PROJECTION_DIRECTION:
{
- DALI_LOG_WARNING("Unknown property (%d)\n", index);
+ ret = mProjectionDirection;
break;
}
} // switch(index)
return ret;
}
-const SceneGraph::PropertyBase* CameraActor::GetSceneObjectAnimatableProperty( Property::Index index ) const
+Property::Value CameraActor::GetDefaultPropertyCurrentValue(Property::Index index) const
{
- DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
-
- const SceneGraph::PropertyBase* property( NULL );
-
- // This method should only return a property of an object connected to the scene-graph
- if ( !OnStage() )
+ Property::Value ret;
+ if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
{
- return property;
+ ret = Actor::GetDefaultPropertyCurrentValue(index);
}
-
- // let actor handle animatable properties, we have no animatable properties
- if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
+ else
{
- property = Actor::GetSceneObjectAnimatableProperty(index);
+ switch(index)
+ {
+ case Dali::CameraActor::Property::FIELD_OF_VIEW:
+ {
+ 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
+ }
+ } // switch(index)
}
- return property;
+ return ret;
}
-const PropertyInputImpl* CameraActor::GetSceneObjectInputProperty( Property::Index index ) const
+void CameraActor::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType)
{
- const PropertyInputImpl* property( NULL );
-
- // This method should only return a property of an object connected to the scene-graph
- if ( !OnStage() )
- {
- return property;
- }
-
- // if its an actor default property or a custom property (actor already handles custom properties)
- if( ( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT ) || ( index >= DEFAULT_PROPERTY_MAX_COUNT ) )
+ if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
{
- property = Actor::GetSceneObjectInputProperty(index);
+ Actor::OnNotifyDefaultPropertyAnimation(animation, index, value, animationType);
}
else
{
- switch( index )
+ switch(animationType)
{
- case Dali::CameraActor::Property::PROJECTION_MATRIX:
+ case Animation::TO:
+ case Animation::BETWEEN:
{
- property = mCameraAttachment->GetProjectionMatrixProperty();
+ switch(index)
+ {
+ case Dali::CameraActor::Property::FIELD_OF_VIEW:
+ {
+ 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;
}
- case Dali::CameraActor::Property::VIEW_MATRIX:
+ case Animation::BY:
{
- property = mCameraAttachment->GetViewMatrixProperty();
+ switch(index)
+ {
+ case Dali::CameraActor::Property::FIELD_OF_VIEW:
+ {
+ 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;
}
- default:
- DALI_LOG_WARNING("Not an input property (%d)\n", index);
- break;
}
}
+}
+
+const SceneGraph::PropertyBase* CameraActor::GetSceneObjectAnimatableProperty(Property::Index index) const
+{
+ const SceneGraph::PropertyBase* property(nullptr);
+ switch(index)
+ {
+ case Dali::CameraActor::Property::FIELD_OF_VIEW:
+ {
+ 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)
+ {
+ // not our property, ask base
+ property = Actor::GetSceneObjectAnimatableProperty(index);
+ }
+
+ return property;
+}
+
+const PropertyInputImpl* CameraActor::GetSceneObjectInputProperty(Property::Index index) const
+{
+ const PropertyInputImpl* property(nullptr);
+
+ switch(index)
+ {
+ case Dali::CameraActor::Property::FIELD_OF_VIEW:
+ {
+ 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();
+ break;
+ }
+ case Dali::CameraActor::Property::VIEW_MATRIX:
+ {
+ property = GetCameraSceneObject().GetViewMatrix();
+ break;
+ }
+ // no default on purpose as we chain method up to actor
+ }
+ if(!property)
+ {
+ property = Actor::GetSceneObjectInputProperty(index);
+ }
return property;
}
+void CameraActor::OnPropertySet(Property::Index index, const Property::Value& propertyValue)
+{
+ // If Position or Orientation are explicitly set, make mPropertyChanged flag true.
+ if(index == Dali::Actor::Property::POSITION ||
+ index == Dali::Actor::Property::POSITION_X ||
+ index == Dali::Actor::Property::POSITION_Y ||
+ index == Dali::Actor::Property::POSITION_Z ||
+ index == Dali::Actor::Property::ORIENTATION)
+ {
+ mPropertyChanged = true;
+ }
+}
} // namespace Internal