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