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