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