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