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