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