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>
37 using Dali::Internal::SceneGraph::UpdateManager;
38 using Dali::Internal::SceneGraph::AnimatorBase;
39 using Dali::Internal::SceneGraph::Shader;
47 static bool SHOW_VALUE = true;
48 static bool HIDE_VALUE = false;
55 return Dali::Animation::New(0.f);
58 TypeRegistration mType( typeid(Dali::Animation), typeid(Dali::BaseHandle), Create );
60 SignalConnectorType signalConnector1( mType, Dali::Animation::SIGNAL_FINISHED, &Animation::DoConnectSignal );
62 TypeAction action1( mType, Dali::Animation::ACTION_PLAY, &Animation::DoAction );
63 TypeAction action2( mType, Dali::Animation::ACTION_STOP, &Animation::DoAction );
64 TypeAction action3( mType, Dali::Animation::ACTION_PAUSE, &Animation::DoAction );
66 const Dali::Animation::EndAction DEFAULT_END_ACTION( Dali::Animation::Bake );
67 const Dali::Animation::EndAction DEFAULT_DISCONNECT_ACTION( Dali::Animation::BakeFinal );
68 const Dali::Animation::Interpolation DEFAULT_INTERPOLATION( Dali::Animation::Linear );
73 AnimationPtr Animation::New(float durationSeconds)
75 ThreadLocalStorage& tls = ThreadLocalStorage::Get();
76 UpdateManager& updateManager = tls.GetUpdateManager();
78 AnimationPlaylist& playlist = Stage::GetCurrent()->GetAnimationPlaylist();
80 AnimationPtr animation = new Animation( updateManager, playlist, durationSeconds, DEFAULT_END_ACTION, DEFAULT_DISCONNECT_ACTION, Dali::AlphaFunctions::Linear );
82 // Second-phase construction
83 animation->Initialize();
88 Animation::Animation( UpdateManager& updateManager, AnimationPlaylist& playlist, float durationSeconds, EndAction endAction, EndAction disconnectAction, AlphaFunction defaultAlpha )
89 : mUpdateManager( updateManager ),
90 mPlaylist( playlist ),
92 mNotificationCount( 0 ),
93 mFinishedCallback( NULL ),
94 mFinishedCallbackObject( NULL ),
95 mDurationSeconds( durationSeconds ),
98 mPlayRange( Vector2(0.0f,1.0f)),
99 mEndAction( endAction ),
100 mDisconnectAction( disconnectAction ),
101 mDefaultAlpha( defaultAlpha )
105 void Animation::Initialize()
107 // Connect to the animation playlist
108 mPlaylist.AnimationCreated( *this );
115 Animation::~Animation()
117 // Guard to allow handle destruction after Core has been destroyed
118 if ( Stage::IsInstalled() )
120 // Disconnect from the animation playlist
121 mPlaylist.AnimationDestroyed( *this );
123 DestroySceneObject();
129 void Animation::CreateSceneObject()
131 DALI_ASSERT_DEBUG( mAnimation == NULL );
133 // Create a new animation, temporarily owned
134 SceneGraph::Animation* animation = SceneGraph::Animation::New( mDurationSeconds, mSpeedFactor, mPlayRange, mIsLooping, mEndAction, mDisconnectAction );
136 // Keep a const pointer to the animation.
137 mAnimation = animation;
139 // Transfer animation ownership to the update manager through a message
140 AddAnimationMessage( mUpdateManager, animation );
143 void Animation::DestroySceneObject()
145 if ( mAnimation != NULL )
147 // Remove animation using a message to the update manager
148 RemoveAnimationMessage( mUpdateManager, *mAnimation );
153 void Animation::SetDuration(float seconds)
155 // Cache for public getters
156 mDurationSeconds = seconds;
158 // mAnimation is being used in a separate thread; queue a message to set the value
159 SetDurationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, seconds );
162 float Animation::GetDuration() const
164 // This is not animatable; the cached value is up-to-date.
165 return mDurationSeconds;
168 void Animation::SetLooping(bool looping)
170 // Cache for public getters
171 mIsLooping = looping;
173 // mAnimation is being used in a separate thread; queue a message to set the value
174 SetLoopingMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, looping );
177 bool Animation::IsLooping() const
179 // This is not animatable; the cached value is up-to-date.
183 void Animation::SetEndAction(EndAction action)
185 // Cache for public getters
188 // mAnimation is being used in a separate thread; queue a message to set the value
189 SetEndActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
192 Dali::Animation::EndAction Animation::GetEndAction() const
194 // This is not animatable; the cached value is up-to-date.
198 void Animation::SetDisconnectAction(EndAction action)
200 // Cache for public getters
201 mDisconnectAction = action;
203 // mAnimation is being used in a separate thread; queue a message to set the value
204 SetDisconnectActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
207 Dali::Animation::EndAction Animation::GetDisconnectAction() const
209 // This is not animatable; the cached value is up-to-date.
210 return mDisconnectAction;
213 void Animation::Play()
215 // Update the current playlist
216 mPlaylist.OnPlay( *this );
218 // mAnimation is being used in a separate thread; queue a Play message
219 PlayAnimationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation );
222 void Animation::PlayFrom( float progress )
224 if( progress >= mPlayRange.x && progress <= mPlayRange.y )
226 // Update the current playlist
227 mPlaylist.OnPlay( *this );
229 // mAnimation is being used in a separate thread; queue a Play message
230 PlayAnimationFromMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, progress );
234 void Animation::Pause()
236 // mAnimation is being used in a separate thread; queue a Pause message
237 PauseAnimationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation );
240 void Animation::Stop()
242 // mAnimation is being used in a separate thread; queue a Stop message
243 StopAnimationMessage( mUpdateManager, *mAnimation );
246 void Animation::Clear()
248 DALI_ASSERT_DEBUG(mAnimation);
250 // Remove all the connectors
253 // Replace the old scene-object with a new one
254 DestroySceneObject();
257 // Reset the notification count, since the new scene-object has never been played
258 mNotificationCount = 0;
260 // Update the current playlist
261 mPlaylist.OnClear( *this );
264 void Animation::AnimateBy(Property& target, Property::Value& relativeValue)
266 AnimateBy(target, relativeValue, AlphaFunctions::Default, mDurationSeconds);
269 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha)
271 AnimateBy(target, relativeValue, alpha, mDurationSeconds);
274 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, TimePeriod period)
276 AnimateBy(target, relativeValue, AlphaFunctions::Default, period);
279 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha, TimePeriod period)
281 ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
283 ExtendDuration( period );
285 switch ( relativeValue.GetType() )
287 case Property::BOOLEAN:
289 AddAnimatorConnector( AnimatorConnector<bool>::New( proxy,
290 target.propertyIndex,
291 target.componentIndex,
292 AnimateByBoolean(relativeValue.Get<bool>()),
298 case Property::FLOAT:
300 AddAnimatorConnector( AnimatorConnector<float>::New( proxy,
301 target.propertyIndex,
302 target.componentIndex,
303 AnimateByFloat(relativeValue.Get<float>()),
309 case Property::INTEGER:
311 AddAnimatorConnector( AnimatorConnector<int>::New( proxy,
312 target.propertyIndex,
313 target.componentIndex,
314 AnimateByInteger(relativeValue.Get<int>()),
320 case Property::VECTOR2:
322 AddAnimatorConnector( AnimatorConnector<Vector2>::New( proxy,
323 target.propertyIndex,
324 target.componentIndex,
325 AnimateByVector2(relativeValue.Get<Vector2>()),
331 case Property::VECTOR3:
333 AddAnimatorConnector( AnimatorConnector<Vector3>::New( proxy,
334 target.propertyIndex,
335 target.componentIndex,
336 AnimateByVector3(relativeValue.Get<Vector3>()),
342 case Property::VECTOR4:
344 AddAnimatorConnector( AnimatorConnector<Vector4>::New( proxy,
345 target.propertyIndex,
346 target.componentIndex,
347 AnimateByVector4(relativeValue.Get<Vector4>()),
353 case Property::ROTATION:
355 AngleAxis angleAxis = relativeValue.Get<AngleAxis>();
357 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( proxy,
358 target.propertyIndex,
359 target.componentIndex,
360 RotateByAngleAxis(angleAxis.angle, angleAxis.axis),
367 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
372 void Animation::AnimateTo(Property& target, Property::Value& destinationValue)
374 AnimateTo(target, destinationValue, AlphaFunctions::Default, mDurationSeconds);
377 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha)
379 AnimateTo(target, destinationValue, alpha, mDurationSeconds);
382 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, TimePeriod period)
384 AnimateTo(target, destinationValue, AlphaFunctions::Default, period);
387 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
389 ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
391 AnimateTo( proxy, target.propertyIndex, target.componentIndex, destinationValue, alpha, period );
394 void Animation::AnimateTo(ProxyObject& targetObject, Property::Index targetPropertyIndex, int componentIndex, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
396 Property::Type type = targetObject.GetPropertyType(targetPropertyIndex);
397 if(componentIndex != Property::INVALID_COMPONENT_INDEX)
399 if( type == Property::VECTOR2
400 || type == Property::VECTOR3
401 || type == Property::VECTOR4 )
403 type = Property::FLOAT;
406 DALI_ASSERT_ALWAYS( type == destinationValue.GetType() && "DestinationValue does not match Target Property type" );
408 ExtendDuration( period );
410 switch (destinationValue.GetType())
412 case Property::BOOLEAN:
414 AddAnimatorConnector( AnimatorConnector<bool>::New(targetObject,
417 AnimateToBoolean(destinationValue.Get<bool>()),
423 case Property::FLOAT:
425 AddAnimatorConnector( AnimatorConnector<float>::New(targetObject,
428 AnimateToFloat(destinationValue.Get<float>()),
434 case Property::INTEGER:
436 AddAnimatorConnector( AnimatorConnector<int>::New(targetObject,
439 AnimateToInteger(destinationValue.Get<int>()),
445 case Property::VECTOR2:
447 AddAnimatorConnector( AnimatorConnector<Vector2>::New(targetObject,
450 AnimateToVector2(destinationValue.Get<Vector2>()),
456 case Property::VECTOR3:
458 if ( Dali::Actor::SIZE == targetPropertyIndex )
460 // Test whether this is actually an Actor
461 Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
464 // Notify the actor that its size is being animated
465 maybeActor->NotifySizeAnimation( *this, destinationValue.Get<Vector3>() );
469 AddAnimatorConnector( AnimatorConnector<Vector3>::New(targetObject,
472 AnimateToVector3(destinationValue.Get<Vector3>()),
478 case Property::VECTOR4:
480 AddAnimatorConnector( AnimatorConnector<Vector4>::New(targetObject,
483 AnimateToVector4(destinationValue.Get<Vector4>()),
489 case Property::ROTATION:
491 AddAnimatorConnector( AnimatorConnector<Quaternion>::New(targetObject,
494 RotateToQuaternion(destinationValue.Get<Quaternion>()),
501 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
506 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames)
508 AnimateBetween(target, keyFrames, mDefaultAlpha, mDurationSeconds, DEFAULT_INTERPOLATION );
511 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Interpolation interpolation )
513 AnimateBetween(target, keyFrames, mDefaultAlpha, mDurationSeconds, interpolation );
516 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period)
518 AnimateBetween(target, keyFrames, mDefaultAlpha, period, DEFAULT_INTERPOLATION);
521 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period, Interpolation interpolation)
523 AnimateBetween(target, keyFrames, mDefaultAlpha, period, interpolation);
526 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha)
528 AnimateBetween(target, keyFrames, alpha, mDurationSeconds, DEFAULT_INTERPOLATION);
531 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, Interpolation interpolation)
533 AnimateBetween(target, keyFrames, alpha, mDurationSeconds, interpolation);
536 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period)
538 AnimateBetween(target, keyFrames, alpha, period, DEFAULT_INTERPOLATION);
541 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period, Interpolation interpolation)
543 ProxyObject& proxy = dynamic_cast<ProxyObject&>( GetImplementation(target.object) );
545 ExtendDuration( period );
547 switch(keyFrames.GetType())
549 case Dali::Property::BOOLEAN:
551 const KeyFrameBoolean* kf;
552 GetSpecialization(keyFrames, kf);
553 KeyFrameBooleanPtr kfCopy = KeyFrameBoolean::Clone(*kf);
554 AddAnimatorConnector( AnimatorConnector<bool>::New( proxy,
555 target.propertyIndex,
556 target.componentIndex,
557 KeyFrameBooleanFunctor(kfCopy),
563 case Dali::Property::FLOAT:
565 const KeyFrameNumber* kf;
566 GetSpecialization(keyFrames, kf);
567 KeyFrameNumberPtr kfCopy = KeyFrameNumber::Clone(*kf);
568 AddAnimatorConnector( AnimatorConnector<float>::New( proxy,
569 target.propertyIndex,
570 target.componentIndex,
571 KeyFrameNumberFunctor(kfCopy,interpolation),
577 case Dali::Property::INTEGER:
579 const KeyFrameInteger* kf;
580 GetSpecialization(keyFrames, kf);
581 KeyFrameIntegerPtr kfCopy = KeyFrameInteger::Clone(*kf);
582 AddAnimatorConnector( AnimatorConnector<int>::New( proxy,
583 target.propertyIndex,
584 target.componentIndex,
585 KeyFrameIntegerFunctor(kfCopy,interpolation),
591 case Dali::Property::VECTOR2:
593 const KeyFrameVector2* kf;
594 GetSpecialization(keyFrames, kf);
595 KeyFrameVector2Ptr kfCopy = KeyFrameVector2::Clone(*kf);
596 AddAnimatorConnector( AnimatorConnector<Vector2>::New( proxy,
597 target.propertyIndex,
598 target.componentIndex,
599 KeyFrameVector2Functor(kfCopy,interpolation),
605 case Dali::Property::VECTOR3:
607 const KeyFrameVector3* kf;
608 GetSpecialization(keyFrames, kf);
609 KeyFrameVector3Ptr kfCopy = KeyFrameVector3::Clone(*kf);
610 AddAnimatorConnector( AnimatorConnector<Vector3>::New( proxy,
611 target.propertyIndex,
612 target.componentIndex,
613 KeyFrameVector3Functor(kfCopy,interpolation),
619 case Dali::Property::VECTOR4:
621 const KeyFrameVector4* kf;
622 GetSpecialization(keyFrames, kf);
623 KeyFrameVector4Ptr kfCopy = KeyFrameVector4::Clone(*kf);
624 AddAnimatorConnector( AnimatorConnector<Vector4>::New( proxy,
625 target.propertyIndex,
626 target.componentIndex,
627 KeyFrameVector4Functor(kfCopy,interpolation),
633 case Dali::Property::ROTATION:
635 const KeyFrameQuaternion* kf;
636 GetSpecialization(keyFrames, kf);
637 KeyFrameQuaternionPtr kfCopy = KeyFrameQuaternion::Clone(*kf);
638 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( proxy,
639 target.propertyIndex,
640 target.componentIndex,
641 KeyFrameQuaternionFunctor(kfCopy),
647 default: // not all property types are animateable
652 bool Animation::HasFinished()
654 bool hasFinished(false);
655 const int playCount(mAnimation->GetPlayCount());
657 // If the play count has been incremented, then another notification is required
658 if (playCount > mNotificationCount)
660 // Note that only one signal is emitted, if the animation has been played repeatedly
661 mNotificationCount = playCount;
669 Dali::Animation::AnimationSignalV2& Animation::FinishedSignal()
671 return mFinishedSignal;
674 void Animation::EmitSignalFinish()
676 if ( !mFinishedSignal.Empty() )
678 Dali::Animation handle( this );
679 mFinishedSignal.Emit( handle );
682 // This callback is used internally, to avoid the overhead of using a signal.
683 if ( mFinishedCallback )
685 mFinishedCallback( mFinishedCallbackObject );
689 bool Animation::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
691 bool connected( true );
692 Animation* animation = dynamic_cast<Animation*>(object);
694 if ( Dali::Animation::SIGNAL_FINISHED == signalName )
696 animation->FinishedSignal().Connect( tracker, functor );
700 // signalName does not match any signal
707 void Animation::SetFinishedCallback( FinishedCallback callback, Object* object )
709 mFinishedCallback = callback;
710 mFinishedCallbackObject = object;
713 void Animation::AddAnimatorConnector( AnimatorConnectorBase* connector )
715 DALI_ASSERT_DEBUG( NULL != connector );
717 connector->SetParent(*this);
719 mConnectors.PushBack( connector );
722 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward )
724 Animate( actor, path, forward, mDefaultAlpha, TimePeriod(0.0f,GetDuration()) );
727 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, AlphaFunction alpha )
729 Animate( actor, path, forward, alpha, TimePeriod(0.0f,GetDuration()) );
732 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, TimePeriod period )
734 Animate( actor, path, forward, mDefaultAlpha, period );
737 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, AlphaFunction alpha, TimePeriod period)
739 ExtendDuration( period );
741 PathPtr pathCopy = Path::Clone(path);
744 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
745 Dali::Actor::POSITION,
746 Property::INVALID_COMPONENT_INDEX,
747 PathPositionFunctor( pathCopy ),
751 //If forward is zero, PathRotationFunctor will always return the unit quaternion
752 if( forward != Vector3::ZERO )
755 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
756 Dali::Actor::ROTATION,
757 Property::INVALID_COMPONENT_INDEX,
758 PathRotationFunctor( pathCopy, forward ),
764 void Animation::MoveBy(Actor& actor, float x, float y, float z)
766 MoveBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
769 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha)
771 MoveBy(actor, displacement, alpha, 0.0f, GetDuration());
774 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha, float delaySeconds, float durationSeconds)
776 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
778 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
779 Dali::Actor::POSITION,
780 Property::INVALID_COMPONENT_INDEX,
781 AnimateByVector3(displacement),
783 TimePeriod(delaySeconds, durationSeconds) ) );
786 void Animation::MoveTo(Actor& actor, float x, float y, float z)
788 MoveTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
791 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha)
793 MoveTo(actor, position, alpha, 0.0f, GetDuration());
796 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha, float delaySeconds, float durationSeconds)
798 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
800 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
801 Dali::Actor::POSITION,
802 Property::INVALID_COMPONENT_INDEX,
803 AnimateToVector3(position),
805 TimePeriod(delaySeconds, durationSeconds) ) );
808 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis)
810 RotateBy(actor, angle, axis, mDefaultAlpha, 0.0f, GetDuration());
813 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
815 RotateBy(actor, angle, axis, alpha, 0.0f, GetDuration());
818 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
820 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
822 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
823 Dali::Actor::ROTATION,
824 Property::INVALID_COMPONENT_INDEX,
825 RotateByAngleAxis(angle, axis),
827 TimePeriod(delaySeconds, durationSeconds) ) );
830 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis)
832 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
833 normalizedAxis.Normalize();
835 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
837 RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
840 void Animation::RotateTo(Actor& actor, const Quaternion& orientation)
842 RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
845 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
847 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
848 normalizedAxis.Normalize();
850 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
852 RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
855 void Animation::RotateTo(Actor& actor, const Quaternion& orientation, AlphaFunction alpha)
857 RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
860 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
862 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
863 normalizedAxis.Normalize();
865 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
867 RotateTo(actor, orientation, alpha, delaySeconds, durationSeconds);
870 void Animation::RotateTo(Actor& actor, const Quaternion& rotation, AlphaFunction alpha, float delaySeconds, float durationSeconds)
872 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
874 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
875 Dali::Actor::ROTATION,
876 Property::INVALID_COMPONENT_INDEX,
877 RotateToQuaternion(rotation),
879 TimePeriod(delaySeconds, durationSeconds) ) );
882 void Animation::ScaleBy(Actor& actor, float x, float y, float z)
884 ScaleBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
887 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha)
889 ScaleBy(actor, scale, alpha, 0.0f, GetDuration());
892 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
894 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
896 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
898 Property::INVALID_COMPONENT_INDEX,
899 AnimateByVector3(scale),
901 TimePeriod(delaySeconds, durationSeconds) ) );
904 void Animation::ScaleTo(Actor& actor, float x, float y, float z)
906 ScaleTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
909 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha)
911 ScaleTo(actor, scale, alpha, 0.0f, GetDuration());
914 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
916 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
918 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
920 Property::INVALID_COMPONENT_INDEX,
921 AnimateToVector3(scale),
923 TimePeriod(delaySeconds, durationSeconds) ) );
926 void Animation::Show(Actor& actor, float delaySeconds)
928 ExtendDuration( TimePeriod(delaySeconds, 0) );
930 AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
931 Dali::Actor::VISIBLE,
932 Property::INVALID_COMPONENT_INDEX,
933 AnimateToBoolean(SHOW_VALUE),
934 AlphaFunctions::Default,
935 TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
938 void Animation::Hide(Actor& actor, float delaySeconds)
940 ExtendDuration( TimePeriod(delaySeconds, 0) );
942 AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
943 Dali::Actor::VISIBLE,
944 Property::INVALID_COMPONENT_INDEX,
945 AnimateToBoolean(HIDE_VALUE),
946 AlphaFunctions::Default,
947 TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
950 void Animation::OpacityBy(Actor& actor, float opacity)
952 OpacityBy(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
955 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha)
957 OpacityBy(actor, opacity, alpha, 0.0f, GetDuration());
960 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
962 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
964 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
966 Property::INVALID_COMPONENT_INDEX,
967 AnimateByOpacity(opacity),
969 TimePeriod(delaySeconds, durationSeconds) ) );
972 void Animation::OpacityTo(Actor& actor, float opacity)
974 OpacityTo(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
977 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha)
979 OpacityTo(actor, opacity, alpha, 0.0f, GetDuration());
982 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
984 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
986 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
988 Property::INVALID_COMPONENT_INDEX,
989 AnimateToOpacity(opacity),
991 TimePeriod(delaySeconds, durationSeconds) ) );
994 void Animation::ColorBy(Actor& actor, const Vector4& color)
996 ColorBy(actor, color, mDefaultAlpha, 0.0f, GetDuration());
999 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha)
1001 ColorBy(actor, color, alpha, 0.0f, GetDuration());
1004 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1006 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1008 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
1010 Property::INVALID_COMPONENT_INDEX,
1011 AnimateByVector4(color),
1013 TimePeriod(delaySeconds, durationSeconds) ) );
1016 void Animation::ColorTo(Actor& actor, const Vector4& color)
1018 ColorTo(actor, color, mDefaultAlpha, 0.0f, GetDuration());
1021 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha)
1023 ColorTo(actor, color, alpha, 0.0f, GetDuration());
1026 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1028 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1030 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
1032 Property::INVALID_COMPONENT_INDEX,
1033 AnimateToVector4(color),
1035 TimePeriod(delaySeconds, durationSeconds) ) );
1038 void Animation::Resize(Actor& actor, float width, float height)
1040 Resize(actor, width, height, mDefaultAlpha, 0.0f, GetDuration());
1043 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha)
1045 Resize(actor, width, height, alpha, 0.0f, GetDuration());
1048 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1050 Vector3 targetSize( width, height, std::min(width, height) );
1052 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1054 // Notify the actor impl that its size is being animated
1055 actor.NotifySizeAnimation( *this, targetSize );
1057 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1059 Property::INVALID_COMPONENT_INDEX,
1060 AnimateToVector3(targetSize),
1062 TimePeriod(delaySeconds, durationSeconds) ) );
1065 void Animation::Resize(Actor& actor, const Vector3& size)
1067 Resize(actor, size, mDefaultAlpha, 0.0f, GetDuration());
1070 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha)
1072 Resize(actor, size, alpha, 0.0f, GetDuration());
1075 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1077 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1079 // Notify the actor impl that its size is being animated
1080 actor.NotifySizeAnimation( *this, size );
1082 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1084 Property::INVALID_COMPONENT_INDEX,
1085 AnimateToVector3(size),
1087 TimePeriod(delaySeconds, durationSeconds) ) );
1090 bool Animation::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
1093 Animation* animation = dynamic_cast<Animation*>(object);
1097 if(Dali::Animation::ACTION_PLAY == actionName)
1099 if(attributes.size() > 0)
1101 animation->SetDuration(attributes[0].Get<float>());
1107 else if(Dali::Animation::ACTION_STOP == actionName)
1112 else if(Dali::Animation::ACTION_PAUSE == actionName)
1122 void Animation::SetCurrentProgress(float progress)
1124 if( mAnimation && progress >= mPlayRange.x && progress <= mPlayRange.y )
1126 // mAnimation is being used in a separate thread; queue a message to set the current progress
1127 SetCurrentProgressMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, progress );
1131 float Animation::GetCurrentProgress()
1135 return mAnimation->GetCurrentProgress();
1141 void Animation::ExtendDuration( const TimePeriod& timePeriod )
1143 float duration = timePeriod.delaySeconds + timePeriod.durationSeconds;
1145 if( duration > mDurationSeconds )
1147 SetDuration( duration );
1151 void Animation::SetSpeedFactor( float factor )
1155 mSpeedFactor = factor;
1156 SetSpeedFactorMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, factor );
1160 float Animation::GetSpeedFactor() const
1162 return mSpeedFactor;
1165 void Animation::SetPlayRange( const Vector2& range)
1167 //Make sure the range specified is between 0.0 and 1.0
1168 if( range.x >= 0.0f && range.x <= 1.0f && range.y >= 0.0f && range.y <= 1.0f )
1170 Vector2 orderedRange( range );
1171 //If the range is not in order swap values
1172 if( range.x > range.y )
1174 orderedRange = Vector2(range.y, range.x);
1177 // Cache for public getters
1178 mPlayRange = orderedRange;
1180 // mAnimation is being used in a separate thread; queue a message to set play range
1181 SetPlayRangeMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, orderedRange );
1185 Vector2 Animation::GetPlayRange() const
1191 } // namespace Internal