[dali_1.0.39] Merge branch 'tizen'
[platform/core/uifw/dali-core.git] / dali / internal / update / animation / scene-graph-animator.h
1 #ifndef __DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H__
2 #define __DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H__
3
4 /*
5  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/common/owner-container.h>
23 #include <dali/internal/event/animation/key-frames-impl.h>
24 #include <dali/internal/event/animation/path-impl.h>
25 #include <dali/internal/update/nodes/node.h>
26 #include <dali/internal/update/common/property-base.h>
27 #include <dali/public-api/animation/alpha-functions.h>
28 #include <dali/public-api/animation/animation.h>
29 #include <dali/public-api/animation/time-period.h>
30 #include <dali/public-api/common/dali-common.h>
31 #include <dali/public-api/math/quaternion.h>
32 #include <dali/public-api/math/radian.h>
33
34 namespace Dali
35 {
36
37 namespace Internal
38 {
39
40 typedef Dali::Animation::Interpolation Interpolation;
41
42 struct AnimatorFunctionBase;
43
44 namespace SceneGraph
45 {
46
47 class AnimatorBase;
48
49 typedef OwnerContainer< AnimatorBase* > AnimatorContainer;
50
51 typedef AnimatorContainer::Iterator AnimatorIter;
52 typedef AnimatorContainer::ConstIterator AnimatorConstIter;
53
54 /**
55  * An abstract base class for Animators, which can be added to scene graph animations.
56  * Each animator changes a single property of an object in the scene graph.
57  */
58 class AnimatorBase
59 {
60 public:
61
62   typedef float (*AlphaFunc)(float progress); ///< Definition of an alpha function
63
64   /**
65    * Constructor.
66    */
67   AnimatorBase()
68   : mDurationSeconds(1.0f),
69     mInitialDelaySeconds(0.0f),
70     mAlphaFunc(AlphaFunctions::Linear),
71     mDisconnectAction(Dali::Animation::BakeFinal),
72     mActive(false),
73     mEnabled(true)
74   {
75   }
76
77   /**
78    * Virtual destructor.
79    */
80   virtual ~AnimatorBase()
81   {
82   }
83
84   /**
85    * Set the duration of the animator.
86    * @pre durationSeconds must be zero or greater; zero is useful when animating boolean values.
87    * @param [in] seconds Duration in seconds.
88    */
89   void SetDuration(float seconds)
90   {
91     DALI_ASSERT_DEBUG(seconds >= 0.0f);
92
93     mDurationSeconds = seconds;
94   }
95
96   /**
97    * Retrieve the duration of the animator.
98    * @return The duration in seconds.
99    */
100   float GetDuration()
101   {
102     return mDurationSeconds;
103   }
104
105   /**
106    * Set the delay before the animator should take effect.
107    * The default is zero i.e. no delay.
108    * @param [in] seconds The delay in seconds.
109    */
110   void SetInitialDelay(float seconds)
111   {
112     mInitialDelaySeconds = seconds;
113   }
114
115   /**
116    * Retrieve the initial delay of the animator.
117    * @return The delay in seconds.
118    */
119   float GetInitialDelay()
120   {
121     return mInitialDelaySeconds;
122   }
123
124   /**
125    * Set the alpha function for an animator.
126    * @param [in] alphaFunc The alpha function to apply to the animation progress.
127    */
128   void SetAlphaFunc(AlphaFunc alphaFunc)
129   {
130     mAlphaFunc = alphaFunc;
131   }
132
133   /**
134    * Retrieve the alpha function of an animator.
135    * @return The function.
136    */
137   AlphaFunc GetAlphaFunc() const
138   {
139     return mAlphaFunc;
140   }
141
142   /**
143    * Whether to bake the animation if attached property owner is disconnected.
144    * Property is only baked if the animator is active.
145    * @param [in] action The disconnect action.
146    */
147   void SetDisconnectAction( Dali::Animation::EndAction action )
148   {
149     mDisconnectAction = action;
150   }
151
152   /**
153    * Retrieve the disconnect action of an animator.
154    * @return The disconnect action.
155    */
156   Dali::Animation::EndAction GetDisconnectAction() const
157   {
158     return mDisconnectAction;
159   }
160
161   /**
162    * Whether the animator is active or not.
163    * @param [in] active The new active state.
164    * @post When the animator becomes active, it applies the disconnect-action if the property owner is then disconnected.
165    * @note When the property owner is disconnected, the active state is set to false.
166    */
167   void SetActive( bool active )
168   {
169     mActive = active;
170   }
171
172   /**
173    * Retrieve whether the animator has been set to active or not.
174    * @return The active state.
175    */
176   bool GetActive() const
177   {
178     return mActive;
179   }
180
181   /*
182    * Retrive wheter the animator's target object is valid and on the stage.
183    * @return The enabled state.
184    */
185   bool IsEnabled() const
186   {
187     return mEnabled;
188   }
189   /**
190    * Returns wheter the target object of the animator is still valid
191    * or has been destroyed.
192    * @return True if animator is orphan, false otherwise   *
193    * @note The SceneGraph::Animation will delete any orphan animator in its Update method.
194    */
195   virtual bool Orphan() = 0;
196
197   /**
198    * Update the scene object attached to the animator.
199    * @param[in] bufferIndex The buffer to animate.
200    * @param[in] progress A value from 0 to 1, where 0 is the start of the animation, and 1 is the end point.
201    * @param[in] bake Bake.
202    */
203   virtual void Update(BufferIndex bufferIndex, float progress, bool bake) = 0;
204
205 protected:
206
207   float mDurationSeconds;
208   float mInitialDelaySeconds;
209
210   AlphaFunc mAlphaFunc;
211
212   Dali::Animation::EndAction mDisconnectAction;     ///< EndAction to apply when target object gets disconnected from the stage.
213   bool mActive:1;                                   ///< Animator is "active" while it's running.
214   bool mEnabled:1;                                  ///< Animator is "enabled" while its target object is valid and on the stage.
215 };
216
217 /**
218  * An animator for a specific property type PropertyType.
219  */
220 template < typename PropertyType, typename PropertyAccessorType >
221 class Animator : public AnimatorBase, public PropertyOwner::Observer
222 {
223 public:
224
225   /**
226    * Construct a new property animator.
227    * @param[in] property The animatable property; only valid while the Animator is attached.
228    * @param[in] animatorFunction The function used to animate the property.
229    * @param[in] alphaFunction The alpha function to apply.
230    * @param[in] timePeriod The time period of this animation.
231    * @return A newly allocated animator.
232    */
233   static AnimatorBase* New( const PropertyOwner& propertyOwner,
234                             const PropertyBase& property,
235                             AnimatorFunctionBase* animatorFunction,
236                             AlphaFunction alphaFunction,
237                             const TimePeriod& timePeriod )
238   {
239     typedef Animator< PropertyType, PropertyAccessorType > AnimatorType;
240
241     // The property was const in the actor-thread, but animators are used in the scene-graph thread.
242     AnimatorType* animator = new AnimatorType( const_cast<PropertyOwner*>( &propertyOwner ),
243                                                const_cast<PropertyBase*>( &property ),
244                                                animatorFunction );
245
246     animator->SetAlphaFunc( alphaFunction );
247     animator->SetInitialDelay( timePeriod.delaySeconds );
248     animator->SetDuration( timePeriod.durationSeconds );
249
250     return animator;
251   }
252
253   /**
254    * Virtual destructor.
255    */
256   virtual ~Animator()
257   {
258     if (mPropertyOwner)
259     {
260       mPropertyOwner->RemoveObserver(*this);
261     }
262
263     if( mAnimatorFunction )
264     {
265       delete mAnimatorFunction;
266     }
267   }
268
269   /**
270    * Called when mPropertyOwner is connected to the scene graph.
271    */
272   virtual void PropertyOwnerConnected( PropertyOwner& owner )
273   {
274     mEnabled = true;
275   }
276
277   /**
278    * Called when mPropertyOwner is disconnected from the scene graph.
279    */
280   virtual void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner )
281   {
282     // If we are active, then bake the value if required
283     if ( mActive && mDisconnectAction != Dali::Animation::Discard )
284     {
285       // Bake to target-value if BakeFinal, otherwise bake current value
286       Update( bufferIndex, ( mDisconnectAction == Dali::Animation::Bake ? mCurrentProgress : 1.0f ), true );
287     }
288
289     mActive = false;
290     mEnabled = false;
291   }
292
293   /**
294    * Called shortly before mPropertyOwner is destroyed
295    */
296   virtual void PropertyOwnerDestroyed( PropertyOwner& owner )
297   {
298     mPropertyOwner = NULL;
299     mPropertyAccessor.Reset();
300     mEnabled = false;
301   }
302
303   /**
304    * From AnimatorBase.
305    */
306   virtual void Update( BufferIndex bufferIndex, float progress, bool bake )
307   {
308     float alpha = mAlphaFunc( progress );
309     const PropertyType& current = mPropertyAccessor.Get( bufferIndex );
310
311     const PropertyType result = (*mAnimatorFunction)( alpha, current );
312     if ( bake )
313     {
314       mPropertyAccessor.Bake( bufferIndex, result );
315     }
316     else
317     {
318       mPropertyAccessor.Set( bufferIndex, result );
319     }
320
321     mCurrentProgress = progress;
322   }
323
324   /**
325    * From AnimatorBase.
326    */
327   virtual bool Orphan()
328   {
329     return (mPropertyOwner == NULL);
330   }
331
332 private:
333
334   /**
335    * Private constructor; see also Animator::New().
336    */
337   Animator( PropertyOwner* propertyOwner,
338             PropertyBase* property,
339             AnimatorFunctionBase* animatorFunction )
340   : mPropertyOwner( propertyOwner ),
341     mPropertyAccessor( property ),
342     mAnimatorFunction( animatorFunction ),
343     mCurrentProgress( 0.0f )
344   {
345     mPropertyOwner->AddObserver(*this);
346   }
347
348   // Undefined
349   Animator( const Animator& );
350
351   // Undefined
352   Animator& operator=( const Animator& );
353
354 protected:
355
356   PropertyOwner* mPropertyOwner;
357   PropertyAccessorType mPropertyAccessor;
358
359   AnimatorFunctionBase* mAnimatorFunction;
360   float mCurrentProgress;
361 };
362
363 } // namespace SceneGraph
364
365 /*
366  * AnimatorFunction base class.
367  * All update functions must inherit from AnimatorFunctionBase and overload the appropiate "()" operator
368  */
369 struct AnimatorFunctionBase
370 {
371   /**
372    * Constructor
373    */
374   AnimatorFunctionBase(){}
375
376   /*
377    * Virtual destructor (Intended as base class)
378    */
379   virtual ~AnimatorFunctionBase(){}
380
381   ///Stub "()" operators.
382   virtual bool operator()(float progress, const bool& property)
383   {
384     return property;
385   }
386
387   virtual float operator()(float progress, const int& property)
388   {
389     return property;
390   }
391
392   virtual float operator()(float progress, const unsigned int& property)
393   {
394     return property;
395   }
396
397   virtual float operator()(float progress, const float& property)
398   {
399     return property;
400   }
401
402   virtual Vector2 operator()(float progress, const Vector2& property)
403   {
404     return property;
405   }
406
407   virtual Vector3 operator()(float progress, const Vector3& property)
408   {
409     return property;
410   }
411
412   virtual Vector4 operator()(float progress, const Vector4& property)
413   {
414     return property;
415   }
416
417   virtual Quaternion operator()(float progress, const Quaternion& property)
418   {
419     return property;
420   }
421 };
422
423 // Update functions
424
425 struct AnimateByInteger : public AnimatorFunctionBase
426 {
427   AnimateByInteger(const int& relativeValue)
428   : mRelative(relativeValue)
429   {
430   }
431
432   float operator()(float alpha, const int& property)
433   {
434     return int(property + mRelative * alpha + 0.5f );
435   }
436
437   int mRelative;
438 };
439
440 struct AnimateToInteger : public AnimatorFunctionBase
441 {
442   AnimateToInteger(const int& targetValue)
443   : mTarget(targetValue)
444   {
445   }
446
447   float operator()(float alpha, const int& property)
448   {
449     return int(property + ((mTarget - property) * alpha) + 0.5f);
450   }
451
452   int mTarget;
453 };
454
455 struct AnimateByUnsignedInteger : public AnimatorFunctionBase
456 {
457   AnimateByUnsignedInteger(const unsigned int& relativeValue)
458   : mRelative(relativeValue)
459   {
460   }
461
462   float operator()(float alpha, const unsigned int& property)
463   {
464     return static_cast<unsigned int>(property + mRelative * alpha + 0.5f );
465   }
466
467   unsigned int mRelative;
468 };
469
470 struct AnimateToUnsignedInteger : public AnimatorFunctionBase
471 {
472   AnimateToUnsignedInteger(const unsigned int& targetValue)
473   : mTarget(targetValue)
474   {
475   }
476
477   float operator()(float alpha, const unsigned int& property)
478   {
479     return static_cast<unsigned int>(property + ((mTarget - property) * alpha) + 0.5f);
480   }
481
482   unsigned int mTarget;
483 };
484
485 struct AnimateByFloat : public AnimatorFunctionBase
486 {
487   AnimateByFloat(const float& relativeValue)
488   : mRelative(relativeValue)
489   {
490   }
491
492   float operator()(float alpha, const float& property)
493   {
494     return float(property + mRelative * alpha);
495   }
496
497   float mRelative;
498 };
499
500 struct AnimateToFloat : public AnimatorFunctionBase
501 {
502   AnimateToFloat(const float& targetValue)
503   : mTarget(targetValue)
504   {
505   }
506
507   float operator()(float alpha, const float& property)
508   {
509     return float(property + ((mTarget - property) * alpha));
510   }
511
512   float mTarget;
513 };
514
515 struct AnimateByVector2 : public AnimatorFunctionBase
516 {
517   AnimateByVector2(const Vector2& relativeValue)
518   : mRelative(relativeValue)
519   {
520   }
521
522   Vector2 operator()(float alpha, const Vector2& property)
523   {
524     return Vector2(property + mRelative * alpha);
525   }
526
527   Vector2 mRelative;
528 };
529
530 struct AnimateToVector2 : public AnimatorFunctionBase
531 {
532   AnimateToVector2(const Vector2& targetValue)
533   : mTarget(targetValue)
534   {
535   }
536
537   Vector2 operator()(float alpha, const Vector2& property)
538   {
539     return Vector2(property + ((mTarget - property) * alpha));
540   }
541
542   Vector2 mTarget;
543 };
544
545 struct AnimateByVector3 : public AnimatorFunctionBase
546 {
547   AnimateByVector3(const Vector3& relativeValue)
548   : mRelative(relativeValue)
549   {
550   }
551
552   Vector3 operator()(float alpha, const Vector3& property)
553   {
554     return Vector3(property + mRelative * alpha);
555   }
556
557   Vector3 mRelative;
558 };
559
560 struct AnimateToVector3 : public AnimatorFunctionBase
561 {
562   AnimateToVector3(const Vector3& targetValue)
563   : mTarget(targetValue)
564   {
565   }
566
567   Vector3 operator()(float alpha, const Vector3& property)
568   {
569     return Vector3(property + ((mTarget - property) * alpha));
570   }
571
572   Vector3 mTarget;
573 };
574
575 struct AnimateByVector4 : public AnimatorFunctionBase
576 {
577   AnimateByVector4(const Vector4& relativeValue)
578   : mRelative(relativeValue)
579   {
580   }
581
582   Vector4 operator()(float alpha, const Vector4& property)
583   {
584     return Vector4(property + mRelative * alpha);
585   }
586
587   Vector4 mRelative;
588 };
589
590 struct AnimateToVector4 : public AnimatorFunctionBase
591 {
592   AnimateToVector4(const Vector4& targetValue)
593   : mTarget(targetValue)
594   {
595   }
596
597   Vector4 operator()(float alpha, const Vector4& property)
598   {
599     return Vector4(property + ((mTarget - property) * alpha));
600   }
601
602   Vector4 mTarget;
603 };
604
605 struct AnimateByOpacity : public AnimatorFunctionBase
606 {
607   AnimateByOpacity(const float& relativeValue)
608   : mRelative(relativeValue)
609   {
610   }
611
612   Vector4 operator()(float alpha, const Vector4& property)
613   {
614     Vector4 result(property);
615     result.a += mRelative * alpha;
616
617     return result;
618   }
619
620   float mRelative;
621 };
622
623 struct AnimateToOpacity : public AnimatorFunctionBase
624 {
625   AnimateToOpacity(const float& targetValue)
626   : mTarget(targetValue)
627   {
628   }
629
630   Vector4 operator()(float alpha, const Vector4& property)
631   {
632     Vector4 result(property);
633     result.a = property.a + ((mTarget - property.a) * alpha);
634
635     return result;
636   }
637
638   float mTarget;
639 };
640
641 struct AnimateByBoolean : public AnimatorFunctionBase
642 {
643   AnimateByBoolean(bool relativeValue)
644   : mRelative(relativeValue)
645   {
646   }
647
648   bool operator()(float alpha, const bool& property)
649   {
650     // Alpha is not useful here, just keeping to the same template as other update functors
651     return bool(alpha >= 1.0f ? (property || mRelative) : property);
652   }
653
654   bool mRelative;
655 };
656
657 struct AnimateToBoolean : public AnimatorFunctionBase
658 {
659   AnimateToBoolean(bool targetValue)
660   : mTarget(targetValue)
661   {
662   }
663
664   bool operator()(float alpha, const bool& property)
665   {
666     // Alpha is not useful here, just keeping to the same template as other update functors
667     return bool(alpha >= 1.0f ? mTarget : property);
668   }
669
670   bool mTarget;
671 };
672
673 struct RotateByAngleAxis : public AnimatorFunctionBase
674 {
675   RotateByAngleAxis(const Radian& angleRadians, const Vector3& axis)
676   : mAngleRadians( angleRadians ),
677     mAxis(axis.x, axis.y, axis.z)
678   {
679   }
680
681   Quaternion operator()(float alpha, const Quaternion& rotation)
682   {
683     if (alpha > 0.0f)
684     {
685       return rotation * Quaternion(mAngleRadians * alpha, mAxis);
686     }
687
688     return rotation;
689   }
690
691   Radian mAngleRadians;
692   Vector3 mAxis;
693 };
694
695 struct RotateToQuaternion : public AnimatorFunctionBase
696 {
697   RotateToQuaternion(const Quaternion& targetValue)
698   : mTarget(targetValue)
699   {
700   }
701
702   Quaternion operator()(float alpha, const Quaternion& rotation)
703   {
704     return Quaternion::Slerp(rotation, mTarget, alpha);
705   }
706
707   Quaternion mTarget;
708 };
709
710
711 struct KeyFrameBooleanFunctor : public AnimatorFunctionBase
712 {
713   KeyFrameBooleanFunctor(KeyFrameBooleanPtr keyFrames)
714   : mKeyFrames(keyFrames)
715   {
716   }
717
718   bool operator()(float progress, const bool& property)
719   {
720     if(mKeyFrames->IsActive(progress))
721     {
722       return mKeyFrames->GetValue(progress, Dali::Animation::Linear);
723     }
724     return property;
725   }
726
727   KeyFrameBooleanPtr mKeyFrames;
728 };
729
730 struct KeyFrameIntegerFunctor : public AnimatorFunctionBase
731 {
732   KeyFrameIntegerFunctor(KeyFrameIntegerPtr keyFrames, Interpolation interpolation)
733   : mKeyFrames(keyFrames),mInterpolation(interpolation)
734   {
735   }
736
737   float operator()(float progress, const int& property)
738   {
739     if(mKeyFrames->IsActive(progress))
740     {
741       return mKeyFrames->GetValue(progress, mInterpolation);
742     }
743     return property;
744   }
745
746   KeyFrameIntegerPtr mKeyFrames;
747   Interpolation mInterpolation;
748 };
749
750 struct KeyFrameUnsignedIntegerFunctor : public AnimatorFunctionBase
751 {
752   KeyFrameUnsignedIntegerFunctor(KeyFrameUnsignedIntegerPtr keyFrames, Interpolation interpolation)
753   : mKeyFrames(keyFrames),mInterpolation(interpolation)
754   {
755   }
756
757   float operator()(float progress, const unsigned int& property)
758   {
759     if(mKeyFrames->IsActive(progress))
760     {
761       return mKeyFrames->GetValue(progress, mInterpolation);
762     }
763     return property;
764   }
765
766   KeyFrameUnsignedIntegerPtr mKeyFrames;
767   Interpolation mInterpolation;
768 };
769
770 struct KeyFrameNumberFunctor : public AnimatorFunctionBase
771 {
772   KeyFrameNumberFunctor(KeyFrameNumberPtr keyFrames, Interpolation interpolation)
773   : mKeyFrames(keyFrames),mInterpolation(interpolation)
774   {
775   }
776
777   float operator()(float progress, const float& property)
778   {
779     if(mKeyFrames->IsActive(progress))
780     {
781       return mKeyFrames->GetValue(progress, mInterpolation);
782     }
783     return property;
784   }
785
786   KeyFrameNumberPtr mKeyFrames;
787   Interpolation mInterpolation;
788 };
789
790 struct KeyFrameVector2Functor : public AnimatorFunctionBase
791 {
792   KeyFrameVector2Functor(KeyFrameVector2Ptr keyFrames, Interpolation interpolation)
793   : mKeyFrames(keyFrames),mInterpolation(interpolation)
794   {
795   }
796
797   Vector2 operator()(float progress, const Vector2& property)
798   {
799     if(mKeyFrames->IsActive(progress))
800     {
801       return mKeyFrames->GetValue(progress, mInterpolation);
802     }
803     return property;
804   }
805
806   KeyFrameVector2Ptr mKeyFrames;
807   Interpolation mInterpolation;
808 };
809
810
811 struct KeyFrameVector3Functor : public AnimatorFunctionBase
812 {
813   KeyFrameVector3Functor(KeyFrameVector3Ptr keyFrames, Interpolation interpolation)
814   : mKeyFrames(keyFrames),mInterpolation(interpolation)
815   {
816   }
817
818   Vector3 operator()(float progress, const Vector3& property)
819   {
820     if(mKeyFrames->IsActive(progress))
821     {
822       return mKeyFrames->GetValue(progress, mInterpolation);
823     }
824     return property;
825   }
826
827   KeyFrameVector3Ptr mKeyFrames;
828   Interpolation mInterpolation;
829 };
830
831 struct KeyFrameVector4Functor : public AnimatorFunctionBase
832 {
833   KeyFrameVector4Functor(KeyFrameVector4Ptr keyFrames, Interpolation interpolation)
834   : mKeyFrames(keyFrames),mInterpolation(interpolation)
835   {
836   }
837
838   Vector4 operator()(float progress, const Vector4& property)
839   {
840     if(mKeyFrames->IsActive(progress))
841     {
842       return mKeyFrames->GetValue(progress, mInterpolation);
843     }
844     return property;
845   }
846
847   KeyFrameVector4Ptr mKeyFrames;
848   Interpolation mInterpolation;
849 };
850
851 struct KeyFrameQuaternionFunctor : public AnimatorFunctionBase
852 {
853   KeyFrameQuaternionFunctor(KeyFrameQuaternionPtr keyFrames)
854   : mKeyFrames(keyFrames)
855   {
856   }
857
858   Quaternion operator()(float progress, const Quaternion& property)
859   {
860     if(mKeyFrames->IsActive(progress))
861     {
862       return mKeyFrames->GetValue(progress, Dali::Animation::Linear);
863     }
864     return property;
865   }
866
867   KeyFrameQuaternionPtr mKeyFrames;
868 };
869
870 struct PathPositionFunctor : public AnimatorFunctionBase
871 {
872   PathPositionFunctor( PathPtr path )
873   : mPath(path)
874   {
875   }
876
877   Vector3 operator()(float progress, const Vector3& property)
878   {
879     return mPath->SamplePosition(progress );
880   }
881
882   PathPtr mPath;
883 };
884
885 struct PathRotationFunctor : public AnimatorFunctionBase
886 {
887   PathRotationFunctor( PathPtr path, const Vector3& forward )
888   : mPath(path),
889     mForward( forward )
890   {
891     mForward.Normalize();
892   }
893
894   Quaternion operator()(float progress, const Quaternion& property)
895   {
896     Vector3 tangent( mPath->SampleTangent(progress) );
897     return Quaternion( mForward, tangent );
898   }
899
900   PathPtr mPath;
901   Vector3 mForward;
902 };
903
904
905 } // namespace Internal
906
907 } // namespace Dali
908
909 #endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H__