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