[Tizen] Add screen and client rotation itself function
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / camera-actor-impl.cpp
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/event/actors/camera-actor-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <cmath>
23 #include <cstring> // for strcmp
24
25 // INTERNAL INCLUDES
26 #include <dali/public-api/object/type-registry.h>
27 #include <dali/devel-api/actors/camera-actor-devel.h>
28 #include <dali/internal/event/common/property-helper.h>
29 #include <dali/internal/event/common/projection.h>
30 #include <dali/internal/event/common/thread-local-storage.h>
31
32 namespace Dali
33 {
34
35 namespace Internal
36 {
37
38 namespace
39 {
40
41 // Properties
42
43 /**
44  * We want to discourage the use of property strings (minimize string comparisons),
45  * particularly for the default properties.
46  *              Name                     Type   writable animatable constraint-input  enum for index-checking
47  */
48 DALI_PROPERTY_TABLE_BEGIN
49 DALI_PROPERTY( "type",                   STRING,   true,    false,   true,   Dali::CameraActor::Property::TYPE                  )
50 DALI_PROPERTY( "projectionMode",         STRING,   true,    false,   true,   Dali::CameraActor::Property::PROJECTION_MODE       )
51 DALI_PROPERTY( "fieldOfView",            FLOAT,    true,    false,   true,   Dali::CameraActor::Property::FIELD_OF_VIEW         )
52 DALI_PROPERTY( "aspectRatio",            FLOAT,    true,    false,   true,   Dali::CameraActor::Property::ASPECT_RATIO          )
53 DALI_PROPERTY( "nearPlaneDistance",      FLOAT,    true,    false,   true,   Dali::CameraActor::Property::NEAR_PLANE_DISTANCE   )
54 DALI_PROPERTY( "farPlaneDistance",       FLOAT,    true,    false,   true,   Dali::CameraActor::Property::FAR_PLANE_DISTANCE    )
55 DALI_PROPERTY( "leftPlaneDistance",      FLOAT,    true,    false,   true,   Dali::CameraActor::Property::LEFT_PLANE_DISTANCE   )
56 DALI_PROPERTY( "rightPlaneDistance",     FLOAT,    true,    false,   true,   Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE  )
57 DALI_PROPERTY( "topPlaneDistance",       FLOAT,    true,    false,   true,   Dali::CameraActor::Property::TOP_PLANE_DISTANCE    )
58 DALI_PROPERTY( "bottomPlaneDistance",    FLOAT,    true,    false,   true,   Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE )
59 DALI_PROPERTY( "targetPosition",         VECTOR3,  true,    false,   true,   Dali::CameraActor::Property::TARGET_POSITION       )
60 DALI_PROPERTY( "projectionMatrix",       MATRIX,   false,   false,   true,   Dali::CameraActor::Property::PROJECTION_MATRIX     )
61 DALI_PROPERTY( "viewMatrix",             MATRIX,   false,   false,   true,   Dali::CameraActor::Property::VIEW_MATRIX           )
62 DALI_PROPERTY( "invertYAxis",            BOOLEAN,  true,    false,   true,   Dali::CameraActor::Property::INVERT_Y_AXIS         )
63 DALI_PROPERTY_TABLE_END( DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX, CameraDefaultProperties )
64
65 // calculate the far plane distance for a 16bit depth buffer with 4 bits per unit precision
66 void CalculateClippingAndZ( float width, float height, float& nearClippingPlane, float& farClippingPlane, float& cameraZ )
67 {
68   nearClippingPlane = std::max( width, height );
69   farClippingPlane = nearClippingPlane + static_cast<float>( 0xFFFF >> 4 );
70   cameraZ = 2.0f * nearClippingPlane;
71 }
72
73 BaseHandle Create()
74 {
75   return Dali::CameraActor::New();
76 }
77
78 TypeRegistration mType( typeid( Dali::CameraActor ), typeid( Dali::Actor ), Create, CameraDefaultProperties );
79
80 /**
81  * Builds the picking ray in the world reference system from an orthographic camera
82  * The ray origin is the screen coordinate in the near plane translated to a parallel
83  * plane at the camera origin. The ray direction is the direction the camera is facing
84  * (i.e. Z=-1 in view space).
85  */
86 void BuildOrthoPickingRay( const Matrix& viewMatrix,
87                            const Matrix& projectionMatrix,
88                            const Viewport& viewport,
89                            float screenX,
90                            float screenY,
91                            Vector4& rayOrigin,
92                            Vector4& rayDir,
93                            float nearPlaneDistance )
94 {
95   //          inv( modelMatrix )          inv( viewMatrix )    inv( projectionMatrix )           normalize
96   //          <-----------------         <-----------------         <--------------           <-------------
97   //  Local                      World                      Camera                 Normalized                 Screen
98   // reference                  reference                  reference                  clip                  coordinates
99   //  system                     system                     system                 coordinates
100   //          ----------------->         ----------------->         -------------->           ------------->
101   //             modelMatrix                 viewMatrix             projectionMatrix             viewport
102
103   // Transforms the touch point from the screen reference system to the world reference system.
104   Matrix invViewProjection( false ); // Don't initialize.
105   Matrix::Multiply( invViewProjection, viewMatrix, projectionMatrix );
106   if( !invViewProjection.Invert() )
107   {
108     DALI_ASSERT_DEBUG( false );
109   }
110
111   Vector4 near( screenX - static_cast<float>( viewport.x ),
112                 static_cast<float>( viewport.height ) - (screenY - static_cast<float>( viewport.y ) ),
113                 0.f, 1.f );
114   if( !Unproject( near, invViewProjection, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), rayOrigin ) )
115   {
116     DALI_ASSERT_DEBUG( false );
117   }
118
119   Matrix invView = viewMatrix;
120   if( !invView.Invert() )
121   {
122     DALI_ASSERT_DEBUG( false );
123   }
124
125   Vector4 cameraOrigin = invView * Vector4( 0.f, 0.f, 0.f, 1.f );
126   Vector4 nearPlaneOrigin = invView * Vector4( 0.0f, 0.0f, -nearPlaneDistance, 1.0f);
127
128   // Vector pointing from the camera to the near plane
129   rayDir = cameraOrigin - nearPlaneOrigin;
130   rayOrigin -= rayDir;
131   rayDir.Normalize();
132   rayDir.w = 1.0f;
133 }
134
135 } // namespace
136
137 CameraActorPtr CameraActor::New( const Size& size )
138 {
139   CameraActorPtr actor( new CameraActor( *CreateNode() ) );
140
141   // Second-phase construction
142   actor->Initialize();
143
144   actor->SetName( "DefaultCamera" );
145   actor->SetPerspectiveProjection( size );
146
147   // By default Actors face in the positive Z direction in world space
148   // CameraActors should face in the negative Z direction, towards the other actors
149   actor->SetOrientation( Quaternion( Dali::ANGLE_180, Vector3::YAXIS ) );
150
151   return actor;
152 }
153
154 CameraActor::CameraActor( const SceneGraph::Node& node )
155 : Actor( Actor::BASIC, node ),
156   mSceneObject( nullptr ),
157   mTarget( SceneGraph::Camera::DEFAULT_TARGET_POSITION ),
158   mType( SceneGraph::Camera::DEFAULT_TYPE ),
159   mProjectionMode( SceneGraph::Camera::DEFAULT_MODE ),
160   mFieldOfView( SceneGraph::Camera::DEFAULT_FIELD_OF_VIEW ),
161   mAspectRatio( SceneGraph::Camera::DEFAULT_ASPECT_RATIO ),
162   mNearClippingPlane( SceneGraph::Camera::DEFAULT_NEAR_CLIPPING_PLANE ),
163   mFarClippingPlane( SceneGraph::Camera::DEFAULT_FAR_CLIPPING_PLANE ),
164   mLeftClippingPlane( SceneGraph::Camera::DEFAULT_LEFT_CLIPPING_PLANE ),
165   mRightClippingPlane( SceneGraph::Camera::DEFAULT_RIGHT_CLIPPING_PLANE ),
166   mTopClippingPlane( SceneGraph::Camera::DEFAULT_TOP_CLIPPING_PLANE ),
167   mBottomClippingPlane( SceneGraph::Camera::DEFAULT_BOTTOM_CLIPPING_PLANE ),
168   mInvertYAxis( SceneGraph::Camera::DEFAULT_INVERT_Y_AXIS )
169 {
170 }
171
172 CameraActor::~CameraActor()
173 {
174   if( EventThreadServices::IsCoreRunning() )
175   {
176     // Create scene-object and transfer ownership through message
177     RemoveCameraMessage( GetEventThreadServices().GetUpdateManager(), mSceneObject );
178   }
179 }
180
181 void CameraActor::OnInitialize()
182 {
183   // Create scene-object and keep raw pointer for message passing.
184   SceneGraph::Camera* sceneGraphCamera = SceneGraph::Camera::New();
185
186   // Store a pointer to this camera node inside the scene-graph camera.
187   sceneGraphCamera->SetNode( &GetNode() );
188
189   mSceneObject = sceneGraphCamera;
190   OwnerPointer< SceneGraph::Camera > sceneGraphCameraOwner( sceneGraphCamera );
191
192   // Send message to inform update of this camera (and move ownership).
193   AddCameraMessage( GetEventThreadServices().GetUpdateManager(), sceneGraphCameraOwner );
194 }
195
196 void CameraActor::OnSceneConnectionInternal()
197 {
198   // 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
199   if( ( mCanvasSize.width < Math::MACHINE_EPSILON_1000 ) || ( mCanvasSize.height < Math::MACHINE_EPSILON_1000 ) )
200   {
201     SetPerspectiveProjection( GetScene().GetSize() );
202   }
203 }
204
205 void CameraActor::SetReflectByPlane(const Vector4& plane) {
206   SceneGraph::Camera* cam = const_cast<SceneGraph::Camera*>(GetCamera());
207   if (cam)
208   {
209     cam->SetReflectByPlane(plane);
210   }
211 }
212
213 void CameraActor::SetTarget( const Vector3& target )
214 {
215   if( target != mTarget ) // using range epsilon
216   {
217     mTarget = target;
218
219     SetTargetPositionMessage( GetEventThreadServices(),  *mSceneObject, mTarget );
220   }
221 }
222
223 Vector3 CameraActor::GetTarget() const
224 {
225   return mTarget;
226 }
227
228 void CameraActor::SetType( Dali::Camera::Type type )
229 {
230   if( type != mType )
231   {
232     mType = type;
233
234     // sceneObject is being used in a separate thread; queue a message to set
235     SetTypeMessage( GetEventThreadServices(), *mSceneObject, mType );
236   }
237 }
238
239 Dali::Camera::Type CameraActor::GetType() const
240 {
241   return mType;
242 }
243
244 void CameraActor::SetProjectionMode( Dali::Camera::ProjectionMode mode )
245 {
246   if( mode != mProjectionMode )
247   {
248     mProjectionMode = mode;
249
250     // sceneObject is being used in a separate thread; queue a message to set
251     SetProjectionModeMessage( GetEventThreadServices(), *mSceneObject, mProjectionMode );
252   }
253 }
254
255 Dali::Camera::ProjectionMode CameraActor::GetProjectionMode() const
256 {
257   return mProjectionMode;
258 }
259
260 void CameraActor::SetFieldOfView( float fieldOfView )
261 {
262   if( ! Equals( fieldOfView, mFieldOfView ) )
263   {
264     mFieldOfView = fieldOfView;
265
266     // sceneObject is being used in a separate thread; queue a message to set
267     SetFieldOfViewMessage( GetEventThreadServices(), *mSceneObject, mFieldOfView );
268   }
269 }
270
271 float CameraActor::GetFieldOfView() const
272 {
273   return mFieldOfView;
274 }
275
276 void CameraActor::SetAspectRatio( float aspectRatio )
277 {
278   if( ! Equals( aspectRatio, mAspectRatio ) )
279   {
280     mAspectRatio = aspectRatio;
281
282     // sceneObject is being used in a separate thread; queue a message to set
283     SetAspectRatioMessage( GetEventThreadServices(), *mSceneObject, mAspectRatio );
284   }
285 }
286
287 float CameraActor::GetAspectRatio() const
288 {
289   return mAspectRatio;
290 }
291
292 void CameraActor::SetNearClippingPlane( float nearClippingPlane )
293 {
294   if( ! Equals( nearClippingPlane, mNearClippingPlane ) )
295   {
296     mNearClippingPlane = nearClippingPlane;
297
298     // sceneObject is being used in a separate thread; queue a message to set
299     SetNearClippingPlaneMessage( GetEventThreadServices(), *mSceneObject, mNearClippingPlane );
300   }
301 }
302
303 float CameraActor::GetNearClippingPlane() const
304 {
305   return mNearClippingPlane;
306 }
307
308 void CameraActor::SetFarClippingPlane( float farClippingPlane )
309 {
310   if( ! Equals( farClippingPlane, mFarClippingPlane ) )
311   {
312     mFarClippingPlane = farClippingPlane;
313
314     // sceneObject is being used in a separate thread; queue a message to set
315     SetFarClippingPlaneMessage( GetEventThreadServices(), *mSceneObject, mFarClippingPlane );
316   }
317 }
318
319 float CameraActor::GetFarClippingPlane() const
320 {
321   return mFarClippingPlane;
322 }
323
324 void CameraActor::SetLeftClippingPlane( float leftClippingPlane )
325 {
326   if( ! Equals( leftClippingPlane, mLeftClippingPlane ) )
327   {
328     mLeftClippingPlane = leftClippingPlane;
329
330     // sceneObject is being used in a separate thread; queue a message to set
331     SetLeftClippingPlaneMessage( GetEventThreadServices(), *mSceneObject, mLeftClippingPlane );
332   }
333 }
334
335 void CameraActor::SetRightClippingPlane( float rightClippingPlane )
336 {
337   if( ! Equals( rightClippingPlane, mRightClippingPlane ) )
338   {
339     mRightClippingPlane = rightClippingPlane;
340
341     // sceneObject is being used in a separate thread; queue a message to set
342     SetRightClippingPlaneMessage( GetEventThreadServices(), *mSceneObject, mRightClippingPlane );
343   }
344 }
345
346 void CameraActor::SetTopClippingPlane( float topClippingPlane )
347 {
348   if( ! Equals( topClippingPlane, mTopClippingPlane ) )
349   {
350     mTopClippingPlane = topClippingPlane;
351
352     // sceneObject is being used in a separate thread; queue a message to set
353     SetTopClippingPlaneMessage( GetEventThreadServices(), *mSceneObject, mTopClippingPlane );
354   }
355 }
356
357 void CameraActor::SetBottomClippingPlane( float bottomClippingPlane )
358 {
359   if( ! Equals( bottomClippingPlane, mBottomClippingPlane ) )
360   {
361     mBottomClippingPlane = bottomClippingPlane;
362
363     // sceneObject is being used in a separate thread; queue a message to set
364     SetBottomClippingPlaneMessage( GetEventThreadServices(), *mSceneObject, mBottomClippingPlane );
365   }
366 }
367
368 void CameraActor::SetInvertYAxis(bool invertYAxis)
369 {
370   if( invertYAxis != mInvertYAxis )
371   {
372     mInvertYAxis = invertYAxis;
373
374     // sceneObject is being used in a separate thread; queue a message to set
375     SetInvertYAxisMessage( GetEventThreadServices(), *mSceneObject, mInvertYAxis );
376   }
377 }
378
379 bool CameraActor::GetInvertYAxis() const
380 {
381   return mInvertYAxis;
382 }
383
384 void CameraActor::SetPerspectiveProjection( const Size& size )
385 {
386   mCanvasSize = size;
387
388   if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
389   {
390     // If the size given is invalid, i.e. ZERO, then check if we've been added to a scene
391     if( OnScene() )
392     {
393       // We've been added to a scene already, set the canvas size to the scene's size
394       mCanvasSize = GetScene().GetSize();
395     }
396     else
397     {
398       // We've not been added to a scene yet, so just return.
399       // We'll set the canvas size when we get added to a scene later
400       return;
401     }
402   }
403
404   float width = mCanvasSize.width;
405   float height = mCanvasSize.height;
406
407   float nearClippingPlane;
408   float farClippingPlane;
409   float cameraZ;
410   CalculateClippingAndZ( width, height, nearClippingPlane, farClippingPlane, cameraZ );
411
412   // calculate the position of the camera to have the desired aspect ratio
413   const float fieldOfView = 2.0f * std::atan( height * 0.5f / cameraZ );
414
415   // unless it is too small, we want at least as much space to the back as we have torwards the front
416   const float minClippingFarPlane = 2.f * nearClippingPlane;
417   if ( farClippingPlane < minClippingFarPlane )
418   {
419     farClippingPlane = minClippingFarPlane;
420   }
421
422   const float aspectRatio = width / height;
423
424   // sceneObject is being used in a separate thread; queue a message to set
425   SetProjectionMode(Dali::Camera::PERSPECTIVE_PROJECTION);
426   SetFieldOfView( fieldOfView );
427   SetNearClippingPlane( nearClippingPlane );
428   SetFarClippingPlane( farClippingPlane );
429   SetAspectRatio( aspectRatio );
430   SetZ( cameraZ );
431 }
432
433
434 void CameraActor::SetOrthographicProjection( const Vector2& size )
435 {
436   // Choose near, far and Z parameters to match the SetPerspectiveProjection above.
437   float nearClippingPlane;
438   float farClippingPlane;
439   float cameraZ;
440   CalculateClippingAndZ( size.width, size.height, nearClippingPlane, farClippingPlane, cameraZ );
441   SetOrthographicProjection( -size.x*0.5f, size.x*0.5f, size.y*0.5f, -size.y*0.5f,
442                              nearClippingPlane, farClippingPlane );
443   SetZ( cameraZ );
444 }
445
446 void CameraActor::SetOrthographicProjection( float left, float right, float top, float bottom, float near, float far )
447 {
448   SetLeftClippingPlane( left );
449   SetRightClippingPlane( right );
450   SetTopClippingPlane( top );
451   SetBottomClippingPlane( bottom );
452   SetNearClippingPlane( near );
453   SetFarClippingPlane( far );
454   SetProjectionMode( Dali::Camera::ORTHOGRAPHIC_PROJECTION );
455 }
456
457 bool CameraActor::BuildPickingRay( const Vector2& screenCoordinates,
458                                    const Viewport& viewport,
459                                    Vector4& rayOrigin,
460                                    Vector4& rayDirection )
461 {
462   bool success = true;
463   if( mProjectionMode == Dali::Camera::PERSPECTIVE_PROJECTION )
464   {
465     // Build a picking ray in the world reference system.
466     // ray starts from the camera world position
467     rayOrigin = GetNode().GetWorldMatrix(0).GetTranslation();
468     rayOrigin.w = 1.0f;
469
470     // Transform the touch point from the screen coordinate system to the world coordinates system.
471     Vector4 near( screenCoordinates.x - static_cast<float>(viewport.x),
472                   static_cast<float>( viewport.height ) - (screenCoordinates.y - static_cast<float>( viewport.y ) ),
473                   0.f, 1.f );
474     const Matrix& inverseViewProjection = mSceneObject->GetInverseViewProjectionMatrix( GetEventThreadServices().GetEventBufferIndex() );
475     success = Unproject( near, inverseViewProjection, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), near );
476
477     // Compute the ray's director vector.
478     rayDirection.x = near.x - rayOrigin.x;
479     rayDirection.y = near.y - rayOrigin.y;
480     rayDirection.z = near.z - rayOrigin.z;
481     rayDirection.Normalize();
482     rayDirection.w = 1.f;
483   }
484   else
485   {
486     float nearPlaneDistance = GetNearClippingPlane();
487     BuildOrthoPickingRay( GetViewMatrix(),
488                           GetProjectionMatrix(),
489                           viewport, screenCoordinates.x,
490                           screenCoordinates.y,
491                           rayOrigin,
492                           rayDirection,
493                           nearPlaneDistance );
494   }
495
496   return success;
497 }
498
499 const Matrix& CameraActor::GetViewMatrix() const
500 {
501   if ( OnScene() )
502   {
503     return mSceneObject->GetViewMatrix( GetEventThreadServices().GetEventBufferIndex() );
504   }
505   else
506   {
507     return Matrix::IDENTITY;
508   }
509 }
510
511 const Matrix& CameraActor::GetProjectionMatrix() const
512 {
513   if ( OnScene() )
514   {
515     return mSceneObject->GetProjectionMatrix( GetEventThreadServices().GetEventBufferIndex() );
516   }
517   else
518   {
519     return Matrix::IDENTITY;
520   }
521 }
522 const SceneGraph::Camera* CameraActor::GetCamera() const
523 {
524   return mSceneObject;
525 }
526
527 void CameraActor::RotateProjection( int rotationAngle )
528 {
529   // sceneObject is being used in a separate thread; queue a message to set
530   RotateProjectionMessage( GetEventThreadServices(), *mSceneObject, rotationAngle );
531 }
532
533 void CameraActor::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
534 {
535   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
536   {
537     Actor::SetDefaultProperty(index, propertyValue);
538   }
539   else
540   {
541     switch(index)
542     {
543       case Dali::CameraActor::Property::TYPE:
544       {
545         std::string s( propertyValue.Get<std::string>() );
546         if(s == "LOOK_AT_TARGET")
547         {
548           SetType( Dali::Camera::LOOK_AT_TARGET );
549         }
550         else if(s == "FREE_LOOK")
551         {
552           SetType( Dali::Camera::FREE_LOOK );
553         }
554         break;
555       }
556       case Dali::CameraActor::Property::PROJECTION_MODE:
557       {
558         std::string s( propertyValue.Get<std::string>() );
559         if( s == "PERSPECTIVE_PROJECTION" )
560         {
561           SetProjectionMode( Dali::Camera::PERSPECTIVE_PROJECTION );
562         }
563         else if( s == "ORTHOGRAPHIC_PROJECTION" )
564         {
565           SetProjectionMode( Dali::Camera::ORTHOGRAPHIC_PROJECTION );
566         }
567         break;
568       }
569       case Dali::CameraActor::Property::FIELD_OF_VIEW:
570       {
571         SetFieldOfView( propertyValue.Get<float>() ); // set to 0 in case property is not float
572         break;
573       }
574       case Dali::CameraActor::Property::ASPECT_RATIO:
575       {
576         SetAspectRatio( propertyValue.Get<float>() ); // set to 0 in case property is not float
577         break;
578       }
579       case Dali::CameraActor::Property::NEAR_PLANE_DISTANCE:
580       {
581         SetNearClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
582         break;
583       }
584       case Dali::CameraActor::Property::FAR_PLANE_DISTANCE:
585       {
586         SetFarClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
587         break;
588       }
589       case Dali::CameraActor::Property::LEFT_PLANE_DISTANCE:
590       {
591         SetLeftClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
592         break;
593       }
594       case Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE:
595       {
596         SetRightClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
597         break;
598       }
599       case Dali::CameraActor::Property::TOP_PLANE_DISTANCE:
600       {
601         SetTopClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
602         break;
603       }
604       case Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE:
605       {
606         SetBottomClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
607         break;
608       }
609       case Dali::CameraActor::Property::TARGET_POSITION:
610       {
611         SetTarget( propertyValue.Get<Vector3>() ); // set to 0 in case property is not Vector3
612         break;
613       }
614       case Dali::CameraActor::Property::PROJECTION_MATRIX:
615       {
616         DALI_LOG_WARNING( "projection-matrix is read-only\n" );
617         break;
618       }
619       case Dali::CameraActor::Property::VIEW_MATRIX:
620       {
621         DALI_LOG_WARNING( "view-matrix is read-only\n" );
622         break;
623       }
624       case Dali::CameraActor::Property::INVERT_Y_AXIS:
625       {
626         SetInvertYAxis( propertyValue.Get<bool>() ); // set to false in case property is not bool
627         break;
628       }
629       case Dali::DevelCameraActor::Property::REFLECTION_PLANE:
630       {
631         SetReflectByPlane( propertyValue.Get<Vector4>() );
632         break;
633       }
634
635       default:
636       {
637         DALI_LOG_WARNING( "Unknown property (%d)\n", index );
638         break;
639       }
640     } // switch(index)
641
642   } // else
643 }
644
645 Property::Value CameraActor::GetDefaultProperty( Property::Index index ) const
646 {
647   Property::Value ret;
648   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
649   {
650     ret = Actor::GetDefaultProperty(index);
651   }
652   else
653   {
654     switch(index)
655     {
656       case Dali::CameraActor::Property::TYPE:
657       {
658         if( Dali::Camera::LOOK_AT_TARGET == mType )
659         {
660           ret = "LOOK_AT_TARGET";
661         }
662         else if( Dali::Camera::FREE_LOOK == mType )
663         {
664           ret = "FREE_LOOK";
665         }
666         break;
667       }
668       case Dali::CameraActor::Property::PROJECTION_MODE:
669       {
670         if( Dali::Camera::PERSPECTIVE_PROJECTION == mProjectionMode )
671         {
672           ret = "PERSPECTIVE_PROJECTION";
673         }
674         else if( Dali::Camera::ORTHOGRAPHIC_PROJECTION == mProjectionMode )
675         {
676           ret = "ORTHOGRAPHIC_PROJECTION";
677         }
678         break;
679       }
680       case Dali::CameraActor::Property::FIELD_OF_VIEW:
681       {
682         ret = mFieldOfView;
683         break;
684       }
685       case Dali::CameraActor::Property::ASPECT_RATIO:
686       {
687         ret = mAspectRatio;
688         break;
689       }
690       case Dali::CameraActor::Property::NEAR_PLANE_DISTANCE:
691       {
692         ret = mNearClippingPlane;
693         break;
694       }
695       case Dali::CameraActor::Property::FAR_PLANE_DISTANCE:
696       {
697         ret = mFarClippingPlane;
698         break;
699       }
700       case Dali::CameraActor::Property::LEFT_PLANE_DISTANCE:
701       {
702         ret = mLeftClippingPlane;
703         break;
704       }
705       case Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE:
706       {
707         ret = mRightClippingPlane;
708         break;
709       }
710       case Dali::CameraActor::Property::TOP_PLANE_DISTANCE:
711       {
712         ret = mTopClippingPlane;
713         break;
714       }
715       case Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE:
716       {
717         ret = mBottomClippingPlane;
718         break;
719       }
720       case Dali::CameraActor::Property::TARGET_POSITION:
721       {
722         ret = mTarget;
723         break;
724       }
725       case Dali::CameraActor::Property::PROJECTION_MATRIX:
726       {
727         ret = GetProjectionMatrix(); // Only on scene-graph
728         break;
729       }
730       case Dali::CameraActor::Property::VIEW_MATRIX:
731       {
732         ret = GetViewMatrix(); // Only on scene-graph
733         break;
734       }
735       case Dali::CameraActor::Property::INVERT_Y_AXIS:
736       {
737         ret = mInvertYAxis;
738         break;
739       }
740     } // switch(index)
741   }
742
743   return ret;
744 }
745
746 Property::Value CameraActor::GetDefaultPropertyCurrentValue( Property::Index index ) const
747 {
748   Property::Value ret;
749   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
750   {
751     ret = Actor::GetDefaultPropertyCurrentValue(index);
752   }
753   else
754   {
755     ret = GetDefaultProperty( index ); // Most are event-side properties, the scene-graph properties are only on the scene-graph
756   }
757
758   return ret;
759 }
760
761 const PropertyInputImpl* CameraActor::GetSceneObjectInputProperty( Property::Index index ) const
762 {
763   const PropertyInputImpl* property( nullptr );
764
765   switch( index )
766   {
767     case Dali::CameraActor::Property::PROJECTION_MATRIX:
768     {
769       property = mSceneObject->GetProjectionMatrix();
770       break;
771     }
772     case Dali::CameraActor::Property::VIEW_MATRIX:
773     {
774       property = mSceneObject->GetViewMatrix();
775       break;
776     }
777     // no default on purpose as we chain method up to actor
778   }
779   if( !property )
780   {
781     property = Actor::GetSceneObjectInputProperty( index );
782   }
783
784   return property;
785 }
786
787 } // namespace Internal
788
789 } // namespace Dali