2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/animation/animation-impl.h>
22 #include <dali/public-api/animation/alpha-functions.h>
23 #include <dali/public-api/animation/time-period.h>
24 #include <dali/public-api/common/dali-common.h>
25 #include <dali/public-api/object/type-registry.h>
26 #include <dali/public-api/math/vector2.h>
27 #include <dali/public-api/math/radian.h>
28 #include <dali/internal/event/actors/actor-impl.h>
29 #include <dali/internal/event/common/stage-impl.h>
30 #include <dali/internal/event/animation/animator-connector.h>
31 #include <dali/internal/event/animation/animation-playlist.h>
32 #include <dali/internal/event/common/notification-manager.h>
33 #include <dali/internal/update/manager/update-manager.h>
34 #include <dali/internal/event/effects/shader-effect-impl.h>
35 #include <dali/internal/event/common/thread-local-storage.h>
39 using Dali::Internal::SceneGraph::UpdateManager;
40 using Dali::Internal::SceneGraph::AnimatorBase;
41 using Dali::Internal::SceneGraph::Shader;
49 static bool SHOW_VALUE = true;
50 static bool HIDE_VALUE = false;
57 return Dali::Animation::New(0.f);
60 TypeRegistration mType( typeid(Dali::Animation), typeid(Dali::BaseHandle), Create );
62 SignalConnectorType signalConnector1( mType, Dali::Animation::SIGNAL_FINISHED, &Animation::DoConnectSignal );
64 TypeAction action1( mType, Dali::Animation::ACTION_PLAY, &Animation::DoAction );
65 TypeAction action2( mType, Dali::Animation::ACTION_STOP, &Animation::DoAction );
66 TypeAction action3( mType, Dali::Animation::ACTION_PAUSE, &Animation::DoAction );
68 const Dali::Animation::EndAction DEFAULT_END_ACTION( Dali::Animation::Bake );
69 const Dali::Animation::EndAction DEFAULT_DISCONNECT_ACTION( Dali::Animation::BakeFinal );
74 AnimationPtr Animation::New(float durationSeconds)
76 ThreadLocalStorage& tls = ThreadLocalStorage::Get();
77 UpdateManager& updateManager = tls.GetUpdateManager();
79 AnimationPlaylist& playlist = Stage::GetCurrent()->GetAnimationPlaylist();
81 AnimationPtr animation = new Animation( updateManager, playlist, durationSeconds, DEFAULT_END_ACTION, DEFAULT_DISCONNECT_ACTION, Dali::AlphaFunctions::Linear );
83 // Second-phase construction
84 animation->Initialize();
89 Animation::Animation( UpdateManager& updateManager, AnimationPlaylist& playlist, float durationSeconds, EndAction endAction, EndAction disconnectAction, AlphaFunction defaultAlpha )
90 : mUpdateManager( updateManager ),
91 mPlaylist( playlist ),
93 mNotificationCount( 0 ),
94 mFinishedCallback( NULL ),
95 mFinishedCallbackObject( NULL ),
96 mDurationSeconds( durationSeconds ),
99 mPlayRange( Vector2(0.0f,1.0f)),
100 mEndAction( endAction ),
101 mDisconnectAction( disconnectAction ),
102 mDefaultAlpha( defaultAlpha )
106 void Animation::Initialize()
108 // Connect to the animation playlist
109 mPlaylist.AnimationCreated( *this );
116 Animation::~Animation()
118 // Guard to allow handle destruction after Core has been destroyed
119 if ( Stage::IsInstalled() )
121 // Disconnect from the animation playlist
122 mPlaylist.AnimationDestroyed( *this );
124 DestroySceneObject();
130 void Animation::CreateSceneObject()
132 DALI_ASSERT_DEBUG( mAnimation == NULL );
134 // Create a new animation, temporarily owned
135 SceneGraph::Animation* animation = SceneGraph::Animation::New( mDurationSeconds, mSpeedFactor, mPlayRange, mIsLooping, mEndAction, mDisconnectAction );
137 // Keep a const pointer to the animation.
138 mAnimation = animation;
140 // Transfer animation ownership to the update manager through a message
141 AddAnimationMessage( mUpdateManager, animation );
144 void Animation::DestroySceneObject()
146 if ( mAnimation != NULL )
148 // Remove animation using a message to the update manager
149 RemoveAnimationMessage( mUpdateManager, *mAnimation );
154 void Animation::SetDuration(float seconds)
156 // Cache for public getters
157 mDurationSeconds = seconds;
159 // mAnimation is being used in a separate thread; queue a message to set the value
160 SetDurationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, seconds );
163 float Animation::GetDuration() const
165 // This is not animatable; the cached value is up-to-date.
166 return mDurationSeconds;
169 void Animation::SetLooping(bool looping)
171 // Cache for public getters
172 mIsLooping = looping;
174 // mAnimation is being used in a separate thread; queue a message to set the value
175 SetLoopingMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, looping );
178 bool Animation::IsLooping() const
180 // This is not animatable; the cached value is up-to-date.
184 void Animation::SetEndAction(EndAction action)
186 // Cache for public getters
189 // mAnimation is being used in a separate thread; queue a message to set the value
190 SetEndActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
193 Dali::Animation::EndAction Animation::GetEndAction() const
195 // This is not animatable; the cached value is up-to-date.
199 void Animation::SetDisconnectAction(EndAction action)
201 // Cache for public getters
202 mDisconnectAction = action;
204 // mAnimation is being used in a separate thread; queue a message to set the value
205 SetDisconnectActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
208 Dali::Animation::EndAction Animation::GetDisconnectAction() const
210 // This is not animatable; the cached value is up-to-date.
211 return mDisconnectAction;
214 void Animation::Play()
216 // Update the current playlist
217 mPlaylist.OnPlay( *this );
219 // mAnimation is being used in a separate thread; queue a Play message
220 PlayAnimationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation );
223 void Animation::PlayFrom( float progress )
225 if( progress >= mPlayRange.x && progress <= mPlayRange.y )
227 // Update the current playlist
228 mPlaylist.OnPlay( *this );
230 // mAnimation is being used in a separate thread; queue a Play message
231 PlayAnimationFromMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, progress );
235 void Animation::Pause()
237 // mAnimation is being used in a separate thread; queue a Pause message
238 PauseAnimationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation );
241 void Animation::Stop()
243 // mAnimation is being used in a separate thread; queue a Stop message
244 StopAnimationMessage( mUpdateManager, *mAnimation );
247 void Animation::Clear()
249 DALI_ASSERT_DEBUG(mAnimation);
251 // Remove all the connectors
254 // Replace the old scene-object with a new one
255 DestroySceneObject();
258 // Reset the notification count, since the new scene-object has never been played
259 mNotificationCount = 0;
261 // Update the current playlist
262 mPlaylist.OnClear( *this );
265 void Animation::AnimateBy(Property& target, Property::Value& relativeValue)
267 AnimateBy(target, relativeValue, AlphaFunctions::Default, mDurationSeconds);
270 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha)
272 AnimateBy(target, relativeValue, alpha, mDurationSeconds);
275 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, TimePeriod period)
277 AnimateBy(target, relativeValue, AlphaFunctions::Default, period);
280 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha, TimePeriod period)
282 ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
284 ExtendDuration( period );
286 switch ( relativeValue.GetType() )
288 case Property::BOOLEAN:
290 AddAnimatorConnector( AnimatorConnector<bool>::New( proxy,
291 target.propertyIndex,
292 target.componentIndex,
293 AnimateByBoolean(relativeValue.Get<bool>()),
299 case Property::FLOAT:
301 AddAnimatorConnector( AnimatorConnector<float>::New( proxy,
302 target.propertyIndex,
303 target.componentIndex,
304 AnimateByFloat(relativeValue.Get<float>()),
310 case Property::INTEGER:
312 AddAnimatorConnector( AnimatorConnector<int>::New( proxy,
313 target.propertyIndex,
314 target.componentIndex,
315 AnimateByInteger(relativeValue.Get<int>()),
321 case Property::VECTOR2:
323 AddAnimatorConnector( AnimatorConnector<Vector2>::New( proxy,
324 target.propertyIndex,
325 target.componentIndex,
326 AnimateByVector2(relativeValue.Get<Vector2>()),
332 case Property::VECTOR3:
334 AddAnimatorConnector( AnimatorConnector<Vector3>::New( proxy,
335 target.propertyIndex,
336 target.componentIndex,
337 AnimateByVector3(relativeValue.Get<Vector3>()),
343 case Property::VECTOR4:
345 AddAnimatorConnector( AnimatorConnector<Vector4>::New( proxy,
346 target.propertyIndex,
347 target.componentIndex,
348 AnimateByVector4(relativeValue.Get<Vector4>()),
354 case Property::ROTATION:
356 AngleAxis angleAxis = relativeValue.Get<AngleAxis>();
358 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( proxy,
359 target.propertyIndex,
360 target.componentIndex,
361 RotateByAngleAxis(angleAxis.angle, angleAxis.axis),
368 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
373 void Animation::AnimateTo(Property& target, Property::Value& destinationValue)
375 AnimateTo(target, destinationValue, AlphaFunctions::Default, mDurationSeconds);
378 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha)
380 AnimateTo(target, destinationValue, alpha, mDurationSeconds);
383 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, TimePeriod period)
385 AnimateTo(target, destinationValue, AlphaFunctions::Default, period);
388 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
390 ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
392 AnimateTo( proxy, target.propertyIndex, target.componentIndex, destinationValue, alpha, period );
395 void Animation::AnimateTo(ProxyObject& targetObject, Property::Index targetPropertyIndex, int componentIndex, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
397 Property::Type type = targetObject.GetPropertyType(targetPropertyIndex);
398 if(componentIndex != Property::INVALID_COMPONENT_INDEX)
400 if( type == Property::VECTOR2
401 || type == Property::VECTOR3
402 || type == Property::VECTOR4 )
404 type = Property::FLOAT;
407 DALI_ASSERT_ALWAYS( type == destinationValue.GetType() && "DestinationValue does not match Target Property type" );
409 ExtendDuration( period );
411 switch (destinationValue.GetType())
413 case Property::BOOLEAN:
415 AddAnimatorConnector( AnimatorConnector<bool>::New(targetObject,
418 AnimateToBoolean(destinationValue.Get<bool>()),
424 case Property::FLOAT:
426 AddAnimatorConnector( AnimatorConnector<float>::New(targetObject,
429 AnimateToFloat(destinationValue.Get<float>()),
435 case Property::INTEGER:
437 AddAnimatorConnector( AnimatorConnector<int>::New(targetObject,
440 AnimateToInteger(destinationValue.Get<int>()),
446 case Property::VECTOR2:
448 AddAnimatorConnector( AnimatorConnector<Vector2>::New(targetObject,
451 AnimateToVector2(destinationValue.Get<Vector2>()),
457 case Property::VECTOR3:
459 if ( Dali::Actor::SIZE == targetPropertyIndex )
461 // Test whether this is actually an Actor
462 Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
465 // Notify the actor that its size is being animated
466 maybeActor->NotifySizeAnimation( *this, destinationValue.Get<Vector3>() );
470 AddAnimatorConnector( AnimatorConnector<Vector3>::New(targetObject,
473 AnimateToVector3(destinationValue.Get<Vector3>()),
479 case Property::VECTOR4:
481 AddAnimatorConnector( AnimatorConnector<Vector4>::New(targetObject,
484 AnimateToVector4(destinationValue.Get<Vector4>()),
490 case Property::ROTATION:
492 AddAnimatorConnector( AnimatorConnector<Quaternion>::New(targetObject,
495 RotateToQuaternion(destinationValue.Get<Quaternion>()),
502 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
507 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames)
509 AnimateBetween(target, keyFrames, mDefaultAlpha, mDurationSeconds);
512 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period)
514 AnimateBetween(target, keyFrames, mDefaultAlpha, period);
517 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha)
519 AnimateBetween(target, keyFrames, alpha, mDurationSeconds);
522 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period)
524 ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
526 ExtendDuration( period );
528 switch(keyFrames.GetType())
530 case Dali::Property::BOOLEAN:
532 const KeyFrameBoolean* kf;
533 GetSpecialization(keyFrames, kf);
534 KeyFrameBooleanPtr kfCopy = KeyFrameBoolean::Clone(*kf);
535 AddAnimatorConnector( AnimatorConnector<bool>::New( proxy,
536 target.propertyIndex,
537 target.componentIndex,
538 KeyFrameBooleanFunctor(kfCopy),
544 case Dali::Property::FLOAT:
546 const KeyFrameNumber* kf;
547 GetSpecialization(keyFrames, kf);
548 KeyFrameNumberPtr kfCopy = KeyFrameNumber::Clone(*kf);
549 AddAnimatorConnector( AnimatorConnector<float>::New( proxy,
550 target.propertyIndex,
551 target.componentIndex,
552 KeyFrameNumberFunctor(kfCopy),
558 case Dali::Property::INTEGER:
560 const KeyFrameInteger* kf;
561 GetSpecialization(keyFrames, kf);
562 KeyFrameIntegerPtr kfCopy = KeyFrameInteger::Clone(*kf);
563 AddAnimatorConnector( AnimatorConnector<int>::New( proxy,
564 target.propertyIndex,
565 target.componentIndex,
566 KeyFrameIntegerFunctor(kfCopy),
572 case Dali::Property::VECTOR2:
574 const KeyFrameVector2* kf;
575 GetSpecialization(keyFrames, kf);
576 KeyFrameVector2Ptr kfCopy = KeyFrameVector2::Clone(*kf);
577 AddAnimatorConnector( AnimatorConnector<Vector2>::New( proxy,
578 target.propertyIndex,
579 target.componentIndex,
580 KeyFrameVector2Functor(kfCopy),
586 case Dali::Property::VECTOR3:
588 const KeyFrameVector3* kf;
589 GetSpecialization(keyFrames, kf);
590 KeyFrameVector3Ptr kfCopy = KeyFrameVector3::Clone(*kf);
591 AddAnimatorConnector( AnimatorConnector<Vector3>::New( proxy,
592 target.propertyIndex,
593 target.componentIndex,
594 KeyFrameVector3Functor(kfCopy),
600 case Dali::Property::VECTOR4:
602 const KeyFrameVector4* kf;
603 GetSpecialization(keyFrames, kf);
604 KeyFrameVector4Ptr kfCopy = KeyFrameVector4::Clone(*kf);
605 AddAnimatorConnector( AnimatorConnector<Vector4>::New( proxy,
606 target.propertyIndex,
607 target.componentIndex,
608 KeyFrameVector4Functor(kfCopy),
614 case Dali::Property::ROTATION:
616 const KeyFrameQuaternion* kf;
617 GetSpecialization(keyFrames, kf);
618 KeyFrameQuaternionPtr kfCopy = KeyFrameQuaternion::Clone(*kf);
619 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( proxy,
620 target.propertyIndex,
621 target.componentIndex,
622 KeyFrameQuaternionFunctor(kfCopy),
628 default: // not all property types are animateable
633 void Animation::Animate( Property& target, Property::Type targetType, AnyFunction& func )
635 Animate( target, targetType, func, mDefaultAlpha, mDurationSeconds );
638 void Animation::Animate( Property& target, Property::Type targetType, AnyFunction& func, AlphaFunction& alpha )
640 Animate( target, targetType, func, alpha, mDurationSeconds );
643 void Animation::Animate( Property& target, Property::Type targetType, AnyFunction& func, TimePeriod period )
645 Animate( target, targetType, func, mDefaultAlpha, period );
648 void Animation::Animate( Property& target, Property::Type targetType, AnyFunction& func, AlphaFunction& alpha, TimePeriod period )
650 Property::Type type = target.object.GetPropertyType(target.propertyIndex);
651 if(target.componentIndex != Property::INVALID_COMPONENT_INDEX)
653 if( type == Property::VECTOR2
654 || type == Property::VECTOR3
655 || type == Property::VECTOR4 )
657 type = Property::FLOAT;
660 DALI_ASSERT_ALWAYS( type == targetType && "Animation function must match target property type" );
662 ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
664 ExtendDuration( period );
666 switch ( targetType )
668 case Property::BOOLEAN:
670 AddAnimatorConnector( AnimatorConnector<bool>::New(proxy,
671 target.propertyIndex,
672 target.componentIndex,
673 AnyCast< AnimatorFunctionBool >( func ),
679 case Property::FLOAT:
681 AddAnimatorConnector( AnimatorConnector<float>::New(proxy,
682 target.propertyIndex,
683 target.componentIndex,
684 AnyCast< AnimatorFunctionFloat >( func ),
690 case Property::INTEGER:
692 AddAnimatorConnector( AnimatorConnector<int>::New(proxy,
693 target.propertyIndex,
694 target.componentIndex,
695 AnyCast< AnimatorFunctionInteger >( func ),
701 case Property::VECTOR2:
703 AddAnimatorConnector( AnimatorConnector<Vector2>::New(proxy,
704 target.propertyIndex,
705 target.componentIndex,
706 AnyCast< AnimatorFunctionVector2 >( func ),
712 case Property::VECTOR3:
714 AddAnimatorConnector( AnimatorConnector<Vector3>::New(proxy,
715 target.propertyIndex,
716 target.componentIndex,
717 AnyCast< AnimatorFunctionVector3 >( func ),
723 case Property::VECTOR4:
725 AddAnimatorConnector( AnimatorConnector<Vector4>::New(proxy,
726 target.propertyIndex,
727 target.componentIndex,
728 AnyCast< AnimatorFunctionVector4 >( func ),
734 case Property::ROTATION:
736 AddAnimatorConnector( AnimatorConnector<Quaternion>::New(proxy,
737 target.propertyIndex,
738 target.componentIndex,
739 AnyCast< AnimatorFunctionQuaternion >( func ),
746 DALI_ASSERT_ALWAYS(false && "Property type enumeration out of bounds" ); // should never come here
751 bool Animation::HasFinished()
753 bool hasFinished(false);
754 const int playCount(mAnimation->GetPlayCount());
756 // If the play count has been incremented, then another notification is required
757 if (playCount > mNotificationCount)
759 // Note that only one signal is emitted, if the animation has been played repeatedly
760 mNotificationCount = playCount;
768 Dali::Animation::AnimationSignalV2& Animation::FinishedSignal()
770 return mFinishedSignal;
773 void Animation::EmitSignalFinish()
775 if ( !mFinishedSignal.Empty() )
777 Dali::Animation handle( this );
778 mFinishedSignal.Emit( handle );
781 // This callback is used internally, to avoid the overhead of using a signal.
782 if ( mFinishedCallback )
784 mFinishedCallback( mFinishedCallbackObject );
788 bool Animation::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
790 bool connected( true );
791 Animation* animation = dynamic_cast<Animation*>(object);
793 if ( Dali::Animation::SIGNAL_FINISHED == signalName )
795 animation->FinishedSignal().Connect( tracker, functor );
799 // signalName does not match any signal
806 void Animation::SetFinishedCallback( FinishedCallback callback, Object* object )
808 mFinishedCallback = callback;
809 mFinishedCallbackObject = object;
812 void Animation::AddAnimatorConnector( AnimatorConnectorBase* connector )
814 DALI_ASSERT_DEBUG( NULL != connector );
816 connector->SetParent(*this);
818 mConnectors.PushBack( connector );
821 void Animation::MoveBy(Actor& actor, float x, float y, float z)
823 MoveBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
826 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha)
828 MoveBy(actor, displacement, alpha, 0.0f, GetDuration());
831 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha, float delaySeconds, float durationSeconds)
833 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
835 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
836 Dali::Actor::POSITION,
837 Property::INVALID_COMPONENT_INDEX,
838 AnimateByVector3(displacement),
840 TimePeriod(delaySeconds, durationSeconds) ) );
843 void Animation::MoveTo(Actor& actor, float x, float y, float z)
845 MoveTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
848 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha)
850 MoveTo(actor, position, alpha, 0.0f, GetDuration());
853 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha, float delaySeconds, float durationSeconds)
855 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
857 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
858 Dali::Actor::POSITION,
859 Property::INVALID_COMPONENT_INDEX,
860 AnimateToVector3(position),
862 TimePeriod(delaySeconds, durationSeconds) ) );
865 void Animation::Move(Actor& actor, AnimatorFunctionVector3 func, AlphaFunction alpha, float delaySeconds, float durationSeconds)
867 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
869 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
870 Dali::Actor::POSITION,
871 Property::INVALID_COMPONENT_INDEX,
874 TimePeriod(delaySeconds, durationSeconds) ) );
877 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis)
879 RotateBy(actor, angle, axis, mDefaultAlpha, 0.0f, GetDuration());
882 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
884 RotateBy(actor, angle, axis, alpha, 0.0f, GetDuration());
887 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
889 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
891 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
892 Dali::Actor::ROTATION,
893 Property::INVALID_COMPONENT_INDEX,
894 RotateByAngleAxis(angle, axis),
896 TimePeriod(delaySeconds, durationSeconds) ) );
899 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis)
901 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
902 normalizedAxis.Normalize();
904 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
906 RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
909 void Animation::RotateTo(Actor& actor, const Quaternion& orientation)
911 RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
914 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
916 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
917 normalizedAxis.Normalize();
919 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
921 RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
924 void Animation::RotateTo(Actor& actor, const Quaternion& orientation, AlphaFunction alpha)
926 RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
929 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
931 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
932 normalizedAxis.Normalize();
934 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
936 RotateTo(actor, orientation, alpha, delaySeconds, durationSeconds);
939 void Animation::RotateTo(Actor& actor, const Quaternion& rotation, AlphaFunction alpha, float delaySeconds, float durationSeconds)
941 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
943 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
944 Dali::Actor::ROTATION,
945 Property::INVALID_COMPONENT_INDEX,
946 RotateToQuaternion(rotation),
948 TimePeriod(delaySeconds, durationSeconds) ) );
951 void Animation::Rotate(Actor& actor, AnimatorFunctionQuaternion func, AlphaFunction alpha, float delaySeconds, float durationSeconds)
953 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
955 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
956 Dali::Actor::ROTATION,
957 Property::INVALID_COMPONENT_INDEX,
960 TimePeriod(delaySeconds, durationSeconds) ) );
963 void Animation::ScaleBy(Actor& actor, float x, float y, float z)
965 ScaleBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
968 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha)
970 ScaleBy(actor, scale, alpha, 0.0f, GetDuration());
973 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
975 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
977 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
979 Property::INVALID_COMPONENT_INDEX,
980 AnimateByVector3(scale),
982 TimePeriod(delaySeconds, durationSeconds) ) );
985 void Animation::ScaleTo(Actor& actor, float x, float y, float z)
987 ScaleTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
990 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha)
992 ScaleTo(actor, scale, alpha, 0.0f, GetDuration());
995 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
997 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
999 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1001 Property::INVALID_COMPONENT_INDEX,
1002 AnimateToVector3(scale),
1004 TimePeriod(delaySeconds, durationSeconds) ) );
1007 void Animation::Show(Actor& actor, float delaySeconds)
1009 ExtendDuration( TimePeriod(delaySeconds, 0) );
1011 AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
1012 Dali::Actor::VISIBLE,
1013 Property::INVALID_COMPONENT_INDEX,
1014 AnimateToBoolean(SHOW_VALUE),
1015 AlphaFunctions::Default,
1016 TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
1019 void Animation::Hide(Actor& actor, float delaySeconds)
1021 ExtendDuration( TimePeriod(delaySeconds, 0) );
1023 AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
1024 Dali::Actor::VISIBLE,
1025 Property::INVALID_COMPONENT_INDEX,
1026 AnimateToBoolean(HIDE_VALUE),
1027 AlphaFunctions::Default,
1028 TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
1031 void Animation::OpacityBy(Actor& actor, float opacity)
1033 OpacityBy(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
1036 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha)
1038 OpacityBy(actor, opacity, alpha, 0.0f, GetDuration());
1041 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1043 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1045 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
1047 Property::INVALID_COMPONENT_INDEX,
1048 AnimateByOpacity(opacity),
1050 TimePeriod(delaySeconds, durationSeconds) ) );
1053 void Animation::OpacityTo(Actor& actor, float opacity)
1055 OpacityTo(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
1058 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha)
1060 OpacityTo(actor, opacity, alpha, 0.0f, GetDuration());
1063 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1065 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1067 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
1069 Property::INVALID_COMPONENT_INDEX,
1070 AnimateToOpacity(opacity),
1072 TimePeriod(delaySeconds, durationSeconds) ) );
1075 void Animation::ColorBy(Actor& actor, const Vector4& color)
1077 ColorBy(actor, color, mDefaultAlpha, 0.0f, GetDuration());
1080 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha)
1082 ColorBy(actor, color, alpha, 0.0f, GetDuration());
1085 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1087 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1089 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
1091 Property::INVALID_COMPONENT_INDEX,
1092 AnimateByVector4(color),
1094 TimePeriod(delaySeconds, durationSeconds) ) );
1097 void Animation::ColorTo(Actor& actor, const Vector4& color)
1099 ColorTo(actor, color, mDefaultAlpha, 0.0f, GetDuration());
1102 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha)
1104 ColorTo(actor, color, alpha, 0.0f, GetDuration());
1107 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1109 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1111 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
1113 Property::INVALID_COMPONENT_INDEX,
1114 AnimateToVector4(color),
1116 TimePeriod(delaySeconds, durationSeconds) ) );
1119 void Animation::Resize(Actor& actor, float width, float height)
1121 Resize(actor, width, height, mDefaultAlpha, 0.0f, GetDuration());
1124 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha)
1126 Resize(actor, width, height, alpha, 0.0f, GetDuration());
1129 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1131 Vector3 targetSize( width, height, min(width, height) );
1133 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1135 // Notify the actor impl that its size is being animated
1136 actor.NotifySizeAnimation( *this, targetSize );
1138 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1140 Property::INVALID_COMPONENT_INDEX,
1141 AnimateToVector3(targetSize),
1143 TimePeriod(delaySeconds, durationSeconds) ) );
1146 void Animation::Resize(Actor& actor, const Vector3& size)
1148 Resize(actor, size, mDefaultAlpha, 0.0f, GetDuration());
1151 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha)
1153 Resize(actor, size, alpha, 0.0f, GetDuration());
1156 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1158 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1160 // Notify the actor impl that its size is being animated
1161 actor.NotifySizeAnimation( *this, size );
1163 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1165 Property::INVALID_COMPONENT_INDEX,
1166 AnimateToVector3(size),
1168 TimePeriod(delaySeconds, durationSeconds) ) );
1171 bool Animation::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
1174 Animation* animation = dynamic_cast<Animation*>(object);
1178 if(Dali::Animation::ACTION_PLAY == actionName)
1180 if(attributes.size() > 0)
1182 animation->SetDuration(attributes[0].Get<float>());
1188 else if(Dali::Animation::ACTION_STOP == actionName)
1193 else if(Dali::Animation::ACTION_PAUSE == actionName)
1203 void Animation::SetCurrentProgress(float progress)
1205 if( mAnimation && progress >= mPlayRange.x && progress <= mPlayRange.y )
1207 // mAnimation is being used in a separate thread; queue a message to set the current progress
1208 SetCurrentProgressMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, progress );
1212 float Animation::GetCurrentProgress()
1216 return mAnimation->GetCurrentProgress();
1222 void Animation::ExtendDuration( const TimePeriod& timePeriod )
1224 float duration = timePeriod.delaySeconds + timePeriod.durationSeconds;
1226 if( duration > mDurationSeconds )
1228 SetDuration( duration );
1232 void Animation::SetSpeedFactor( float factor )
1236 mSpeedFactor = factor;
1237 SetSpeedFactorMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, factor );
1241 float Animation::GetSpeedFactor() const
1243 return mSpeedFactor;
1246 void Animation::SetPlayRange( const Vector2& range)
1248 //Make sure the range specified is between 0.0 and 1.0
1249 if( range.x >= 0.0f && range.x <= 1.0f && range.y >= 0.0f && range.y <= 1.0f )
1251 Vector2 orderedRange( range );
1252 //If the range is not in order swap values
1253 if( range.x > range.y )
1255 orderedRange = Vector2(range.y, range.x);
1258 // Cache for public getters
1259 mPlayRange = orderedRange;
1261 // mAnimation is being used in a separate thread; queue a message to set play range
1262 SetPlayRangeMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, orderedRange );
1266 Vector2 Animation::GetPlayRange() const
1272 } // namespace Internal