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