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