[dali_1.0.22] 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 // EXTERNAL INCLUDES
22 #include <boost/function.hpp>
23
24 // INTERNAL INCLUDES
25 #include <dali/internal/common/owner-container.h>
26 #include <dali/internal/event/animation/key-frames-impl.h>
27 #include <dali/internal/event/animation/path-impl.h>
28 #include <dali/internal/update/nodes/node.h>
29 #include <dali/internal/update/common/property-base.h>
30 #include <dali/public-api/animation/alpha-functions.h>
31 #include <dali/public-api/animation/animation.h>
32 #include <dali/public-api/animation/time-period.h>
33 #include <dali/public-api/common/dali-common.h>
34 #include <dali/public-api/math/quaternion.h>
35 #include <dali/public-api/math/radian.h>
36
37 namespace Dali
38 {
39
40 namespace Internal
41 {
42
43 typedef Dali::Animation::Interpolation Interpolation;
44
45 namespace SceneGraph
46 {
47
48 class AnimatorBase;
49
50 typedef OwnerContainer< AnimatorBase* > AnimatorContainer;
51
52 typedef AnimatorContainer::Iterator AnimatorIter;
53 typedef AnimatorContainer::ConstIterator AnimatorConstIter;
54
55 /**
56  * An abstract base class for Animators, which can be added to scene graph animations.
57  * Each animator changes a single property of an object in the scene graph.
58  */
59 class AnimatorBase
60 {
61 public:
62
63   typedef float (*AlphaFunc)(float progress); ///< Definition of an alpha function
64
65   /**
66    * Constructor.
67    */
68   AnimatorBase()
69   : mDurationSeconds(1.0f),
70     mInitialDelaySeconds(0.0f),
71     mAlphaFunc(AlphaFunctions::Linear),
72     mDisconnectAction(Dali::Animation::BakeFinal),
73     mActive(false)
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] action The disconnect action.
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    * This must be called when the animator is attached to the scene-graph.
183    * @pre The animatable scene object must also be attached to the scene-graph.
184    * @param[in] propertyOwner The scene-object that owns the animatable property.
185    */
186   virtual void Attach( PropertyOwner* propertyOwner ) = 0;
187
188   /**
189    * Update the scene object attached to the animator.
190    * @param[in] bufferIndex The buffer to animate.
191    * @param[in] progress A value from 0 to 1, where 0 is the start of the animation, and 1 is the end point.
192    * @param[in] bake Bake.
193    * @return True if the update was applied, false if the animator has been orphaned.
194    */
195   virtual bool Update(BufferIndex bufferIndex, float progress, bool bake) = 0;
196
197   /**
198    * Query whether the animator is still attached to a scene object.
199    * The attachment will be automatically severed, when the object is destroyed.
200    * @return True if the animator is attached.
201    */
202   virtual bool IsAttached() const = 0;
203
204 protected:
205
206   float mDurationSeconds;
207   float mInitialDelaySeconds;
208
209   AlphaFunc mAlphaFunc;
210
211   Dali::Animation::EndAction mDisconnectAction;
212   bool mActive:1;
213 };
214
215 /**
216  * An animator for a specific property type PropertyType.
217  */
218 template < typename PropertyType, typename PropertyAccessorType >
219 class Animator : public AnimatorBase, public PropertyOwner::Observer
220 {
221 public:
222
223   typedef boost::function< PropertyType (float, const PropertyType&) > AnimatorFunction;
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 PropertyBase& property,
234                             AnimatorFunction animatorFunction,
235                             AlphaFunction alphaFunction,
236                             const TimePeriod& timePeriod )
237   {
238     typedef Animator< PropertyType, PropertyAccessorType > AnimatorType;
239
240     // The property was const in the actor-thread, but animators are used in the scene-graph thread.
241     AnimatorType* animator = new AnimatorType( const_cast<PropertyBase*>( &property ),
242                                                animatorFunction );
243
244     animator->SetAlphaFunc( alphaFunction );
245     animator->SetInitialDelay( timePeriod.delaySeconds );
246     animator->SetDuration( timePeriod.durationSeconds );
247
248     return animator;
249   }
250
251   /**
252    * Virtual destructor.
253    */
254   virtual ~Animator()
255   {
256     if (mPropertyOwner)
257     {
258       mPropertyOwner->RemoveObserver(*this);
259     }
260   }
261
262   /**
263    * From AnimatorBase.
264    * @param[in] propertyOwner The scene-object that owns the animatable property.
265    */
266   virtual void Attach( PropertyOwner* propertyOwner )
267   {
268     mPropertyOwner = propertyOwner;
269
270     if (mPropertyOwner)
271     {
272       mPropertyOwner->AddObserver(*this);
273     }
274   }
275
276   /**
277    * From AnimatorBase.
278    */
279   virtual bool Update( BufferIndex bufferIndex, float progress, bool bake )
280   {
281     // If the object dies, the animator has no effect
282     if ( mPropertyOwner )
283     {
284       float alpha = mAlphaFunc( progress );
285
286       const PropertyType& current = mPropertyAccessor.Get( bufferIndex );
287
288       const PropertyType result = mAnimatorFunction( alpha, current );
289
290       if ( bake )
291       {
292         mPropertyAccessor.Bake( bufferIndex, result );
293       }
294       else
295       {
296         mPropertyAccessor.Set( bufferIndex, result );
297       }
298
299       mCurrentProgress = progress;
300     }
301
302     return IsAttached(); // return false if orphaned
303   }
304
305   /**
306    * From AnimatorBase.
307    */
308   virtual bool IsAttached() const
309   {
310     return NULL != mPropertyOwner;
311   }
312
313   /**
314    * Called when mPropertyOwner is disconnected from the scene graph.
315    */
316   virtual void PropertyOwnerDisconnected( BufferIndex bufferIndex, PropertyOwner& owner )
317   {
318     // If we are active, then bake the value if required
319     if ( mActive && mDisconnectAction != Dali::Animation::Discard )
320     {
321       // Bake to target-value if BakeFinal, otherwise bake current value
322       Update( bufferIndex, ( mDisconnectAction == Dali::Animation::Bake ? mCurrentProgress : 1.0f ), true );
323     }
324
325     mActive = false;
326     mPropertyOwner = NULL;
327     mPropertyAccessor.Reset();
328   }
329
330   /**
331    * Called shortly before mPropertyOwner is destroyed, along with its property.
332    */
333   virtual void PropertyOwnerDestroyed( PropertyOwner& owner )
334   {
335     mPropertyOwner = NULL;
336     mPropertyAccessor.Reset();
337   }
338
339 private:
340
341   /**
342    * Private constructor; see also Animator::New().
343    */
344   Animator( PropertyBase* property,
345             AnimatorFunction animatorFunction )
346   : mPropertyOwner( NULL ),
347     mPropertyAccessor( property ),
348     mAnimatorFunction( animatorFunction ),
349     mCurrentProgress( 0.0f )
350   {
351   }
352
353   // Undefined
354   Animator( const Animator& );
355
356   // Undefined
357   Animator& operator=( const Animator& );
358
359 protected:
360
361   PropertyOwner* mPropertyOwner;
362   PropertyAccessorType mPropertyAccessor;
363
364   AnimatorFunction mAnimatorFunction;
365   float mCurrentProgress;
366 };
367
368 } // namespace SceneGraph
369
370
371 // Common Update functions
372
373 struct AnimateByFloat
374 {
375   AnimateByFloat(const float& relativeValue)
376   : mRelative(relativeValue)
377   {
378   }
379
380   float operator()(float alpha, const float& property)
381   {
382     return float(property + mRelative * alpha);
383   }
384
385   float mRelative;
386 };
387
388 struct AnimateToFloat
389 {
390   AnimateToFloat(const float& targetValue)
391   : mTarget(targetValue)
392   {
393   }
394
395   float operator()(float alpha, const float& property)
396   {
397     return float(property + ((mTarget - property) * alpha));
398   }
399
400   float mTarget;
401 };
402
403 struct AnimateByInteger
404 {
405   AnimateByInteger(const int& relativeValue)
406   : mRelative(relativeValue)
407   {
408   }
409
410   float operator()(float alpha, const int& property)
411   {
412     return int(property + mRelative * alpha + 0.5f );
413   }
414
415   int mRelative;
416 };
417
418 struct AnimateToInteger
419 {
420   AnimateToInteger(const int& targetValue)
421   : mTarget(targetValue)
422   {
423   }
424
425   float operator()(float alpha, const int& property)
426   {
427     return int(property + ((mTarget - property) * alpha) + 0.5f);
428   }
429
430   int mTarget;
431 };
432
433 struct AnimateByVector2
434 {
435   AnimateByVector2(const Vector2& relativeValue)
436   : mRelative(relativeValue)
437   {
438   }
439
440   Vector2 operator()(float alpha, const Vector2& property)
441   {
442     return Vector2(property + mRelative * alpha);
443   }
444
445   Vector2 mRelative;
446 };
447
448 struct AnimateToVector2
449 {
450   AnimateToVector2(const Vector2& targetValue)
451   : mTarget(targetValue)
452   {
453   }
454
455   Vector2 operator()(float alpha, const Vector2& property)
456   {
457     return Vector2(property + ((mTarget - property) * alpha));
458   }
459
460   Vector2 mTarget;
461 };
462
463 struct AnimateByVector3
464 {
465   AnimateByVector3(const Vector3& relativeValue)
466   : mRelative(relativeValue)
467   {
468   }
469
470   Vector3 operator()(float alpha, const Vector3& property)
471   {
472     return Vector3(property + mRelative * alpha);
473   }
474
475   Vector3 mRelative;
476 };
477
478 struct AnimateToVector3
479 {
480   AnimateToVector3(const Vector3& targetValue)
481   : mTarget(targetValue)
482   {
483   }
484
485   Vector3 operator()(float alpha, const Vector3& property)
486   {
487     return Vector3(property + ((mTarget - property) * alpha));
488   }
489
490   Vector3 mTarget;
491 };
492
493 struct AnimateByVector4
494 {
495   AnimateByVector4(const Vector4& relativeValue)
496   : mRelative(relativeValue)
497   {
498   }
499
500   Vector4 operator()(float alpha, const Vector4& property)
501   {
502     return Vector4(property + mRelative * alpha);
503   }
504
505   Vector4 mRelative;
506 };
507
508 struct AnimateToVector4
509 {
510   AnimateToVector4(const Vector4& targetValue)
511   : mTarget(targetValue)
512   {
513   }
514
515   Vector4 operator()(float alpha, const Vector4& property)
516   {
517     return Vector4(property + ((mTarget - property) * alpha));
518   }
519
520   Vector4 mTarget;
521 };
522
523 struct AnimateByOpacity
524 {
525   AnimateByOpacity(const float& relativeValue)
526   : mRelative(relativeValue)
527   {
528   }
529
530   Vector4 operator()(float alpha, const Vector4& property)
531   {
532     Vector4 result(property);
533     result.a += mRelative * alpha;
534
535     return result;
536   }
537
538   float mRelative;
539 };
540
541 struct AnimateToOpacity
542 {
543   AnimateToOpacity(const float& targetValue)
544   : mTarget(targetValue)
545   {
546   }
547
548   Vector4 operator()(float alpha, const Vector4& property)
549   {
550     Vector4 result(property);
551     result.a = property.a + ((mTarget - property.a) * alpha);
552
553     return result;
554   }
555
556   float mTarget;
557 };
558
559 struct AnimateByBoolean
560 {
561   AnimateByBoolean(bool relativeValue)
562   : mRelative(relativeValue)
563   {
564   }
565
566   bool operator()(float alpha, const bool& property)
567   {
568     // Alpha is not useful here, just keeping to the same template as other update functors
569     return bool(alpha >= 1.0f ? (property || mRelative) : property);
570   }
571
572   bool mRelative;
573 };
574
575 struct AnimateToBoolean
576 {
577   AnimateToBoolean(bool targetValue)
578   : mTarget(targetValue)
579   {
580   }
581
582   bool operator()(float alpha, const bool& property)
583   {
584     // Alpha is not useful here, just keeping to the same template as other update functors
585     return bool(alpha >= 1.0f ? mTarget : property);
586   }
587
588   bool mTarget;
589 };
590
591 struct RotateByAngleAxis
592 {
593   RotateByAngleAxis(const Radian& angleRadians, const Vector3& axis)
594   : mAngleRadians(angleRadians),
595     mAxis(axis.x, axis.y, axis.z, 0.0f)
596   {
597   }
598
599   Quaternion operator()(float alpha, const Quaternion& rotation)
600   {
601     if (alpha > 0.0f)
602     {
603       return rotation * Quaternion(mAngleRadians * alpha, mAxis);
604     }
605
606     return rotation;
607   }
608
609   float mAngleRadians;
610   Vector4 mAxis;
611 };
612
613 struct RotateToQuaternion
614 {
615   RotateToQuaternion(const Quaternion& targetValue)
616   : mTarget(targetValue)
617   {
618   }
619
620   Quaternion operator()(float alpha, const Quaternion& rotation)
621   {
622     return Quaternion::Slerp(rotation, mTarget, alpha);
623   }
624
625   Quaternion mTarget;
626 };
627
628
629 struct KeyFrameBooleanFunctor
630 {
631   KeyFrameBooleanFunctor(KeyFrameBooleanPtr keyFrames)
632   : mKeyFrames(keyFrames)
633   {
634   }
635
636   bool operator()(float progress, const bool& property)
637   {
638     if(mKeyFrames->IsActive(progress))
639     {
640       return mKeyFrames->GetValue(progress, Dali::Animation::Linear);
641     }
642     return property;
643   }
644
645   KeyFrameBooleanPtr mKeyFrames;
646 };
647
648 struct KeyFrameNumberFunctor
649 {
650   KeyFrameNumberFunctor(KeyFrameNumberPtr keyFrames, Interpolation interpolation)
651   : mKeyFrames(keyFrames),mInterpolation(interpolation)
652   {
653   }
654
655   float operator()(float progress, const float& property)
656   {
657     if(mKeyFrames->IsActive(progress))
658     {
659       return mKeyFrames->GetValue(progress, mInterpolation);
660     }
661     return property;
662   }
663
664   KeyFrameNumberPtr mKeyFrames;
665   Interpolation mInterpolation;
666 };
667
668 struct KeyFrameIntegerFunctor
669 {
670   KeyFrameIntegerFunctor(KeyFrameIntegerPtr keyFrames, Interpolation interpolation)
671   : mKeyFrames(keyFrames),mInterpolation(interpolation)
672   {
673   }
674
675   float operator()(float progress, const int& property)
676   {
677     if(mKeyFrames->IsActive(progress))
678     {
679       return mKeyFrames->GetValue(progress, mInterpolation);
680     }
681     return property;
682   }
683
684   KeyFrameIntegerPtr mKeyFrames;
685   Interpolation mInterpolation;
686 };
687
688 struct KeyFrameVector2Functor
689 {
690   KeyFrameVector2Functor(KeyFrameVector2Ptr keyFrames, Interpolation interpolation)
691   : mKeyFrames(keyFrames),mInterpolation(interpolation)
692   {
693   }
694
695   Vector2 operator()(float progress, const Vector2& property)
696   {
697     if(mKeyFrames->IsActive(progress))
698     {
699       return mKeyFrames->GetValue(progress, mInterpolation);
700     }
701     return property;
702   }
703
704   KeyFrameVector2Ptr mKeyFrames;
705   Interpolation mInterpolation;
706 };
707
708
709 struct KeyFrameVector3Functor
710 {
711   KeyFrameVector3Functor(KeyFrameVector3Ptr keyFrames, Interpolation interpolation)
712   : mKeyFrames(keyFrames),mInterpolation(interpolation)
713   {
714   }
715
716   Vector3 operator()(float progress, const Vector3& property)
717   {
718     if(mKeyFrames->IsActive(progress))
719     {
720       return mKeyFrames->GetValue(progress, mInterpolation);
721     }
722     return property;
723   }
724
725   KeyFrameVector3Ptr mKeyFrames;
726   Interpolation mInterpolation;
727 };
728
729 struct KeyFrameVector4Functor
730 {
731   KeyFrameVector4Functor(KeyFrameVector4Ptr keyFrames, Interpolation interpolation)
732   : mKeyFrames(keyFrames),mInterpolation(interpolation)
733   {
734   }
735
736   Vector4 operator()(float progress, const Vector4& property)
737   {
738     if(mKeyFrames->IsActive(progress))
739     {
740       return mKeyFrames->GetValue(progress, mInterpolation);
741     }
742     return property;
743   }
744
745   KeyFrameVector4Ptr mKeyFrames;
746   Interpolation mInterpolation;
747 };
748
749 struct KeyFrameQuaternionFunctor
750 {
751   KeyFrameQuaternionFunctor(KeyFrameQuaternionPtr keyFrames)
752   : mKeyFrames(keyFrames)
753   {
754   }
755
756   Quaternion operator()(float progress, const Quaternion& property)
757   {
758     if(mKeyFrames->IsActive(progress))
759     {
760       return mKeyFrames->GetValue(progress, Dali::Animation::Linear);
761     }
762     return property;
763   }
764
765   KeyFrameQuaternionPtr mKeyFrames;
766 };
767
768 struct PathPositionFunctor
769 {
770   PathPositionFunctor( PathPtr path )
771   : mPath(path)
772   {
773   }
774
775   Vector3 operator()(float progress, const Vector3& property)
776   {
777     return mPath->SamplePosition(progress );
778   }
779
780   PathPtr mPath;
781 };
782
783 struct PathRotationFunctor
784 {
785   PathRotationFunctor( PathPtr path, const Vector3& forward )
786   : mPath(path),
787     mForward( forward )
788   {
789     mForward.Normalize();
790   }
791
792   Quaternion operator()(float progress, const Quaternion& property)
793   {
794     Vector3 tangent( mPath->SampleTangent(progress) );
795     return Quaternion( mForward, tangent );
796   }
797
798   PathPtr mPath;
799   Vector3 mForward;
800 };
801
802
803 } // namespace Internal
804
805 } // namespace Dali
806
807 #endif // __DALI_INTERNAL_SCENE_GRAPH_ANIMATOR_H__