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