19d4ecccc1f7a141431608ae3ac8d1a82a18e905
[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) 2017 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 #include <dali/internal/update/animation/property-accessor.h>
35 #include <dali/integration-api/debug.h>
36
37 namespace Dali
38 {
39
40 namespace Internal
41 {
42
43 typedef Dali::Animation::Interpolation Interpolation;
44
45 struct AnimatorFunctionBase;
46
47 namespace SceneGraph
48 {
49
50 class AnimatorBase;
51
52 typedef OwnerContainer< AnimatorBase* > AnimatorContainer;
53
54 typedef AnimatorContainer::Iterator AnimatorIter;
55 typedef AnimatorContainer::ConstIterator AnimatorConstIter;
56
57 /**
58  * An abstract base class for Animators, which can be added to scene graph animations.
59  * Each animator changes a single property of an object in the scene graph.
60  */
61 class AnimatorBase
62 {
63 public:
64
65   typedef float (*AlphaFunc)(float progress); ///< Definition of an alpha function
66
67   /**
68    * Constructor.
69    */
70   AnimatorBase()
71   : mDurationSeconds(1.0f),
72     mIntervalDelaySeconds(0.0f),
73     mSpeedFactor(1.0f),
74     mLoopCount(1),
75     mAlphaFunction(AlphaFunction::DEFAULT),
76     mDisconnectAction(Dali::Animation::BakeFinal),
77     mActive(false),
78     mEnabled(true),
79     mConnectedToSceneGraph(false),
80     mAutoReverseEnabled( false )
81   {
82   }
83
84   /**
85    * Virtual destructor.
86    */
87   virtual ~AnimatorBase()
88   {
89   }
90
91   /**
92    * Called when Animator is added to the scene-graph in update-thread.
93    */
94   virtual void ConnectToSceneGraph() = 0;
95
96   /**
97    * Set the duration of the animator.
98    * @pre durationSeconds must be zero or greater; zero is useful when animating boolean values.
99    * @param [in] seconds Duration in seconds.
100    */
101   void SetDuration(float seconds)
102   {
103     DALI_ASSERT_DEBUG(seconds >= 0.0f);
104
105     mDurationSeconds = seconds;
106   }
107
108   /**
109    * Retrieve the duration of the animator.
110    * @return The duration in seconds.
111    */
112   float GetDuration() const
113   {
114     return mDurationSeconds;
115   }
116
117   void SetSpeedFactor( float factor )
118   {
119     mSpeedFactor = factor;
120   }
121
122   void SetLoopCount(int loopCount)
123   {
124     mLoopCount = loopCount;
125   }
126
127   float SetProgress( float progress )
128   {
129     float value = 0.0f;
130
131     if( mAutoReverseEnabled )
132     {
133       if( mSpeedFactor > 0.0f )
134       {
135         value = 1.0f - 2.0f * std::abs( progress - 0.5f );
136       }
137       // Reverse mode
138       else if( mSpeedFactor < 0.0f )
139       {
140         value = 2.0f * std::abs( progress - 0.5f );
141       }
142     }
143
144     return value;
145   }
146
147   /**
148    * Set the delay before the animator should take effect.
149    * The default is zero i.e. no delay.
150    * @param [in] seconds The delay in seconds.
151    */
152   void SetIntervalDelay(float seconds)
153   {
154     mIntervalDelaySeconds = seconds;
155   }
156
157   /**
158    * Retrieve the delay before the animator should take effect.
159    * @return The delay in seconds.
160    */
161   float GetIntervalDelay() const
162   {
163     return mIntervalDelaySeconds;
164   }
165
166   /**
167    * Set the alpha function for an animator.
168    * @param [in] alphaFunc The alpha function to apply to the animation progress.
169    */
170   void SetAlphaFunction(const AlphaFunction& alphaFunction)
171   {
172     mAlphaFunction = alphaFunction;
173   }
174
175   /**
176    * Retrieve the alpha function of an animator.
177    * @return The function.
178    */
179   AlphaFunction GetAlphaFunction() const
180   {
181     return mAlphaFunction;
182   }
183
184   /**
185    * Applies the alpha function to the specified progress
186    * @param[in] Current progress
187    * @return The progress after the alpha function has been aplied
188    */
189   float ApplyAlphaFunction( float progress ) const
190   {
191     float result = progress;
192
193     AlphaFunction::Mode alphaFunctionMode( mAlphaFunction.GetMode() );
194     if( alphaFunctionMode == AlphaFunction::BUILTIN_FUNCTION )
195     {
196       switch(mAlphaFunction.GetBuiltinFunction())
197       {
198         case AlphaFunction::DEFAULT:
199         case AlphaFunction::LINEAR:
200         {
201           break;
202         }
203         case AlphaFunction::REVERSE:
204         {
205           result = 1.0f-progress;
206           break;
207         }
208         case AlphaFunction::EASE_IN_SQUARE:
209         {
210           result = progress * progress;
211           break;
212         }
213         case AlphaFunction::EASE_OUT_SQUARE:
214         {
215           result = 1.0f - (1.0f-progress) * (1.0f-progress);
216           break;
217         }
218         case AlphaFunction::EASE_IN:
219         {
220           result = progress * progress * progress;
221           break;
222         }
223         case AlphaFunction::EASE_OUT:
224         {
225           result = (progress-1.0f) * (progress-1.0f) * (progress-1.0f) + 1.0f;
226           break;
227         }
228         case AlphaFunction::EASE_IN_OUT:
229         {
230           result = progress*progress*(3.0f-2.0f*progress);
231           break;
232         }
233         case AlphaFunction::EASE_IN_SINE:
234         {
235           result = -1.0f * cosf(progress * Math::PI_2) + 1.0f;
236           break;
237         }
238         case AlphaFunction::EASE_OUT_SINE:
239         {
240           result = sinf(progress * Math::PI_2);
241           break;
242         }
243         case AlphaFunction::EASE_IN_OUT_SINE:
244         {
245           result = -0.5f * (cosf(Math::PI * progress) - 1.0f);
246           break;
247         }
248         case AlphaFunction::BOUNCE:
249         {
250           result = sinf(progress * Math::PI);
251           break;
252         }
253         case AlphaFunction::SIN:
254         {
255           result = 0.5f - cosf(progress * 2.0f * Math::PI) * 0.5f;
256           break;
257         }
258         case AlphaFunction::EASE_OUT_BACK:
259         {
260           const float sqrt2 = 1.70158f;
261           progress -= 1.0f;
262           result = 1.0f + progress * progress * ( ( sqrt2 + 1.0f ) * progress + sqrt2 );
263           break;
264         }
265         case AlphaFunction::COUNT:
266         {
267           break;
268         }
269       }
270     }
271     else if(  alphaFunctionMode == AlphaFunction::CUSTOM_FUNCTION )
272     {
273       AlphaFunctionPrototype customFunction = mAlphaFunction.GetCustomFunction();
274       if( customFunction )
275       {
276         result = customFunction(progress);
277       }
278     }
279     else
280     {
281       //If progress is very close to 0 or very close to 1 we don't need to evaluate the curve as the result will
282       //be almost 0 or almost 1 respectively
283       if( ( progress > Math::MACHINE_EPSILON_1 ) && ((1.0f - progress) > Math::MACHINE_EPSILON_1) )
284       {
285         Dali::Vector4 controlPoints = mAlphaFunction.GetBezierControlPoints();
286
287         static const float tolerance = 0.001f;  //10 iteration max
288
289         //Perform a binary search on the curve
290         float lowerBound(0.0f);
291         float upperBound(1.0f);
292         float currentT(0.5f);
293         float currentX = EvaluateCubicBezier( controlPoints.x, controlPoints.z, currentT);
294         while( fabs( progress - currentX ) > tolerance )
295         {
296           if( progress > currentX )
297           {
298             lowerBound = currentT;
299           }
300           else
301           {
302             upperBound = currentT;
303           }
304           currentT = (upperBound+lowerBound)*0.5f;
305           currentX = EvaluateCubicBezier( controlPoints.x, controlPoints.z, currentT);
306         }
307         result = EvaluateCubicBezier( controlPoints.y, controlPoints.w, currentT);
308       }
309     }
310
311     return result;
312   }
313
314   /**
315    * Whether to bake the animation if attached property owner is disconnected.
316    * Property is only baked if the animator is active.
317    * @param [in] action The disconnect action.
318    */
319   void SetDisconnectAction( Dali::Animation::EndAction action )
320   {
321     mDisconnectAction = action;
322   }
323
324   /**
325    * Retrieve the disconnect action of an animator.
326    * @return The disconnect action.
327    */
328   Dali::Animation::EndAction GetDisconnectAction() const
329   {
330     return mDisconnectAction;
331   }
332
333   /**
334    * Whether the animator is active or not.
335    * @param [in] active The new active state.
336    * @post When the animator becomes active, it applies the disconnect-action if the property owner is then disconnected.
337    * @note When the property owner is disconnected, the active state is set to false.
338    */
339   void SetActive( bool active )
340   {
341     mActive = active;
342   }
343
344   /**
345    * Retrieve whether the animator has been set to active or not.
346    * @return The active state.
347    */
348   bool GetActive() const
349   {
350     return mActive;
351   }
352
353   /**
354    * Retrive wheter the animator's target object is valid and on the stage.
355    * @return The enabled state.
356    */
357   bool IsEnabled() const
358   {
359     return mEnabled;
360   }
361
362   /**
363    * @brief Sets the looping mode.
364    * @param[in] loopingMode True when the looping mode is AUTO_REVERSE
365    */
366   void SetLoopingMode( bool loopingMode )
367   {
368     mAutoReverseEnabled = loopingMode;
369   }
370
371   /**
372    * Returns wheter the target object of the animator is still valid
373    * or has been destroyed.
374    * @return True if animator is orphan, false otherwise   *
375    * @note The SceneGraph::Animation will delete any orphan animator in its Update method.
376    */
377   virtual bool Orphan() = 0;
378
379   /**
380    * Update the scene object attached to the animator.
381    * @param[in] bufferIndex The buffer to animate.
382    * @param[in] progress A value from 0 to 1, where 0 is the start of the animation, and 1 is the end point.
383    * @param[in] bake Bake.
384    */
385   virtual void Update(BufferIndex bufferIndex, float progress, bool bake) = 0;
386
387 protected:
388
389   /**
390    * Helper function to evaluate a cubic bezier curve assuming first point is at 0.0 and last point is at 1.0
391    * @param[in] p0 First control point of the bezier curve
392    * @param[in] p1 Second control point of the bezier curve
393    * @param[in] t A floating point value between 0.0 and 1.0
394    * @return Value of the curve at progress t
395    */
396   inline float EvaluateCubicBezier( float p0, float p1, float t ) const
397   {
398     float tSquare = t*t;
399     return 3.0f*(1.0f-t)*(1.0f-t)*t*p0 + 3.0f*(1.0f-t)*tSquare*p1 + tSquare*t;
400   }
401
402   float mDurationSeconds;
403   float mIntervalDelaySeconds;
404   float mSpeedFactor;
405
406   int mLoopCount;
407
408   AlphaFunction mAlphaFunction;
409
410   Dali::Animation::EndAction mDisconnectAction;     ///< EndAction to apply when target object gets disconnected from the stage.
411   bool mActive:1;                                   ///< Animator is "active" while it's running.
412   bool mEnabled:1;                                  ///< Animator is "enabled" while its target object is valid and on the stage.
413   bool mConnectedToSceneGraph:1;                    ///< True if ConnectToSceneGraph() has been called in update-thread.
414   bool mAutoReverseEnabled:1;
415 };
416
417 /**
418  * An animator for a specific property type PropertyType.
419  */
420 template < typename PropertyType, typename PropertyAccessorType >
421 class Animator : public AnimatorBase, public PropertyOwner::Observer
422 {
423 public:
424
425   /**
426    * Construct a new property animator.
427    * @param[in] property The animatable property; only valid while the Animator is attached.
428    * @param[in] animatorFunction The function used to animate the property.
429    * @param[in] alphaFunction The alpha function to apply.
430    * @param[in] timePeriod The time period of this animation.
431    * @return A newly allocated animator.
432    */
433   static AnimatorBase* New( const PropertyOwner& propertyOwner,
434                             const PropertyBase& property,
435                             AnimatorFunctionBase* animatorFunction,
436                             AlphaFunction alphaFunction,
437                             const TimePeriod& timePeriod )
438   {
439     typedef Animator< PropertyType, PropertyAccessorType > AnimatorType;
440
441     // The property was const in the actor-thread, but animators are used in the scene-graph thread.
442     AnimatorType* animator = new AnimatorType( const_cast<PropertyOwner*>( &propertyOwner ),
443                                                const_cast<PropertyBase*>( &property ),
444                                                animatorFunction );
445
446     animator->SetAlphaFunction( alphaFunction );
447     animator->SetIntervalDelay( timePeriod.delaySeconds );
448     animator->SetDuration( timePeriod.durationSeconds );
449
450     return animator;
451   }
452
453   /**
454    * Virtual destructor.
455    */
456   virtual ~Animator()
457   {
458     if (mPropertyOwner && mConnectedToSceneGraph)
459     {
460       mPropertyOwner->RemoveObserver(*this);
461     }
462
463     delete mAnimatorFunction;
464   }
465
466   /**
467    * Called when Animator is added to the scene-graph in update-thread.
468    */
469   virtual void ConnectToSceneGraph()
470   {
471     mConnectedToSceneGraph = true;
472     mPropertyOwner->AddObserver(*this);
473   }
474
475   /**
476    * Called when mPropertyOwner is connected to the scene graph.
477    */
478   virtual void PropertyOwnerConnected( PropertyOwner& owner )
479   {
480     mEnabled = true;
481   }
482
483   /**
484    * Called when mPropertyOwner is disconnected from the scene graph.
485    */
486   virtual void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner )
487   {
488     // If we are active, then bake the value if required
489     if ( mActive && mDisconnectAction != Dali::Animation::Discard )
490     {
491       // Bake to target-value if BakeFinal, otherwise bake current value
492       Update( bufferIndex, ( mDisconnectAction == Dali::Animation::Bake ? mCurrentProgress : 1.0f ), true );
493     }
494
495     mActive = false;
496     mEnabled = false;
497   }
498
499   /**
500    * Called shortly before mPropertyOwner is destroyed
501    */
502   virtual void PropertyOwnerDestroyed( PropertyOwner& owner )
503   {
504     mPropertyOwner = NULL;
505   }
506
507   /**
508    * From AnimatorBase.
509    */
510   virtual void Update( BufferIndex bufferIndex, float progress, bool bake )
511   {
512     if( mLoopCount != 1 ) // Looping mode
513     {
514       // Update the progress value
515       progress = SetProgress( progress );
516     }
517
518     float alpha = ApplyAlphaFunction( progress );
519
520     const PropertyType& current = mPropertyAccessor.Get( bufferIndex );
521
522     const PropertyType result = (*mAnimatorFunction)( alpha, current );
523     if ( bake )
524     {
525       mPropertyAccessor.Bake( bufferIndex, result );
526     }
527     else
528     {
529       mPropertyAccessor.Set( bufferIndex, result );
530     }
531
532     mCurrentProgress = progress;
533   }
534
535   /**
536    * From AnimatorBase.
537    */
538   virtual bool Orphan()
539   {
540     return (mPropertyOwner == NULL);
541   }
542
543 private:
544
545   /**
546    * Private constructor; see also Animator::New().
547    */
548   Animator( PropertyOwner* propertyOwner,
549             PropertyBase* property,
550             AnimatorFunctionBase* animatorFunction )
551   : mPropertyOwner( propertyOwner ),
552     mPropertyAccessor( property ),
553     mAnimatorFunction( animatorFunction ),
554     mCurrentProgress( 0.0f )
555   {
556     // WARNING - this object is created in the event-thread
557     // The scene-graph mPropertyOwner object cannot be observed here
558   }
559
560   // Undefined
561   Animator( const Animator& );
562
563   // Undefined
564   Animator& operator=( const Animator& );
565
566 protected:
567
568   PropertyOwner* mPropertyOwner;
569   PropertyAccessorType mPropertyAccessor;
570
571   AnimatorFunctionBase* mAnimatorFunction;
572   float mCurrentProgress;
573 };
574
575
576
577 /**
578  * An animator for a specific property type PropertyType.
579  */
580 template <typename T, typename PropertyAccessorType>
581 class AnimatorTransformProperty : public AnimatorBase, public PropertyOwner::Observer
582 {
583 public:
584
585   /**
586    * Construct a new property animator.
587    * @param[in] property The animatable property; only valid while the Animator is attached.
588    * @param[in] animatorFunction The function used to animate the property.
589    * @param[in] alphaFunction The alpha function to apply.
590    * @param[in] timePeriod The time period of this animation.
591    * @return A newly allocated animator.
592    */
593   static AnimatorBase* New( const PropertyOwner& propertyOwner,
594                             const PropertyBase& property,
595                             AnimatorFunctionBase* animatorFunction,
596                             AlphaFunction alphaFunction,
597                             const TimePeriod& timePeriod )
598   {
599
600     // The property was const in the actor-thread, but animators are used in the scene-graph thread.
601     AnimatorTransformProperty* animator = new AnimatorTransformProperty( const_cast<PropertyOwner*>( &propertyOwner ),
602                                                const_cast<PropertyBase*>( &property ),
603                                                animatorFunction );
604
605     animator->SetAlphaFunction( alphaFunction );
606     animator->SetIntervalDelay( timePeriod.delaySeconds );
607     animator->SetDuration( timePeriod.durationSeconds );
608
609     return animator;
610   }
611
612   /**
613    * Virtual destructor.
614    */
615   virtual ~AnimatorTransformProperty()
616   {
617     if (mPropertyOwner && mConnectedToSceneGraph)
618     {
619       mPropertyOwner->RemoveObserver(*this);
620     }
621
622     delete mAnimatorFunction;
623   }
624
625   /**
626    * Called when Animator is added to the scene-graph in update-thread.
627    */
628   virtual void ConnectToSceneGraph()
629   {
630     mConnectedToSceneGraph = true;
631     mPropertyOwner->AddObserver(*this);
632   }
633
634   /**
635    * Called when mPropertyOwner is connected to the scene graph.
636    */
637   virtual void PropertyOwnerConnected( PropertyOwner& owner )
638   {
639     mEnabled = true;
640   }
641
642   /**
643    * Called when mPropertyOwner is disconnected from the scene graph.
644    */
645   virtual void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner )
646   {
647     // If we are active, then bake the value if required
648     if ( mActive && mDisconnectAction != Dali::Animation::Discard )
649     {
650       // Bake to target-value if BakeFinal, otherwise bake current value
651       Update( bufferIndex, ( mDisconnectAction == Dali::Animation::Bake ? mCurrentProgress : 1.0f ), true );
652     }
653
654     mActive = false;
655     mEnabled = false;
656   }
657
658   /**
659    * Called shortly before mPropertyOwner is destroyed
660    */
661   virtual void PropertyOwnerDestroyed( PropertyOwner& owner )
662   {
663     mPropertyOwner = NULL;
664   }
665
666   /**
667    * From AnimatorBase.
668    */
669   virtual void Update( BufferIndex bufferIndex, float progress, bool bake )
670   {
671     if( mLoopCount != 1 ) // Looping mode
672     {
673       // Update the progress value
674       progress = SetProgress( progress );
675     }
676
677     float alpha = ApplyAlphaFunction( progress );
678
679     const T& current = mPropertyAccessor.Get( bufferIndex );
680
681     const T result = (*mAnimatorFunction)( alpha, current );
682
683
684     if ( bake )
685     {
686       mPropertyAccessor.Bake( bufferIndex, result );
687     }
688     else
689     {
690       mPropertyAccessor.Set( bufferIndex, result );
691     }
692
693     mCurrentProgress = progress;
694   }
695
696   /**
697    * From AnimatorBase.
698    */
699   virtual bool Orphan()
700   {
701     return (mPropertyOwner == NULL);
702   }
703
704 private:
705
706   /**
707    * Private constructor; see also Animator::New().
708    */
709   AnimatorTransformProperty( PropertyOwner* propertyOwner,
710             PropertyBase* property,
711             AnimatorFunctionBase* animatorFunction )
712   : mPropertyOwner( propertyOwner ),
713     mPropertyAccessor( property ),
714     mAnimatorFunction( animatorFunction ),
715     mCurrentProgress( 0.0f )
716   {
717     // WARNING - this object is created in the event-thread
718     // The scene-graph mPropertyOwner object cannot be observed here
719   }
720
721   // Undefined
722   AnimatorTransformProperty( const AnimatorTransformProperty& );
723
724   // Undefined
725   AnimatorTransformProperty& operator=( const AnimatorTransformProperty& );
726
727 protected:
728
729   PropertyOwner* mPropertyOwner;
730   PropertyAccessorType mPropertyAccessor;
731
732   AnimatorFunctionBase* mAnimatorFunction;
733   float mCurrentProgress;
734 };
735
736 } // namespace SceneGraph
737
738 /*
739  * AnimatorFunction base class.
740  * All update functions must inherit from AnimatorFunctionBase and overload the appropiate "()" operator
741  */
742 struct AnimatorFunctionBase
743 {
744   /**
745    * Constructor
746    */
747   AnimatorFunctionBase(){}
748
749   /*
750    * Virtual destructor (Intended as base class)
751    */
752   virtual ~AnimatorFunctionBase(){}
753
754   ///Stub "()" operators.
755   virtual bool operator()(float progress, const bool& property)
756   {
757     return property;
758   }
759
760   virtual float operator()(float progress, const int& property)
761   {
762     return property;
763   }
764
765   virtual float operator()(float progress, const unsigned int& property)
766   {
767     return property;
768   }
769
770   virtual float operator()(float progress, const float& property)
771   {
772     return property;
773   }
774
775   virtual Vector2 operator()(float progress, const Vector2& property)
776   {
777     return property;
778   }
779
780   virtual Vector3 operator()(float progress, const Vector3& property)
781   {
782     return property;
783   }
784
785   virtual Vector4 operator()(float progress, const Vector4& property)
786   {
787     return property;
788   }
789
790   virtual Quaternion operator()(float progress, const Quaternion& property)
791   {
792     return property;
793   }
794 };
795
796 // Update functions
797
798 struct AnimateByInteger : public AnimatorFunctionBase
799 {
800   AnimateByInteger(const int& relativeValue)
801   : mRelative(relativeValue)
802   {
803   }
804
805   using AnimatorFunctionBase::operator();
806   float operator()(float alpha, const int& property)
807   {
808     return int(property + mRelative * alpha + 0.5f );
809   }
810
811   int mRelative;
812 };
813
814 struct AnimateToInteger : public AnimatorFunctionBase
815 {
816   AnimateToInteger(const int& targetValue)
817   : mTarget(targetValue)
818   {
819   }
820
821   using AnimatorFunctionBase::operator();
822   float operator()(float alpha, const int& property)
823   {
824     return int(property + ((mTarget - property) * alpha) + 0.5f);
825   }
826
827   int mTarget;
828 };
829
830 struct AnimateByFloat : public AnimatorFunctionBase
831 {
832   AnimateByFloat(const float& relativeValue)
833   : mRelative(relativeValue)
834   {
835   }
836
837   using AnimatorFunctionBase::operator();
838   float operator()(float alpha, const float& property)
839   {
840     return float(property + mRelative * alpha);
841   }
842
843   float mRelative;
844 };
845
846 struct AnimateToFloat : public AnimatorFunctionBase
847 {
848   AnimateToFloat(const float& targetValue)
849   : mTarget(targetValue)
850   {
851   }
852
853   using AnimatorFunctionBase::operator();
854   float operator()(float alpha, const float& property)
855   {
856     return float(property + ((mTarget - property) * alpha));
857   }
858
859   float mTarget;
860 };
861
862 struct AnimateByVector2 : public AnimatorFunctionBase
863 {
864   AnimateByVector2(const Vector2& relativeValue)
865   : mRelative(relativeValue)
866   {
867   }
868
869   using AnimatorFunctionBase::operator();
870   Vector2 operator()(float alpha, const Vector2& property)
871   {
872     return Vector2(property + mRelative * alpha);
873   }
874
875   Vector2 mRelative;
876 };
877
878 struct AnimateToVector2 : public AnimatorFunctionBase
879 {
880   AnimateToVector2(const Vector2& targetValue)
881   : mTarget(targetValue)
882   {
883   }
884
885   using AnimatorFunctionBase::operator();
886   Vector2 operator()(float alpha, const Vector2& property)
887   {
888     return Vector2(property + ((mTarget - property) * alpha));
889   }
890
891   Vector2 mTarget;
892 };
893
894 struct AnimateByVector3 : public AnimatorFunctionBase
895 {
896   AnimateByVector3(const Vector3& relativeValue)
897   : mRelative(relativeValue)
898   {
899   }
900
901   using AnimatorFunctionBase::operator();
902   Vector3 operator()(float alpha, const Vector3& property)
903   {
904     return Vector3(property + mRelative * alpha);
905   }
906
907   Vector3 mRelative;
908 };
909
910 struct AnimateToVector3 : public AnimatorFunctionBase
911 {
912   AnimateToVector3(const Vector3& targetValue)
913   : mTarget(targetValue)
914   {
915   }
916
917   using AnimatorFunctionBase::operator();
918   Vector3 operator()(float alpha, const Vector3& property)
919   {
920     return Vector3(property + ((mTarget - property) * alpha));
921   }
922
923   Vector3 mTarget;
924 };
925
926 struct AnimateByVector4 : public AnimatorFunctionBase
927 {
928   AnimateByVector4(const Vector4& relativeValue)
929   : mRelative(relativeValue)
930   {
931   }
932
933   using AnimatorFunctionBase::operator();
934   Vector4 operator()(float alpha, const Vector4& property)
935   {
936     return Vector4(property + mRelative * alpha);
937   }
938
939   Vector4 mRelative;
940 };
941
942 struct AnimateToVector4 : public AnimatorFunctionBase
943 {
944   AnimateToVector4(const Vector4& targetValue)
945   : mTarget(targetValue)
946   {
947   }
948
949   using AnimatorFunctionBase::operator();
950   Vector4 operator()(float alpha, const Vector4& property)
951   {
952     return Vector4(property + ((mTarget - property) * alpha));
953   }
954
955   Vector4 mTarget;
956 };
957
958 struct AnimateByOpacity : public AnimatorFunctionBase
959 {
960   AnimateByOpacity(const float& relativeValue)
961   : mRelative(relativeValue)
962   {
963   }
964
965   using AnimatorFunctionBase::operator();
966   Vector4 operator()(float alpha, const Vector4& property)
967   {
968     Vector4 result(property);
969     result.a += mRelative * alpha;
970
971     return result;
972   }
973
974   float mRelative;
975 };
976
977 struct AnimateToOpacity : public AnimatorFunctionBase
978 {
979   AnimateToOpacity(const float& targetValue)
980   : mTarget(targetValue)
981   {
982   }
983
984   using AnimatorFunctionBase::operator();
985   Vector4 operator()(float alpha, const Vector4& property)
986   {
987     Vector4 result(property);
988     result.a = property.a + ((mTarget - property.a) * alpha);
989
990     return result;
991   }
992
993   float mTarget;
994 };
995
996 struct AnimateByBoolean : public AnimatorFunctionBase
997 {
998   AnimateByBoolean(bool relativeValue)
999   : mRelative(relativeValue)
1000   {
1001   }
1002
1003   using AnimatorFunctionBase::operator();
1004   bool operator()(float alpha, const bool& property)
1005   {
1006     // Alpha is not useful here, just keeping to the same template as other update functors
1007     return bool(alpha >= 1.0f ? (property || mRelative) : property);
1008   }
1009
1010   bool mRelative;
1011 };
1012
1013 struct AnimateToBoolean : public AnimatorFunctionBase
1014 {
1015   AnimateToBoolean(bool targetValue)
1016   : mTarget(targetValue)
1017   {
1018   }
1019
1020   using AnimatorFunctionBase::operator();
1021   bool operator()(float alpha, const bool& property)
1022   {
1023     // Alpha is not useful here, just keeping to the same template as other update functors
1024     return bool(alpha >= 1.0f ? mTarget : property);
1025   }
1026
1027   bool mTarget;
1028 };
1029
1030 struct RotateByAngleAxis : public AnimatorFunctionBase
1031 {
1032   RotateByAngleAxis(const Radian& angleRadians, const Vector3& axis)
1033   : mAngleRadians( angleRadians ),
1034     mAxis(axis.x, axis.y, axis.z)
1035   {
1036   }
1037
1038   using AnimatorFunctionBase::operator();
1039   Quaternion operator()(float alpha, const Quaternion& rotation)
1040   {
1041     if (alpha > 0.0f)
1042     {
1043       return rotation * Quaternion(mAngleRadians * alpha, mAxis);
1044     }
1045
1046     return rotation;
1047   }
1048
1049   Radian mAngleRadians;
1050   Vector3 mAxis;
1051 };
1052
1053 struct RotateToQuaternion : public AnimatorFunctionBase
1054 {
1055   RotateToQuaternion(const Quaternion& targetValue)
1056   : mTarget(targetValue)
1057   {
1058   }
1059
1060   using AnimatorFunctionBase::operator();
1061   Quaternion operator()(float alpha, const Quaternion& rotation)
1062   {
1063     return Quaternion::Slerp(rotation, mTarget, alpha);
1064   }
1065
1066   Quaternion mTarget;
1067 };
1068
1069
1070 struct KeyFrameBooleanFunctor : public AnimatorFunctionBase
1071 {
1072   KeyFrameBooleanFunctor(KeyFrameBooleanPtr keyFrames)
1073   : mKeyFrames(keyFrames)
1074   {
1075   }
1076
1077   using AnimatorFunctionBase::operator();
1078   bool operator()(float progress, const bool& property)
1079   {
1080     if(mKeyFrames->IsActive(progress))
1081     {
1082       return mKeyFrames->GetValue(progress, Dali::Animation::Linear);
1083     }
1084     return property;
1085   }
1086
1087   KeyFrameBooleanPtr mKeyFrames;
1088 };
1089
1090 struct KeyFrameIntegerFunctor : public AnimatorFunctionBase
1091 {
1092   KeyFrameIntegerFunctor(KeyFrameIntegerPtr keyFrames, Interpolation interpolation)
1093   : mKeyFrames(keyFrames),mInterpolation(interpolation)
1094   {
1095   }
1096
1097   using AnimatorFunctionBase::operator();
1098   float operator()(float progress, const int& property)
1099   {
1100     if(mKeyFrames->IsActive(progress))
1101     {
1102       return mKeyFrames->GetValue(progress, mInterpolation);
1103     }
1104     return property;
1105   }
1106
1107   KeyFrameIntegerPtr mKeyFrames;
1108   Interpolation mInterpolation;
1109 };
1110
1111 struct KeyFrameNumberFunctor : public AnimatorFunctionBase
1112 {
1113   KeyFrameNumberFunctor(KeyFrameNumberPtr keyFrames, Interpolation interpolation)
1114   : mKeyFrames(keyFrames),mInterpolation(interpolation)
1115   {
1116   }
1117
1118   using AnimatorFunctionBase::operator();
1119   float operator()(float progress, const float& property)
1120   {
1121     if(mKeyFrames->IsActive(progress))
1122     {
1123       return mKeyFrames->GetValue(progress, mInterpolation);
1124     }
1125     return property;
1126   }
1127
1128   KeyFrameNumberPtr mKeyFrames;
1129   Interpolation mInterpolation;
1130 };
1131
1132 struct KeyFrameVector2Functor : public AnimatorFunctionBase
1133 {
1134   KeyFrameVector2Functor(KeyFrameVector2Ptr keyFrames, Interpolation interpolation)
1135   : mKeyFrames(keyFrames),mInterpolation(interpolation)
1136   {
1137   }
1138
1139   using AnimatorFunctionBase::operator();
1140   Vector2 operator()(float progress, const Vector2& property)
1141   {
1142     if(mKeyFrames->IsActive(progress))
1143     {
1144       return mKeyFrames->GetValue(progress, mInterpolation);
1145     }
1146     return property;
1147   }
1148
1149   KeyFrameVector2Ptr mKeyFrames;
1150   Interpolation mInterpolation;
1151 };
1152
1153
1154 struct KeyFrameVector3Functor : public AnimatorFunctionBase
1155 {
1156   KeyFrameVector3Functor(KeyFrameVector3Ptr keyFrames, Interpolation interpolation)
1157   : mKeyFrames(keyFrames),mInterpolation(interpolation)
1158   {
1159   }
1160
1161   using AnimatorFunctionBase::operator();
1162   Vector3 operator()(float progress, const Vector3& property)
1163   {
1164     if(mKeyFrames->IsActive(progress))
1165     {
1166       return mKeyFrames->GetValue(progress, mInterpolation);
1167     }
1168     return property;
1169   }
1170
1171   KeyFrameVector3Ptr mKeyFrames;
1172   Interpolation mInterpolation;
1173 };
1174
1175 struct KeyFrameVector4Functor : public AnimatorFunctionBase
1176 {
1177   KeyFrameVector4Functor(KeyFrameVector4Ptr keyFrames, Interpolation interpolation)
1178   : mKeyFrames(keyFrames),mInterpolation(interpolation)
1179   {
1180   }
1181
1182   using AnimatorFunctionBase::operator();
1183   Vector4 operator()(float progress, const Vector4& property)
1184   {
1185     if(mKeyFrames->IsActive(progress))
1186     {
1187       return mKeyFrames->GetValue(progress, mInterpolation);
1188     }
1189     return property;
1190   }
1191
1192   KeyFrameVector4Ptr mKeyFrames;
1193   Interpolation mInterpolation;
1194 };
1195
1196 struct KeyFrameQuaternionFunctor : public AnimatorFunctionBase
1197 {
1198   KeyFrameQuaternionFunctor(KeyFrameQuaternionPtr keyFrames)
1199   : mKeyFrames(keyFrames)
1200   {
1201   }
1202
1203   using AnimatorFunctionBase::operator();
1204   Quaternion operator()(float progress, const Quaternion& property)
1205   {
1206     if(mKeyFrames->IsActive(progress))
1207     {
1208       return mKeyFrames->GetValue(progress, Dali::Animation::Linear);
1209     }
1210     return property;
1211   }
1212
1213   KeyFrameQuaternionPtr mKeyFrames;
1214 };
1215
1216 struct PathPositionFunctor : public AnimatorFunctionBase
1217 {
1218   PathPositionFunctor( PathPtr path )
1219   : mPath(path)
1220   {
1221   }
1222
1223   using AnimatorFunctionBase::operator();
1224   Vector3 operator()(float progress, const Vector3& property)
1225   {
1226     Vector3 position(property);
1227     static_cast<void>( mPath->SamplePosition(progress, position) );
1228     return position;
1229   }
1230
1231   PathPtr mPath;
1232 };
1233
1234 struct PathRotationFunctor : public AnimatorFunctionBase
1235 {
1236   PathRotationFunctor( PathPtr path, const Vector3& forward )
1237   : mPath(path),
1238     mForward( forward )
1239   {
1240     mForward.Normalize();
1241   }
1242
1243   using AnimatorFunctionBase::operator();
1244   Quaternion operator()(float progress, const Quaternion& property)
1245   {
1246     Vector3 tangent;
1247     if( mPath->SampleTangent(progress, tangent) )
1248     {
1249       return Quaternion( mForward, tangent );
1250     }
1251     else
1252     {
1253       return property;
1254     }
1255   }
1256
1257   PathPtr mPath;
1258   Vector3 mForward;
1259 };
1260
1261 } // namespace Internal
1262
1263 } // namespace Dali
1264
1265 #endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H__