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