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