Moved OwnerContainer from internal to devel-api.
[platform/core/uifw/dali-core.git] / dali / internal / update / animation / scene-graph-animator.h
1 #ifndef __DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H__
2 #define __DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H__
3
4 /*
5  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/devel-api/common/owner-container.h>
23 #include <dali/internal/event/animation/key-frames-impl.h>
24 #include <dali/internal/event/animation/path-impl.h>
25 #include <dali/internal/update/nodes/node.h>
26 #include <dali/internal/update/common/property-base.h>
27 #include <dali/public-api/animation/alpha-function.h>
28 #include <dali/public-api/animation/animation.h>
29 #include <dali/public-api/animation/time-period.h>
30 #include <dali/public-api/common/constants.h>
31 #include <dali/public-api/common/dali-common.h>
32 #include <dali/public-api/math/quaternion.h>
33 #include <dali/public-api/math/radian.h>
34
35 namespace Dali
36 {
37
38 namespace Internal
39 {
40
41 typedef Dali::Animation::Interpolation Interpolation;
42
43 struct AnimatorFunctionBase;
44
45 namespace SceneGraph
46 {
47
48 class AnimatorBase;
49
50 typedef OwnerContainer< AnimatorBase* > AnimatorContainer;
51
52 typedef AnimatorContainer::Iterator AnimatorIter;
53 typedef AnimatorContainer::ConstIterator AnimatorConstIter;
54
55 /**
56  * An abstract base class for Animators, which can be added to scene graph animations.
57  * Each animator changes a single property of an object in the scene graph.
58  */
59 class AnimatorBase
60 {
61 public:
62
63   typedef float (*AlphaFunc)(float progress); ///< Definition of an alpha function
64
65   /**
66    * Constructor.
67    */
68   AnimatorBase()
69   : mDurationSeconds(1.0f),
70     mInitialDelaySeconds(0.0f),
71     mAlphaFunction(AlphaFunction::DEFAULT),
72     mDisconnectAction(Dali::Animation::BakeFinal),
73     mActive(false),
74     mEnabled(true),
75     mConnectedToSceneGraph(false)
76   {
77   }
78
79   /**
80    * Virtual destructor.
81    */
82   virtual ~AnimatorBase()
83   {
84   }
85
86   /**
87    * Called when Animator is added to the scene-graph in update-thread.
88    */
89   virtual void ConnectToSceneGraph() = 0;
90
91   /**
92    * Set the duration of the animator.
93    * @pre durationSeconds must be zero or greater; zero is useful when animating boolean values.
94    * @param [in] seconds Duration in seconds.
95    */
96   void SetDuration(float seconds)
97   {
98     DALI_ASSERT_DEBUG(seconds >= 0.0f);
99
100     mDurationSeconds = seconds;
101   }
102
103   /**
104    * Retrieve the duration of the animator.
105    * @return The duration in seconds.
106    */
107   float GetDuration()
108   {
109     return mDurationSeconds;
110   }
111
112   /**
113    * Set the delay before the animator should take effect.
114    * The default is zero i.e. no delay.
115    * @param [in] seconds The delay in seconds.
116    */
117   void SetInitialDelay(float seconds)
118   {
119     mInitialDelaySeconds = seconds;
120   }
121
122   /**
123    * Retrieve the initial delay of the animator.
124    * @return The delay in seconds.
125    */
126   float GetInitialDelay()
127   {
128     return mInitialDelaySeconds;
129   }
130
131   /**
132    * Set the alpha function for an animator.
133    * @param [in] alphaFunc The alpha function to apply to the animation progress.
134    */
135   void SetAlphaFunction(const AlphaFunction& alphaFunction)
136   {
137     mAlphaFunction = alphaFunction;
138   }
139
140   /**
141    * Retrieve the alpha function of an animator.
142    * @return The function.
143    */
144   AlphaFunction GetAlphaFunction() const
145   {
146     return mAlphaFunction;
147   }
148
149   /*
150    * Applies the alpha function to the specified progress
151    * @param[in] Current progress
152    * @return The progress after the alpha function has been aplied
153    */
154   float ApplyAlphaFunction( float progress ) const
155   {
156     float result = progress;
157
158     AlphaFunction::Mode alphaFunctionMode( mAlphaFunction.GetMode() );
159     if( alphaFunctionMode == AlphaFunction::BUILTIN_FUNCTION )
160     {
161       switch(mAlphaFunction.GetBuiltinFunction())
162       {
163         case AlphaFunction::DEFAULT:
164         case AlphaFunction::LINEAR:
165         {
166           break;
167         }
168         case AlphaFunction::REVERSE:
169         {
170           result = 1.0f-progress;
171           break;
172         }
173         case AlphaFunction::EASE_IN_SQUARE:
174         {
175           result = progress * progress;
176           break;
177         }
178         case AlphaFunction::EASE_OUT_SQUARE:
179         {
180           result = 1.0f - (1.0f-progress) * (1.0f-progress);
181           break;
182         }
183         case AlphaFunction::EASE_IN:
184         {
185           result = progress * progress * progress;
186           break;
187         }
188         case AlphaFunction::EASE_OUT:
189         {
190           result = (progress-1.0f) * (progress-1.0f) * (progress-1.0f) + 1.0f;
191           break;
192         }
193         case AlphaFunction::EASE_IN_OUT:
194         {
195           result = progress*progress*(3.0f-2.0f*progress);
196           break;
197         }
198         case AlphaFunction::EASE_IN_SINE:
199         {
200           result = -1.0f * cosf(progress * Math::PI_2) + 1.0f;
201           break;
202         }
203         case AlphaFunction::EASE_OUT_SINE:
204         {
205           result = sinf(progress * Math::PI_2);
206           break;
207         }
208         case AlphaFunction::EASE_IN_OUT_SINE:
209         {
210           result = -0.5f * (cosf(Math::PI * progress) - 1.0f);
211           break;
212         }
213         case AlphaFunction::BOUNCE:
214         {
215           result = sinf(progress * Math::PI);
216           break;
217         }
218         case AlphaFunction::SIN:
219         {
220           result = 0.5f - cosf(progress * 2.0f * Math::PI) * 0.5f;
221           break;
222         }
223         case AlphaFunction::EASE_OUT_BACK:
224         {
225           const float sqrt2 = 1.70158f;
226           progress -= 1.0f;
227           result = 1.0f + progress * progress * ( ( sqrt2 + 1.0f ) * progress + sqrt2 );
228           break;
229         }
230         case AlphaFunction::COUNT:
231         {
232           break;
233         }
234       }
235     }
236     else if(  alphaFunctionMode == AlphaFunction::CUSTOM_FUNCTION )
237     {
238       AlphaFunctionPrototype customFunction = mAlphaFunction.GetCustomFunction();
239       if( customFunction )
240       {
241         result = customFunction(progress);
242       }
243     }
244     else
245     {
246       //If progress is very close to 0 or very close to 1 we don't need to evaluate the curve as the result will
247       //be almost 0 or almost 1 respectively
248       if( ( progress > Math::MACHINE_EPSILON_1 ) && ((1.0f - progress) > Math::MACHINE_EPSILON_1) )
249       {
250         Dali::Vector4 controlPoints = mAlphaFunction.GetBezierControlPoints();
251
252         static const float tolerance = 0.001f;  //10 iteration max
253
254         //Perform a binary search on the curve
255         float lowerBound(0.0f);
256         float upperBound(1.0f);
257         float currentT(0.5f);
258         float currentX = EvaluateCubicBezier( controlPoints.x, controlPoints.z, currentT);
259         while( fabs( progress - currentX ) > tolerance )
260         {
261           if( progress > currentX )
262           {
263             lowerBound = currentT;
264           }
265           else
266           {
267             upperBound = currentT;
268           }
269           currentT = (upperBound+lowerBound)*0.5f;
270           currentX = EvaluateCubicBezier( controlPoints.x, controlPoints.z, currentT);
271         }
272         result = EvaluateCubicBezier( controlPoints.y, controlPoints.w, currentT);
273       }
274     }
275
276     return result;
277   }
278
279   /**
280    * Whether to bake the animation if attached property owner is disconnected.
281    * Property is only baked if the animator is active.
282    * @param [in] action The disconnect action.
283    */
284   void SetDisconnectAction( Dali::Animation::EndAction action )
285   {
286     mDisconnectAction = action;
287   }
288
289   /**
290    * Retrieve the disconnect action of an animator.
291    * @return The disconnect action.
292    */
293   Dali::Animation::EndAction GetDisconnectAction() const
294   {
295     return mDisconnectAction;
296   }
297
298   /**
299    * Whether the animator is active or not.
300    * @param [in] active The new active state.
301    * @post When the animator becomes active, it applies the disconnect-action if the property owner is then disconnected.
302    * @note When the property owner is disconnected, the active state is set to false.
303    */
304   void SetActive( bool active )
305   {
306     mActive = active;
307   }
308
309   /**
310    * Retrieve whether the animator has been set to active or not.
311    * @return The active state.
312    */
313   bool GetActive() const
314   {
315     return mActive;
316   }
317
318   /*
319    * Retrive wheter the animator's target object is valid and on the stage.
320    * @return The enabled state.
321    */
322   bool IsEnabled() const
323   {
324     return mEnabled;
325   }
326   /**
327    * Returns wheter the target object of the animator is still valid
328    * or has been destroyed.
329    * @return True if animator is orphan, false otherwise   *
330    * @note The SceneGraph::Animation will delete any orphan animator in its Update method.
331    */
332   virtual bool Orphan() = 0;
333
334   /**
335    * Update the scene object attached to the animator.
336    * @param[in] bufferIndex The buffer to animate.
337    * @param[in] progress A value from 0 to 1, where 0 is the start of the animation, and 1 is the end point.
338    * @param[in] bake Bake.
339    */
340   virtual void Update(BufferIndex bufferIndex, float progress, bool bake) = 0;
341
342 protected:
343
344   /**
345    * Helper function to evaluate a cubic bezier curve assuming first point is at 0.0 and last point is at 1.0
346    * @param[in] p0 First control point of the bezier curve
347    * @param[in] p1 Second control point of the bezier curve
348    * @param[in] t A floating point value between 0.0 and 1.0
349    * @return Value of the curve at progress t
350    */
351   inline float EvaluateCubicBezier( float p0, float p1, float t ) const
352   {
353     float tSquare = t*t;
354     return 3.0f*(1.0f-t)*(1.0f-t)*t*p0 + 3.0f*(1.0f-t)*tSquare*p1 + tSquare*t;
355   }
356
357   float mDurationSeconds;
358   float mInitialDelaySeconds;
359
360   AlphaFunction mAlphaFunction;
361
362   Dali::Animation::EndAction mDisconnectAction;     ///< EndAction to apply when target object gets disconnected from the stage.
363   bool mActive:1;                                   ///< Animator is "active" while it's running.
364   bool mEnabled:1;                                  ///< Animator is "enabled" while its target object is valid and on the stage.
365   bool mConnectedToSceneGraph:1;                    ///< True if ConnectToSceneGraph() has been called in update-thread.
366 };
367
368 /**
369  * An animator for a specific property type PropertyType.
370  */
371 template < typename PropertyType, typename PropertyAccessorType >
372 class Animator : public AnimatorBase, public PropertyOwner::Observer
373 {
374 public:
375
376   /**
377    * Construct a new property animator.
378    * @param[in] property The animatable property; only valid while the Animator is attached.
379    * @param[in] animatorFunction The function used to animate the property.
380    * @param[in] alphaFunction The alpha function to apply.
381    * @param[in] timePeriod The time period of this animation.
382    * @return A newly allocated animator.
383    */
384   static AnimatorBase* New( const PropertyOwner& propertyOwner,
385                             const PropertyBase& property,
386                             AnimatorFunctionBase* animatorFunction,
387                             AlphaFunction alphaFunction,
388                             const TimePeriod& timePeriod )
389   {
390     typedef Animator< PropertyType, PropertyAccessorType > AnimatorType;
391
392     // The property was const in the actor-thread, but animators are used in the scene-graph thread.
393     AnimatorType* animator = new AnimatorType( const_cast<PropertyOwner*>( &propertyOwner ),
394                                                const_cast<PropertyBase*>( &property ),
395                                                animatorFunction );
396
397     animator->SetAlphaFunction( alphaFunction );
398     animator->SetInitialDelay( timePeriod.delaySeconds );
399     animator->SetDuration( timePeriod.durationSeconds );
400
401     return animator;
402   }
403
404   /**
405    * Virtual destructor.
406    */
407   virtual ~Animator()
408   {
409     if (mPropertyOwner && mConnectedToSceneGraph)
410     {
411       mPropertyOwner->RemoveObserver(*this);
412     }
413
414     if( mAnimatorFunction )
415     {
416       delete mAnimatorFunction;
417     }
418   }
419
420   /**
421    * Called when Animator is added to the scene-graph in update-thread.
422    */
423   virtual void ConnectToSceneGraph()
424   {
425     mConnectedToSceneGraph = true;
426     mPropertyOwner->AddObserver(*this);
427   }
428
429   /**
430    * Called when mPropertyOwner is connected to the scene graph.
431    */
432   virtual void PropertyOwnerConnected( PropertyOwner& owner )
433   {
434     mEnabled = true;
435   }
436
437   /**
438    * Called when mPropertyOwner is disconnected from the scene graph.
439    */
440   virtual void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner )
441   {
442     // If we are active, then bake the value if required
443     if ( mActive && mDisconnectAction != Dali::Animation::Discard )
444     {
445       // Bake to target-value if BakeFinal, otherwise bake current value
446       Update( bufferIndex, ( mDisconnectAction == Dali::Animation::Bake ? mCurrentProgress : 1.0f ), true );
447     }
448
449     mActive = false;
450     mEnabled = false;
451   }
452
453   /**
454    * Called shortly before mPropertyOwner is destroyed
455    */
456   virtual void PropertyOwnerDestroyed( PropertyOwner& owner )
457   {
458     mPropertyOwner = NULL;
459     mPropertyAccessor.Reset();
460     mEnabled = false;
461   }
462
463   /**
464    * From AnimatorBase.
465    */
466   virtual void Update( BufferIndex bufferIndex, float progress, bool bake )
467   {
468     float alpha = ApplyAlphaFunction(progress);
469
470     const PropertyType& current = mPropertyAccessor.Get( bufferIndex );
471
472     const PropertyType result = (*mAnimatorFunction)( alpha, current );
473     if ( bake )
474     {
475       mPropertyAccessor.Bake( bufferIndex, result );
476     }
477     else
478     {
479       mPropertyAccessor.Set( bufferIndex, result );
480     }
481
482     mCurrentProgress = progress;
483   }
484
485   /**
486    * From AnimatorBase.
487    */
488   virtual bool Orphan()
489   {
490     return (mPropertyOwner == NULL);
491   }
492
493 private:
494
495   /**
496    * Private constructor; see also Animator::New().
497    */
498   Animator( PropertyOwner* propertyOwner,
499             PropertyBase* property,
500             AnimatorFunctionBase* animatorFunction )
501   : mPropertyOwner( propertyOwner ),
502     mPropertyAccessor( property ),
503     mAnimatorFunction( animatorFunction ),
504     mCurrentProgress( 0.0f )
505   {
506     // WARNING - this object is created in the event-thread
507     // The scene-graph mPropertyOwner object cannot be observed here
508   }
509
510   // Undefined
511   Animator( const Animator& );
512
513   // Undefined
514   Animator& operator=( const Animator& );
515
516 protected:
517
518   PropertyOwner* mPropertyOwner;
519   PropertyAccessorType mPropertyAccessor;
520
521   AnimatorFunctionBase* mAnimatorFunction;
522   float mCurrentProgress;
523 };
524
525 } // namespace SceneGraph
526
527 /*
528  * AnimatorFunction base class.
529  * All update functions must inherit from AnimatorFunctionBase and overload the appropiate "()" operator
530  */
531 struct AnimatorFunctionBase
532 {
533   /**
534    * Constructor
535    */
536   AnimatorFunctionBase(){}
537
538   /*
539    * Virtual destructor (Intended as base class)
540    */
541   virtual ~AnimatorFunctionBase(){}
542
543   ///Stub "()" operators.
544   virtual bool operator()(float progress, const bool& property)
545   {
546     return property;
547   }
548
549   virtual float operator()(float progress, const int& property)
550   {
551     return property;
552   }
553
554   virtual float operator()(float progress, const unsigned int& property)
555   {
556     return property;
557   }
558
559   virtual float operator()(float progress, const float& property)
560   {
561     return property;
562   }
563
564   virtual Vector2 operator()(float progress, const Vector2& property)
565   {
566     return property;
567   }
568
569   virtual Vector3 operator()(float progress, const Vector3& property)
570   {
571     return property;
572   }
573
574   virtual Vector4 operator()(float progress, const Vector4& property)
575   {
576     return property;
577   }
578
579   virtual Quaternion operator()(float progress, const Quaternion& property)
580   {
581     return property;
582   }
583 };
584
585 // Update functions
586
587 struct AnimateByInteger : public AnimatorFunctionBase
588 {
589   AnimateByInteger(const int& relativeValue)
590   : mRelative(relativeValue)
591   {
592   }
593
594   float operator()(float alpha, const int& property)
595   {
596     return int(property + mRelative * alpha + 0.5f );
597   }
598
599   int mRelative;
600 };
601
602 struct AnimateToInteger : public AnimatorFunctionBase
603 {
604   AnimateToInteger(const int& targetValue)
605   : mTarget(targetValue)
606   {
607   }
608
609   float operator()(float alpha, const int& property)
610   {
611     return int(property + ((mTarget - property) * alpha) + 0.5f);
612   }
613
614   int mTarget;
615 };
616
617 struct AnimateByFloat : public AnimatorFunctionBase
618 {
619   AnimateByFloat(const float& relativeValue)
620   : mRelative(relativeValue)
621   {
622   }
623
624   float operator()(float alpha, const float& property)
625   {
626     return float(property + mRelative * alpha);
627   }
628
629   float mRelative;
630 };
631
632 struct AnimateToFloat : public AnimatorFunctionBase
633 {
634   AnimateToFloat(const float& targetValue)
635   : mTarget(targetValue)
636   {
637   }
638
639   float operator()(float alpha, const float& property)
640   {
641     return float(property + ((mTarget - property) * alpha));
642   }
643
644   float mTarget;
645 };
646
647 struct AnimateByVector2 : public AnimatorFunctionBase
648 {
649   AnimateByVector2(const Vector2& relativeValue)
650   : mRelative(relativeValue)
651   {
652   }
653
654   Vector2 operator()(float alpha, const Vector2& property)
655   {
656     return Vector2(property + mRelative * alpha);
657   }
658
659   Vector2 mRelative;
660 };
661
662 struct AnimateToVector2 : public AnimatorFunctionBase
663 {
664   AnimateToVector2(const Vector2& targetValue)
665   : mTarget(targetValue)
666   {
667   }
668
669   Vector2 operator()(float alpha, const Vector2& property)
670   {
671     return Vector2(property + ((mTarget - property) * alpha));
672   }
673
674   Vector2 mTarget;
675 };
676
677 struct AnimateByVector3 : public AnimatorFunctionBase
678 {
679   AnimateByVector3(const Vector3& relativeValue)
680   : mRelative(relativeValue)
681   {
682   }
683
684   Vector3 operator()(float alpha, const Vector3& property)
685   {
686     return Vector3(property + mRelative * alpha);
687   }
688
689   Vector3 mRelative;
690 };
691
692 struct AnimateToVector3 : public AnimatorFunctionBase
693 {
694   AnimateToVector3(const Vector3& targetValue)
695   : mTarget(targetValue)
696   {
697   }
698
699   Vector3 operator()(float alpha, const Vector3& property)
700   {
701     return Vector3(property + ((mTarget - property) * alpha));
702   }
703
704   Vector3 mTarget;
705 };
706
707 struct AnimateByVector4 : public AnimatorFunctionBase
708 {
709   AnimateByVector4(const Vector4& relativeValue)
710   : mRelative(relativeValue)
711   {
712   }
713
714   Vector4 operator()(float alpha, const Vector4& property)
715   {
716     return Vector4(property + mRelative * alpha);
717   }
718
719   Vector4 mRelative;
720 };
721
722 struct AnimateToVector4 : public AnimatorFunctionBase
723 {
724   AnimateToVector4(const Vector4& targetValue)
725   : mTarget(targetValue)
726   {
727   }
728
729   Vector4 operator()(float alpha, const Vector4& property)
730   {
731     return Vector4(property + ((mTarget - property) * alpha));
732   }
733
734   Vector4 mTarget;
735 };
736
737 struct AnimateByOpacity : public AnimatorFunctionBase
738 {
739   AnimateByOpacity(const float& relativeValue)
740   : mRelative(relativeValue)
741   {
742   }
743
744   Vector4 operator()(float alpha, const Vector4& property)
745   {
746     Vector4 result(property);
747     result.a += mRelative * alpha;
748
749     return result;
750   }
751
752   float mRelative;
753 };
754
755 struct AnimateToOpacity : public AnimatorFunctionBase
756 {
757   AnimateToOpacity(const float& targetValue)
758   : mTarget(targetValue)
759   {
760   }
761
762   Vector4 operator()(float alpha, const Vector4& property)
763   {
764     Vector4 result(property);
765     result.a = property.a + ((mTarget - property.a) * alpha);
766
767     return result;
768   }
769
770   float mTarget;
771 };
772
773 struct AnimateByBoolean : public AnimatorFunctionBase
774 {
775   AnimateByBoolean(bool relativeValue)
776   : mRelative(relativeValue)
777   {
778   }
779
780   bool operator()(float alpha, const bool& property)
781   {
782     // Alpha is not useful here, just keeping to the same template as other update functors
783     return bool(alpha >= 1.0f ? (property || mRelative) : property);
784   }
785
786   bool mRelative;
787 };
788
789 struct AnimateToBoolean : public AnimatorFunctionBase
790 {
791   AnimateToBoolean(bool targetValue)
792   : mTarget(targetValue)
793   {
794   }
795
796   bool operator()(float alpha, const bool& property)
797   {
798     // Alpha is not useful here, just keeping to the same template as other update functors
799     return bool(alpha >= 1.0f ? mTarget : property);
800   }
801
802   bool mTarget;
803 };
804
805 struct RotateByAngleAxis : public AnimatorFunctionBase
806 {
807   RotateByAngleAxis(const Radian& angleRadians, const Vector3& axis)
808   : mAngleRadians( angleRadians ),
809     mAxis(axis.x, axis.y, axis.z)
810   {
811   }
812
813   Quaternion operator()(float alpha, const Quaternion& rotation)
814   {
815     if (alpha > 0.0f)
816     {
817       return rotation * Quaternion(mAngleRadians * alpha, mAxis);
818     }
819
820     return rotation;
821   }
822
823   Radian mAngleRadians;
824   Vector3 mAxis;
825 };
826
827 struct RotateToQuaternion : public AnimatorFunctionBase
828 {
829   RotateToQuaternion(const Quaternion& targetValue)
830   : mTarget(targetValue)
831   {
832   }
833
834   Quaternion operator()(float alpha, const Quaternion& rotation)
835   {
836     return Quaternion::Slerp(rotation, mTarget, alpha);
837   }
838
839   Quaternion mTarget;
840 };
841
842
843 struct KeyFrameBooleanFunctor : public AnimatorFunctionBase
844 {
845   KeyFrameBooleanFunctor(KeyFrameBooleanPtr keyFrames)
846   : mKeyFrames(keyFrames)
847   {
848   }
849
850   bool operator()(float progress, const bool& property)
851   {
852     if(mKeyFrames->IsActive(progress))
853     {
854       return mKeyFrames->GetValue(progress, Dali::Animation::Linear);
855     }
856     return property;
857   }
858
859   KeyFrameBooleanPtr mKeyFrames;
860 };
861
862 struct KeyFrameIntegerFunctor : public AnimatorFunctionBase
863 {
864   KeyFrameIntegerFunctor(KeyFrameIntegerPtr keyFrames, Interpolation interpolation)
865   : mKeyFrames(keyFrames),mInterpolation(interpolation)
866   {
867   }
868
869   float operator()(float progress, const int& property)
870   {
871     if(mKeyFrames->IsActive(progress))
872     {
873       return mKeyFrames->GetValue(progress, mInterpolation);
874     }
875     return property;
876   }
877
878   KeyFrameIntegerPtr mKeyFrames;
879   Interpolation mInterpolation;
880 };
881
882 struct KeyFrameNumberFunctor : public AnimatorFunctionBase
883 {
884   KeyFrameNumberFunctor(KeyFrameNumberPtr keyFrames, Interpolation interpolation)
885   : mKeyFrames(keyFrames),mInterpolation(interpolation)
886   {
887   }
888
889   float operator()(float progress, const float& property)
890   {
891     if(mKeyFrames->IsActive(progress))
892     {
893       return mKeyFrames->GetValue(progress, mInterpolation);
894     }
895     return property;
896   }
897
898   KeyFrameNumberPtr mKeyFrames;
899   Interpolation mInterpolation;
900 };
901
902 struct KeyFrameVector2Functor : public AnimatorFunctionBase
903 {
904   KeyFrameVector2Functor(KeyFrameVector2Ptr keyFrames, Interpolation interpolation)
905   : mKeyFrames(keyFrames),mInterpolation(interpolation)
906   {
907   }
908
909   Vector2 operator()(float progress, const Vector2& property)
910   {
911     if(mKeyFrames->IsActive(progress))
912     {
913       return mKeyFrames->GetValue(progress, mInterpolation);
914     }
915     return property;
916   }
917
918   KeyFrameVector2Ptr mKeyFrames;
919   Interpolation mInterpolation;
920 };
921
922
923 struct KeyFrameVector3Functor : public AnimatorFunctionBase
924 {
925   KeyFrameVector3Functor(KeyFrameVector3Ptr keyFrames, Interpolation interpolation)
926   : mKeyFrames(keyFrames),mInterpolation(interpolation)
927   {
928   }
929
930   Vector3 operator()(float progress, const Vector3& property)
931   {
932     if(mKeyFrames->IsActive(progress))
933     {
934       return mKeyFrames->GetValue(progress, mInterpolation);
935     }
936     return property;
937   }
938
939   KeyFrameVector3Ptr mKeyFrames;
940   Interpolation mInterpolation;
941 };
942
943 struct KeyFrameVector4Functor : public AnimatorFunctionBase
944 {
945   KeyFrameVector4Functor(KeyFrameVector4Ptr keyFrames, Interpolation interpolation)
946   : mKeyFrames(keyFrames),mInterpolation(interpolation)
947   {
948   }
949
950   Vector4 operator()(float progress, const Vector4& property)
951   {
952     if(mKeyFrames->IsActive(progress))
953     {
954       return mKeyFrames->GetValue(progress, mInterpolation);
955     }
956     return property;
957   }
958
959   KeyFrameVector4Ptr mKeyFrames;
960   Interpolation mInterpolation;
961 };
962
963 struct KeyFrameQuaternionFunctor : public AnimatorFunctionBase
964 {
965   KeyFrameQuaternionFunctor(KeyFrameQuaternionPtr keyFrames)
966   : mKeyFrames(keyFrames)
967   {
968   }
969
970   Quaternion operator()(float progress, const Quaternion& property)
971   {
972     if(mKeyFrames->IsActive(progress))
973     {
974       return mKeyFrames->GetValue(progress, Dali::Animation::Linear);
975     }
976     return property;
977   }
978
979   KeyFrameQuaternionPtr mKeyFrames;
980 };
981
982 struct PathPositionFunctor : public AnimatorFunctionBase
983 {
984   PathPositionFunctor( PathPtr path )
985   : mPath(path)
986   {
987   }
988
989   Vector3 operator()(float progress, const Vector3& property)
990   {
991     return mPath->SamplePosition(progress );
992   }
993
994   PathPtr mPath;
995 };
996
997 struct PathRotationFunctor : public AnimatorFunctionBase
998 {
999   PathRotationFunctor( PathPtr path, const Vector3& forward )
1000   : mPath(path),
1001     mForward( forward )
1002   {
1003     mForward.Normalize();
1004   }
1005
1006   Quaternion operator()(float progress, const Quaternion& property)
1007   {
1008     Vector3 tangent( mPath->SampleTangent(progress) );
1009     return Quaternion( mForward, tangent );
1010   }
1011
1012   PathPtr mPath;
1013   Vector3 mForward;
1014 };
1015
1016
1017 } // namespace Internal
1018
1019 } // namespace Dali
1020
1021 #endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H__