[dali_1.0.40] Merge branch 'tizen'
[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 AnimateByUnsignedInteger : public AnimatorFunctionBase
599 {
600   AnimateByUnsignedInteger(const unsigned int& relativeValue)
601   : mRelative(relativeValue)
602   {
603   }
604
605   float operator()(float alpha, const unsigned int& property)
606   {
607     return static_cast<unsigned int>(property + mRelative * alpha + 0.5f );
608   }
609
610   unsigned int mRelative;
611 };
612
613 struct AnimateToUnsignedInteger : public AnimatorFunctionBase
614 {
615   AnimateToUnsignedInteger(const unsigned int& targetValue)
616   : mTarget(targetValue)
617   {
618   }
619
620   float operator()(float alpha, const unsigned int& property)
621   {
622     return static_cast<unsigned int>(property + ((mTarget - property) * alpha) + 0.5f);
623   }
624
625   unsigned int mTarget;
626 };
627
628 struct AnimateByFloat : public AnimatorFunctionBase
629 {
630   AnimateByFloat(const float& relativeValue)
631   : mRelative(relativeValue)
632   {
633   }
634
635   float operator()(float alpha, const float& property)
636   {
637     return float(property + mRelative * alpha);
638   }
639
640   float mRelative;
641 };
642
643 struct AnimateToFloat : public AnimatorFunctionBase
644 {
645   AnimateToFloat(const float& targetValue)
646   : mTarget(targetValue)
647   {
648   }
649
650   float operator()(float alpha, const float& property)
651   {
652     return float(property + ((mTarget - property) * alpha));
653   }
654
655   float mTarget;
656 };
657
658 struct AnimateByVector2 : public AnimatorFunctionBase
659 {
660   AnimateByVector2(const Vector2& relativeValue)
661   : mRelative(relativeValue)
662   {
663   }
664
665   Vector2 operator()(float alpha, const Vector2& property)
666   {
667     return Vector2(property + mRelative * alpha);
668   }
669
670   Vector2 mRelative;
671 };
672
673 struct AnimateToVector2 : public AnimatorFunctionBase
674 {
675   AnimateToVector2(const Vector2& targetValue)
676   : mTarget(targetValue)
677   {
678   }
679
680   Vector2 operator()(float alpha, const Vector2& property)
681   {
682     return Vector2(property + ((mTarget - property) * alpha));
683   }
684
685   Vector2 mTarget;
686 };
687
688 struct AnimateByVector3 : public AnimatorFunctionBase
689 {
690   AnimateByVector3(const Vector3& relativeValue)
691   : mRelative(relativeValue)
692   {
693   }
694
695   Vector3 operator()(float alpha, const Vector3& property)
696   {
697     return Vector3(property + mRelative * alpha);
698   }
699
700   Vector3 mRelative;
701 };
702
703 struct AnimateToVector3 : public AnimatorFunctionBase
704 {
705   AnimateToVector3(const Vector3& targetValue)
706   : mTarget(targetValue)
707   {
708   }
709
710   Vector3 operator()(float alpha, const Vector3& property)
711   {
712     return Vector3(property + ((mTarget - property) * alpha));
713   }
714
715   Vector3 mTarget;
716 };
717
718 struct AnimateByVector4 : public AnimatorFunctionBase
719 {
720   AnimateByVector4(const Vector4& relativeValue)
721   : mRelative(relativeValue)
722   {
723   }
724
725   Vector4 operator()(float alpha, const Vector4& property)
726   {
727     return Vector4(property + mRelative * alpha);
728   }
729
730   Vector4 mRelative;
731 };
732
733 struct AnimateToVector4 : public AnimatorFunctionBase
734 {
735   AnimateToVector4(const Vector4& targetValue)
736   : mTarget(targetValue)
737   {
738   }
739
740   Vector4 operator()(float alpha, const Vector4& property)
741   {
742     return Vector4(property + ((mTarget - property) * alpha));
743   }
744
745   Vector4 mTarget;
746 };
747
748 struct AnimateByOpacity : public AnimatorFunctionBase
749 {
750   AnimateByOpacity(const float& relativeValue)
751   : mRelative(relativeValue)
752   {
753   }
754
755   Vector4 operator()(float alpha, const Vector4& property)
756   {
757     Vector4 result(property);
758     result.a += mRelative * alpha;
759
760     return result;
761   }
762
763   float mRelative;
764 };
765
766 struct AnimateToOpacity : public AnimatorFunctionBase
767 {
768   AnimateToOpacity(const float& targetValue)
769   : mTarget(targetValue)
770   {
771   }
772
773   Vector4 operator()(float alpha, const Vector4& property)
774   {
775     Vector4 result(property);
776     result.a = property.a + ((mTarget - property.a) * alpha);
777
778     return result;
779   }
780
781   float mTarget;
782 };
783
784 struct AnimateByBoolean : public AnimatorFunctionBase
785 {
786   AnimateByBoolean(bool relativeValue)
787   : mRelative(relativeValue)
788   {
789   }
790
791   bool operator()(float alpha, const bool& property)
792   {
793     // Alpha is not useful here, just keeping to the same template as other update functors
794     return bool(alpha >= 1.0f ? (property || mRelative) : property);
795   }
796
797   bool mRelative;
798 };
799
800 struct AnimateToBoolean : public AnimatorFunctionBase
801 {
802   AnimateToBoolean(bool targetValue)
803   : mTarget(targetValue)
804   {
805   }
806
807   bool operator()(float alpha, const bool& property)
808   {
809     // Alpha is not useful here, just keeping to the same template as other update functors
810     return bool(alpha >= 1.0f ? mTarget : property);
811   }
812
813   bool mTarget;
814 };
815
816 struct RotateByAngleAxis : public AnimatorFunctionBase
817 {
818   RotateByAngleAxis(const Radian& angleRadians, const Vector3& axis)
819   : mAngleRadians( angleRadians ),
820     mAxis(axis.x, axis.y, axis.z)
821   {
822   }
823
824   Quaternion operator()(float alpha, const Quaternion& rotation)
825   {
826     if (alpha > 0.0f)
827     {
828       return rotation * Quaternion(mAngleRadians * alpha, mAxis);
829     }
830
831     return rotation;
832   }
833
834   Radian mAngleRadians;
835   Vector3 mAxis;
836 };
837
838 struct RotateToQuaternion : public AnimatorFunctionBase
839 {
840   RotateToQuaternion(const Quaternion& targetValue)
841   : mTarget(targetValue)
842   {
843   }
844
845   Quaternion operator()(float alpha, const Quaternion& rotation)
846   {
847     return Quaternion::Slerp(rotation, mTarget, alpha);
848   }
849
850   Quaternion mTarget;
851 };
852
853
854 struct KeyFrameBooleanFunctor : public AnimatorFunctionBase
855 {
856   KeyFrameBooleanFunctor(KeyFrameBooleanPtr keyFrames)
857   : mKeyFrames(keyFrames)
858   {
859   }
860
861   bool operator()(float progress, const bool& property)
862   {
863     if(mKeyFrames->IsActive(progress))
864     {
865       return mKeyFrames->GetValue(progress, Dali::Animation::Linear);
866     }
867     return property;
868   }
869
870   KeyFrameBooleanPtr mKeyFrames;
871 };
872
873 struct KeyFrameIntegerFunctor : public AnimatorFunctionBase
874 {
875   KeyFrameIntegerFunctor(KeyFrameIntegerPtr keyFrames, Interpolation interpolation)
876   : mKeyFrames(keyFrames),mInterpolation(interpolation)
877   {
878   }
879
880   float operator()(float progress, const int& property)
881   {
882     if(mKeyFrames->IsActive(progress))
883     {
884       return mKeyFrames->GetValue(progress, mInterpolation);
885     }
886     return property;
887   }
888
889   KeyFrameIntegerPtr mKeyFrames;
890   Interpolation mInterpolation;
891 };
892
893 struct KeyFrameUnsignedIntegerFunctor : public AnimatorFunctionBase
894 {
895   KeyFrameUnsignedIntegerFunctor(KeyFrameUnsignedIntegerPtr keyFrames, Interpolation interpolation)
896   : mKeyFrames(keyFrames),mInterpolation(interpolation)
897   {
898   }
899
900   float operator()(float progress, const unsigned int& property)
901   {
902     if(mKeyFrames->IsActive(progress))
903     {
904       return mKeyFrames->GetValue(progress, mInterpolation);
905     }
906     return property;
907   }
908
909   KeyFrameUnsignedIntegerPtr mKeyFrames;
910   Interpolation mInterpolation;
911 };
912
913 struct KeyFrameNumberFunctor : public AnimatorFunctionBase
914 {
915   KeyFrameNumberFunctor(KeyFrameNumberPtr keyFrames, Interpolation interpolation)
916   : mKeyFrames(keyFrames),mInterpolation(interpolation)
917   {
918   }
919
920   float operator()(float progress, const float& property)
921   {
922     if(mKeyFrames->IsActive(progress))
923     {
924       return mKeyFrames->GetValue(progress, mInterpolation);
925     }
926     return property;
927   }
928
929   KeyFrameNumberPtr mKeyFrames;
930   Interpolation mInterpolation;
931 };
932
933 struct KeyFrameVector2Functor : public AnimatorFunctionBase
934 {
935   KeyFrameVector2Functor(KeyFrameVector2Ptr keyFrames, Interpolation interpolation)
936   : mKeyFrames(keyFrames),mInterpolation(interpolation)
937   {
938   }
939
940   Vector2 operator()(float progress, const Vector2& property)
941   {
942     if(mKeyFrames->IsActive(progress))
943     {
944       return mKeyFrames->GetValue(progress, mInterpolation);
945     }
946     return property;
947   }
948
949   KeyFrameVector2Ptr mKeyFrames;
950   Interpolation mInterpolation;
951 };
952
953
954 struct KeyFrameVector3Functor : public AnimatorFunctionBase
955 {
956   KeyFrameVector3Functor(KeyFrameVector3Ptr keyFrames, Interpolation interpolation)
957   : mKeyFrames(keyFrames),mInterpolation(interpolation)
958   {
959   }
960
961   Vector3 operator()(float progress, const Vector3& property)
962   {
963     if(mKeyFrames->IsActive(progress))
964     {
965       return mKeyFrames->GetValue(progress, mInterpolation);
966     }
967     return property;
968   }
969
970   KeyFrameVector3Ptr mKeyFrames;
971   Interpolation mInterpolation;
972 };
973
974 struct KeyFrameVector4Functor : public AnimatorFunctionBase
975 {
976   KeyFrameVector4Functor(KeyFrameVector4Ptr keyFrames, Interpolation interpolation)
977   : mKeyFrames(keyFrames),mInterpolation(interpolation)
978   {
979   }
980
981   Vector4 operator()(float progress, const Vector4& property)
982   {
983     if(mKeyFrames->IsActive(progress))
984     {
985       return mKeyFrames->GetValue(progress, mInterpolation);
986     }
987     return property;
988   }
989
990   KeyFrameVector4Ptr mKeyFrames;
991   Interpolation mInterpolation;
992 };
993
994 struct KeyFrameQuaternionFunctor : public AnimatorFunctionBase
995 {
996   KeyFrameQuaternionFunctor(KeyFrameQuaternionPtr keyFrames)
997   : mKeyFrames(keyFrames)
998   {
999   }
1000
1001   Quaternion operator()(float progress, const Quaternion& property)
1002   {
1003     if(mKeyFrames->IsActive(progress))
1004     {
1005       return mKeyFrames->GetValue(progress, Dali::Animation::Linear);
1006     }
1007     return property;
1008   }
1009
1010   KeyFrameQuaternionPtr mKeyFrames;
1011 };
1012
1013 struct PathPositionFunctor : public AnimatorFunctionBase
1014 {
1015   PathPositionFunctor( PathPtr path )
1016   : mPath(path)
1017   {
1018   }
1019
1020   Vector3 operator()(float progress, const Vector3& property)
1021   {
1022     return mPath->SamplePosition(progress );
1023   }
1024
1025   PathPtr mPath;
1026 };
1027
1028 struct PathRotationFunctor : public AnimatorFunctionBase
1029 {
1030   PathRotationFunctor( PathPtr path, const Vector3& forward )
1031   : mPath(path),
1032     mForward( forward )
1033   {
1034     mForward.Normalize();
1035   }
1036
1037   Quaternion operator()(float progress, const Quaternion& property)
1038   {
1039     Vector3 tangent( mPath->SampleTangent(progress) );
1040     return Quaternion( mForward, tangent );
1041   }
1042
1043   PathPtr mPath;
1044   Vector3 mForward;
1045 };
1046
1047
1048 } // namespace Internal
1049
1050 } // namespace Dali
1051
1052 #endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H__