Revert "[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::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
528 {
529   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
530   {
531     Actor::SetDefaultProperty(index, propertyValue);
532   }
533   else
534   {
535     switch(index)
536     {
537       case Dali::CameraActor::Property::TYPE:
538       {
539         std::string s( propertyValue.Get<std::string>() );
540         if(s == "LOOK_AT_TARGET")
541         {
542           SetType( Dali::Camera::LOOK_AT_TARGET );
543         }
544         else if(s == "FREE_LOOK")
545         {
546           SetType( Dali::Camera::FREE_LOOK );
547         }
548         break;
549       }
550       case Dali::CameraActor::Property::PROJECTION_MODE:
551       {
552         std::string s( propertyValue.Get<std::string>() );
553         if( s == "PERSPECTIVE_PROJECTION" )
554         {
555           SetProjectionMode( Dali::Camera::PERSPECTIVE_PROJECTION );
556         }
557         else if( s == "ORTHOGRAPHIC_PROJECTION" )
558         {
559           SetProjectionMode( Dali::Camera::ORTHOGRAPHIC_PROJECTION );
560         }
561         break;
562       }
563       case Dali::CameraActor::Property::FIELD_OF_VIEW:
564       {
565         SetFieldOfView( propertyValue.Get<float>() ); // set to 0 in case property is not float
566         break;
567       }
568       case Dali::CameraActor::Property::ASPECT_RATIO:
569       {
570         SetAspectRatio( propertyValue.Get<float>() ); // set to 0 in case property is not float
571         break;
572       }
573       case Dali::CameraActor::Property::NEAR_PLANE_DISTANCE:
574       {
575         SetNearClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
576         break;
577       }
578       case Dali::CameraActor::Property::FAR_PLANE_DISTANCE:
579       {
580         SetFarClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
581         break;
582       }
583       case Dali::CameraActor::Property::LEFT_PLANE_DISTANCE:
584       {
585         SetLeftClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
586         break;
587       }
588       case Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE:
589       {
590         SetRightClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
591         break;
592       }
593       case Dali::CameraActor::Property::TOP_PLANE_DISTANCE:
594       {
595         SetTopClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
596         break;
597       }
598       case Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE:
599       {
600         SetBottomClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
601         break;
602       }
603       case Dali::CameraActor::Property::TARGET_POSITION:
604       {
605         SetTarget( propertyValue.Get<Vector3>() ); // set to 0 in case property is not Vector3
606         break;
607       }
608       case Dali::CameraActor::Property::PROJECTION_MATRIX:
609       {
610         DALI_LOG_WARNING( "projection-matrix is read-only\n" );
611         break;
612       }
613       case Dali::CameraActor::Property::VIEW_MATRIX:
614       {
615         DALI_LOG_WARNING( "view-matrix is read-only\n" );
616         break;
617       }
618       case Dali::CameraActor::Property::INVERT_Y_AXIS:
619       {
620         SetInvertYAxis( propertyValue.Get<bool>() ); // set to false in case property is not bool
621         break;
622       }
623       case Dali::DevelCameraActor::Property::REFLECTION_PLANE:
624       {
625         SetReflectByPlane( propertyValue.Get<Vector4>() );
626         break;
627       }
628
629       default:
630       {
631         DALI_LOG_WARNING( "Unknown property (%d)\n", index );
632         break;
633       }
634     } // switch(index)
635
636   } // else
637 }
638
639 Property::Value CameraActor::GetDefaultProperty( Property::Index index ) const
640 {
641   Property::Value ret;
642   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
643   {
644     ret = Actor::GetDefaultProperty(index);
645   }
646   else
647   {
648     switch(index)
649     {
650       case Dali::CameraActor::Property::TYPE:
651       {
652         if( Dali::Camera::LOOK_AT_TARGET == mType )
653         {
654           ret = "LOOK_AT_TARGET";
655         }
656         else if( Dali::Camera::FREE_LOOK == mType )
657         {
658           ret = "FREE_LOOK";
659         }
660         break;
661       }
662       case Dali::CameraActor::Property::PROJECTION_MODE:
663       {
664         if( Dali::Camera::PERSPECTIVE_PROJECTION == mProjectionMode )
665         {
666           ret = "PERSPECTIVE_PROJECTION";
667         }
668         else if( Dali::Camera::ORTHOGRAPHIC_PROJECTION == mProjectionMode )
669         {
670           ret = "ORTHOGRAPHIC_PROJECTION";
671         }
672         break;
673       }
674       case Dali::CameraActor::Property::FIELD_OF_VIEW:
675       {
676         ret = mFieldOfView;
677         break;
678       }
679       case Dali::CameraActor::Property::ASPECT_RATIO:
680       {
681         ret = mAspectRatio;
682         break;
683       }
684       case Dali::CameraActor::Property::NEAR_PLANE_DISTANCE:
685       {
686         ret = mNearClippingPlane;
687         break;
688       }
689       case Dali::CameraActor::Property::FAR_PLANE_DISTANCE:
690       {
691         ret = mFarClippingPlane;
692         break;
693       }
694       case Dali::CameraActor::Property::LEFT_PLANE_DISTANCE:
695       {
696         ret = mLeftClippingPlane;
697         break;
698       }
699       case Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE:
700       {
701         ret = mRightClippingPlane;
702         break;
703       }
704       case Dali::CameraActor::Property::TOP_PLANE_DISTANCE:
705       {
706         ret = mTopClippingPlane;
707         break;
708       }
709       case Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE:
710       {
711         ret = mBottomClippingPlane;
712         break;
713       }
714       case Dali::CameraActor::Property::TARGET_POSITION:
715       {
716         ret = mTarget;
717         break;
718       }
719       case Dali::CameraActor::Property::PROJECTION_MATRIX:
720       {
721         ret = GetProjectionMatrix(); // Only on scene-graph
722         break;
723       }
724       case Dali::CameraActor::Property::VIEW_MATRIX:
725       {
726         ret = GetViewMatrix(); // Only on scene-graph
727         break;
728       }
729       case Dali::CameraActor::Property::INVERT_Y_AXIS:
730       {
731         ret = mInvertYAxis;
732         break;
733       }
734     } // switch(index)
735   }
736
737   return ret;
738 }
739
740 Property::Value CameraActor::GetDefaultPropertyCurrentValue( Property::Index index ) const
741 {
742   Property::Value ret;
743   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
744   {
745     ret = Actor::GetDefaultPropertyCurrentValue(index);
746   }
747   else
748   {
749     ret = GetDefaultProperty( index ); // Most are event-side properties, the scene-graph properties are only on the scene-graph
750   }
751
752   return ret;
753 }
754
755 const PropertyInputImpl* CameraActor::GetSceneObjectInputProperty( Property::Index index ) const
756 {
757   const PropertyInputImpl* property( nullptr );
758
759   switch( index )
760   {
761     case Dali::CameraActor::Property::PROJECTION_MATRIX:
762     {
763       property = mSceneObject->GetProjectionMatrix();
764       break;
765     }
766     case Dali::CameraActor::Property::VIEW_MATRIX:
767     {
768       property = mSceneObject->GetViewMatrix();
769       break;
770     }
771     // no default on purpose as we chain method up to actor
772   }
773   if( !property )
774   {
775     property = Actor::GetSceneObjectInputProperty( index );
776   }
777
778   return property;
779 }
780
781 } // namespace Internal
782
783 } // namespace Dali