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