2afd2eb595c9a4154ea8d9f8108a723e6e26867c
[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::SetTarget( const Vector3& target )
203 {
204   if( target != mTarget ) // using range epsilon
205   {
206     mTarget = target;
207
208     SetTargetPositionMessage( GetEventThreadServices(),  *mSceneObject, mTarget );
209   }
210 }
211
212 Vector3 CameraActor::GetTarget() const
213 {
214   return mTarget;
215 }
216
217 void CameraActor::SetType( Dali::Camera::Type type )
218 {
219   if( type != mType )
220   {
221     mType = type;
222
223     // sceneObject is being used in a separate thread; queue a message to set
224     SetTypeMessage( GetEventThreadServices(), *mSceneObject, mType );
225   }
226 }
227
228 Dali::Camera::Type CameraActor::GetType() const
229 {
230   return mType;
231 }
232
233 void CameraActor::SetProjectionMode( Dali::Camera::ProjectionMode mode )
234 {
235   if( mode != mProjectionMode )
236   {
237     mProjectionMode = mode;
238
239     // sceneObject is being used in a separate thread; queue a message to set
240     SetProjectionModeMessage( GetEventThreadServices(), *mSceneObject, mProjectionMode );
241   }
242 }
243
244 Dali::Camera::ProjectionMode CameraActor::GetProjectionMode() const
245 {
246   return mProjectionMode;
247 }
248
249 void CameraActor::SetFieldOfView( float fieldOfView )
250 {
251   if( ! Equals( fieldOfView, mFieldOfView ) )
252   {
253     mFieldOfView = fieldOfView;
254
255     // sceneObject is being used in a separate thread; queue a message to set
256     SetFieldOfViewMessage( GetEventThreadServices(), *mSceneObject, mFieldOfView );
257   }
258 }
259
260 float CameraActor::GetFieldOfView() const
261 {
262   return mFieldOfView;
263 }
264
265 void CameraActor::SetAspectRatio( float aspectRatio )
266 {
267   if( ! Equals( aspectRatio, mAspectRatio ) )
268   {
269     mAspectRatio = aspectRatio;
270
271     // sceneObject is being used in a separate thread; queue a message to set
272     SetAspectRatioMessage( GetEventThreadServices(), *mSceneObject, mAspectRatio );
273   }
274 }
275
276 float CameraActor::GetAspectRatio() const
277 {
278   return mAspectRatio;
279 }
280
281 void CameraActor::SetNearClippingPlane( float nearClippingPlane )
282 {
283   if( ! Equals( nearClippingPlane, mNearClippingPlane ) )
284   {
285     mNearClippingPlane = nearClippingPlane;
286
287     // sceneObject is being used in a separate thread; queue a message to set
288     SetNearClippingPlaneMessage( GetEventThreadServices(), *mSceneObject, mNearClippingPlane );
289   }
290 }
291
292 float CameraActor::GetNearClippingPlane() const
293 {
294   return mNearClippingPlane;
295 }
296
297 void CameraActor::SetFarClippingPlane( float farClippingPlane )
298 {
299   if( ! Equals( farClippingPlane, mFarClippingPlane ) )
300   {
301     mFarClippingPlane = farClippingPlane;
302
303     // sceneObject is being used in a separate thread; queue a message to set
304     SetFarClippingPlaneMessage( GetEventThreadServices(), *mSceneObject, mFarClippingPlane );
305   }
306 }
307
308 float CameraActor::GetFarClippingPlane() const
309 {
310   return mFarClippingPlane;
311 }
312
313 void CameraActor::SetLeftClippingPlane( float leftClippingPlane )
314 {
315   if( ! Equals( leftClippingPlane, mLeftClippingPlane ) )
316   {
317     mLeftClippingPlane = leftClippingPlane;
318
319     // sceneObject is being used in a separate thread; queue a message to set
320     SetLeftClippingPlaneMessage( GetEventThreadServices(), *mSceneObject, mLeftClippingPlane );
321   }
322 }
323
324 void CameraActor::SetRightClippingPlane( float rightClippingPlane )
325 {
326   if( ! Equals( rightClippingPlane, mRightClippingPlane ) )
327   {
328     mRightClippingPlane = rightClippingPlane;
329
330     // sceneObject is being used in a separate thread; queue a message to set
331     SetRightClippingPlaneMessage( GetEventThreadServices(), *mSceneObject, mRightClippingPlane );
332   }
333 }
334
335 void CameraActor::SetTopClippingPlane( float topClippingPlane )
336 {
337   if( ! Equals( topClippingPlane, mTopClippingPlane ) )
338   {
339     mTopClippingPlane = topClippingPlane;
340
341     // sceneObject is being used in a separate thread; queue a message to set
342     SetTopClippingPlaneMessage( GetEventThreadServices(), *mSceneObject, mTopClippingPlane );
343   }
344 }
345
346 void CameraActor::SetBottomClippingPlane( float bottomClippingPlane )
347 {
348   if( ! Equals( bottomClippingPlane, mBottomClippingPlane ) )
349   {
350     mBottomClippingPlane = bottomClippingPlane;
351
352     // sceneObject is being used in a separate thread; queue a message to set
353     SetBottomClippingPlaneMessage( GetEventThreadServices(), *mSceneObject, mBottomClippingPlane );
354   }
355 }
356
357 void CameraActor::SetInvertYAxis(bool invertYAxis)
358 {
359   if( invertYAxis != mInvertYAxis )
360   {
361     mInvertYAxis = invertYAxis;
362
363     // sceneObject is being used in a separate thread; queue a message to set
364     SetInvertYAxisMessage( GetEventThreadServices(), *mSceneObject, mInvertYAxis );
365   }
366 }
367
368 bool CameraActor::GetInvertYAxis() const
369 {
370   return mInvertYAxis;
371 }
372
373 void CameraActor::SetPerspectiveProjection( const Size& size )
374 {
375   float width = size.width;
376   float height = size.height;
377
378   if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
379   {
380     Size stageSize = Dali::Stage::GetCurrent().GetSize();
381     width = stageSize.width;
382     height = stageSize.height;
383   }
384
385   float nearClippingPlane;
386   float farClippingPlane;
387   float cameraZ;
388   CalculateClippingAndZ( width, height, nearClippingPlane, farClippingPlane, cameraZ );
389
390   // calculate the position of the camera to have the desired aspect ratio
391   const float fieldOfView = 2.0f * std::atan( height * 0.5f / cameraZ );
392
393   // unless it is too small, we want at least as much space to the back as we have torwards the front
394   const float minClippingFarPlane = 2.f * nearClippingPlane;
395   if ( farClippingPlane < minClippingFarPlane )
396   {
397     farClippingPlane = minClippingFarPlane;
398   }
399
400   const float aspectRatio = width / height;
401
402   // sceneObject is being used in a separate thread; queue a message to set
403   SetProjectionMode(Dali::Camera::PERSPECTIVE_PROJECTION);
404   SetFieldOfView( fieldOfView );
405   SetNearClippingPlane( nearClippingPlane );
406   SetFarClippingPlane( farClippingPlane );
407   SetAspectRatio( aspectRatio );
408   SetZ( cameraZ );
409 }
410
411
412 void CameraActor::SetOrthographicProjection( const Vector2& size )
413 {
414   // Choose near, far and Z parameters to match the SetPerspectiveProjection above.
415   float nearClippingPlane;
416   float farClippingPlane;
417   float cameraZ;
418   CalculateClippingAndZ( size.width, size.height, nearClippingPlane, farClippingPlane, cameraZ );
419   SetOrthographicProjection( -size.x*0.5f, size.x*0.5f, size.y*0.5f, -size.y*0.5f,
420                              nearClippingPlane, farClippingPlane );
421   SetZ( cameraZ );
422 }
423
424 void CameraActor::SetOrthographicProjection( float left, float right, float top, float bottom, float near, float far )
425 {
426   SetLeftClippingPlane( left );
427   SetRightClippingPlane( right );
428   SetTopClippingPlane( top );
429   SetBottomClippingPlane( bottom );
430   SetNearClippingPlane( near );
431   SetFarClippingPlane( far );
432   SetProjectionMode( Dali::Camera::ORTHOGRAPHIC_PROJECTION );
433 }
434
435 bool CameraActor::BuildPickingRay( const Vector2& screenCoordinates,
436                                    const Viewport& viewport,
437                                    Vector4& rayOrigin,
438                                    Vector4& rayDirection )
439 {
440   bool success = true;
441   if( mProjectionMode == Dali::Camera::PERSPECTIVE_PROJECTION )
442   {
443     // Build a picking ray in the world reference system.
444     // ray starts from the camera world position
445     rayOrigin = GetNode().GetWorldMatrix(0).GetTranslation();
446     rayOrigin.w = 1.0f;
447
448     // Transform the touch point from the screen coordinate system to the world coordinates system.
449     Vector4 near( screenCoordinates.x - static_cast<float>(viewport.x),
450                   static_cast<float>( viewport.height ) - (screenCoordinates.y - static_cast<float>( viewport.y ) ),
451                   0.f, 1.f );
452     const Matrix& inverseViewProjection = mSceneObject->GetInverseViewProjectionMatrix( GetEventThreadServices().GetEventBufferIndex() );
453     success = Unproject( near, inverseViewProjection, static_cast<float>( viewport.width ), static_cast<float>( viewport.height ), near );
454
455     // Compute the ray's director vector.
456     rayDirection.x = near.x - rayOrigin.x;
457     rayDirection.y = near.y - rayOrigin.y;
458     rayDirection.z = near.z - rayOrigin.z;
459     rayDirection.Normalize();
460     rayDirection.w = 1.f;
461   }
462   else
463   {
464     float nearPlaneDistance = GetNearClippingPlane();
465     BuildOrthoPickingRay( GetViewMatrix(),
466                           GetProjectionMatrix(),
467                           viewport, screenCoordinates.x,
468                           screenCoordinates.y,
469                           rayOrigin,
470                           rayDirection,
471                           nearPlaneDistance );
472   }
473
474   return success;
475 }
476
477 const Matrix& CameraActor::GetViewMatrix() const
478 {
479   if ( OnStage() )
480   {
481     return mSceneObject->GetViewMatrix( GetEventThreadServices().GetEventBufferIndex() );
482   }
483   else
484   {
485     return Matrix::IDENTITY;
486   }
487 }
488
489 const Matrix& CameraActor::GetProjectionMatrix() const
490 {
491   if ( OnStage() )
492   {
493     return mSceneObject->GetProjectionMatrix( GetEventThreadServices().GetEventBufferIndex() );
494   }
495   else
496   {
497     return Matrix::IDENTITY;
498   }
499 }
500 const SceneGraph::Camera* CameraActor::GetCamera() const
501 {
502   return mSceneObject;
503 }
504
505 void CameraActor::RotateProjection( int rotationAngle )
506 {
507   // sceneObject is being used in a separate thread; queue a message to set
508   RotateProjectionMessage( GetEventThreadServices(), *mSceneObject, rotationAngle );
509 }
510
511 void CameraActor::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
512 {
513   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
514   {
515     Actor::SetDefaultProperty(index, propertyValue);
516   }
517   else
518   {
519     switch(index)
520     {
521       case Dali::CameraActor::Property::TYPE:
522       {
523         std::string s( propertyValue.Get<std::string>() );
524         if(s == "LOOK_AT_TARGET")
525         {
526           SetType( Dali::Camera::LOOK_AT_TARGET );
527         }
528         else if(s == "FREE_LOOK")
529         {
530           SetType( Dali::Camera::FREE_LOOK );
531         }
532         break;
533       }
534       case Dali::CameraActor::Property::PROJECTION_MODE:
535       {
536         std::string s( propertyValue.Get<std::string>() );
537         if( s == "PERSPECTIVE_PROJECTION" )
538         {
539           SetProjectionMode( Dali::Camera::PERSPECTIVE_PROJECTION );
540         }
541         else if( s == "ORTHOGRAPHIC_PROJECTION" )
542         {
543           SetProjectionMode( Dali::Camera::ORTHOGRAPHIC_PROJECTION );
544         }
545         break;
546       }
547       case Dali::CameraActor::Property::FIELD_OF_VIEW:
548       {
549         SetFieldOfView( propertyValue.Get<float>() ); // set to 0 in case property is not float
550         break;
551       }
552       case Dali::CameraActor::Property::ASPECT_RATIO:
553       {
554         SetAspectRatio( propertyValue.Get<float>() ); // set to 0 in case property is not float
555         break;
556       }
557       case Dali::CameraActor::Property::NEAR_PLANE_DISTANCE:
558       {
559         SetNearClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
560         break;
561       }
562       case Dali::CameraActor::Property::FAR_PLANE_DISTANCE:
563       {
564         SetFarClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
565         break;
566       }
567       case Dali::CameraActor::Property::LEFT_PLANE_DISTANCE:
568       {
569         SetLeftClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
570         break;
571       }
572       case Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE:
573       {
574         SetRightClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
575         break;
576       }
577       case Dali::CameraActor::Property::TOP_PLANE_DISTANCE:
578       {
579         SetTopClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
580         break;
581       }
582       case Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE:
583       {
584         SetBottomClippingPlane( propertyValue.Get<float>() ); // set to 0 in case property is not float
585         break;
586       }
587       case Dali::CameraActor::Property::TARGET_POSITION:
588       {
589         SetTarget( propertyValue.Get<Vector3>() ); // set to 0 in case property is not Vector3
590         break;
591       }
592       case Dali::CameraActor::Property::PROJECTION_MATRIX:
593       {
594         DALI_LOG_WARNING( "projection-matrix is read-only\n" );
595         break;
596       }
597       case Dali::CameraActor::Property::VIEW_MATRIX:
598       {
599         DALI_LOG_WARNING( "view-matrix is read-only\n" );
600         break;
601       }
602       case Dali::CameraActor::Property::INVERT_Y_AXIS:
603       {
604         SetInvertYAxis( propertyValue.Get<bool>() ); // set to false in case property is not bool
605         break;
606       }
607       default:
608       {
609         DALI_LOG_WARNING( "Unknown property (%d)\n", index );
610         break;
611       }
612     } // switch(index)
613
614   } // else
615 }
616
617 Property::Value CameraActor::GetDefaultProperty( Property::Index index ) const
618 {
619   Property::Value ret;
620   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
621   {
622     ret = Actor::GetDefaultProperty(index);
623   }
624   else
625   {
626     switch(index)
627     {
628       case Dali::CameraActor::Property::TYPE:
629       {
630         if( Dali::Camera::LOOK_AT_TARGET == mType )
631         {
632           ret = "LOOK_AT_TARGET";
633         }
634         else if( Dali::Camera::FREE_LOOK == mType )
635         {
636           ret = "FREE_LOOK";
637         }
638         break;
639       }
640       case Dali::CameraActor::Property::PROJECTION_MODE:
641       {
642         if( Dali::Camera::PERSPECTIVE_PROJECTION == mProjectionMode )
643         {
644           ret = "PERSPECTIVE_PROJECTION";
645         }
646         else if( Dali::Camera::ORTHOGRAPHIC_PROJECTION == mProjectionMode )
647         {
648           ret = "ORTHOGRAPHIC_PROJECTION";
649         }
650         break;
651       }
652       case Dali::CameraActor::Property::FIELD_OF_VIEW:
653       {
654         ret = mFieldOfView;
655         break;
656       }
657       case Dali::CameraActor::Property::ASPECT_RATIO:
658       {
659         ret = mAspectRatio;
660         break;
661       }
662       case Dali::CameraActor::Property::NEAR_PLANE_DISTANCE:
663       {
664         ret = mNearClippingPlane;
665         break;
666       }
667       case Dali::CameraActor::Property::FAR_PLANE_DISTANCE:
668       {
669         ret = mFarClippingPlane;
670         break;
671       }
672       case Dali::CameraActor::Property::LEFT_PLANE_DISTANCE:
673       {
674         ret = mLeftClippingPlane;
675         break;
676       }
677       case Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE:
678       {
679         ret = mRightClippingPlane;
680         break;
681       }
682       case Dali::CameraActor::Property::TOP_PLANE_DISTANCE:
683       {
684         ret = mTopClippingPlane;
685         break;
686       }
687       case Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE:
688       {
689         ret = mBottomClippingPlane;
690         break;
691       }
692       case Dali::CameraActor::Property::TARGET_POSITION:
693       {
694         ret = mTarget;
695         break;
696       }
697       case Dali::CameraActor::Property::PROJECTION_MATRIX:
698       {
699         ret = GetProjectionMatrix(); // Only on scene-graph
700         break;
701       }
702       case Dali::CameraActor::Property::VIEW_MATRIX:
703       {
704         ret = GetViewMatrix(); // Only on scene-graph
705         break;
706       }
707       case Dali::CameraActor::Property::INVERT_Y_AXIS:
708       {
709         ret = mInvertYAxis;
710         break;
711       }
712     } // switch(index)
713   }
714
715   return ret;
716 }
717
718 Property::Value CameraActor::GetDefaultPropertyCurrentValue( Property::Index index ) const
719 {
720   Property::Value ret;
721   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
722   {
723     ret = Actor::GetDefaultPropertyCurrentValue(index);
724   }
725   else
726   {
727     ret = GetDefaultProperty( index ); // Most are event-side properties, the scene-graph properties are only on the scene-graph
728   }
729
730   return ret;
731 }
732
733 const PropertyInputImpl* CameraActor::GetSceneObjectInputProperty( Property::Index index ) const
734 {
735   const PropertyInputImpl* property( NULL );
736
737   switch( index )
738   {
739     case Dali::CameraActor::Property::PROJECTION_MATRIX:
740     {
741       property = mSceneObject->GetProjectionMatrix();
742       break;
743     }
744     case Dali::CameraActor::Property::VIEW_MATRIX:
745     {
746       property = mSceneObject->GetViewMatrix();
747       break;
748     }
749     // no default on purpose as we chain method up to actor
750   }
751   if( !property )
752   {
753     property = Actor::GetSceneObjectInputProperty( index );
754   }
755
756   return property;
757 }
758
759 } // namespace Internal
760
761 } // namespace Dali