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/actors/actor.h>
23 #include <dali/public-api/animation/alpha-functions.h>
24 #include <dali/public-api/animation/time-period.h>
25 #include <dali/public-api/common/dali-common.h>
26 #include <dali/public-api/object/type-registry.h>
27 #include <dali/public-api/math/vector2.h>
28 #include <dali/public-api/math/radian.h>
29 #include <dali/internal/event/actors/actor-impl.h>
30 #include <dali/internal/event/animation/animation-playlist.h>
31 #include <dali/internal/event/animation/animator-connector.h>
32 #include <dali/internal/event/common/notification-manager.h>
33 #include <dali/internal/event/common/property-helper.h>
34 #include <dali/internal/event/common/stage-impl.h>
35 #include <dali/internal/event/common/thread-local-storage.h>
36 #include <dali/internal/event/effects/shader-effect-impl.h>
37 #include <dali/internal/update/manager/update-manager.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 const char* const SIGNAL_FINISHED = "finished";
61 const char* const ACTION_PLAY = "play";
62 const char* const ACTION_STOP = "stop";
63 const char* const ACTION_PAUSE = "pause";
67 return Dali::Animation::New(0.f);
70 TypeRegistration mType( typeid( Dali::Animation ), typeid( Dali::BaseHandle ), Create );
72 SignalConnectorType signalConnector1( mType, SIGNAL_FINISHED, &Animation::DoConnectSignal );
74 TypeAction action1( mType, ACTION_PLAY, &Animation::DoAction );
75 TypeAction action2( mType, ACTION_STOP, &Animation::DoAction );
76 TypeAction action3( mType, ACTION_PAUSE, &Animation::DoAction );
78 const Dali::Animation::EndAction DEFAULT_END_ACTION( Dali::Animation::Bake );
79 const Dali::Animation::EndAction DEFAULT_DISCONNECT_ACTION( Dali::Animation::BakeFinal );
80 const Dali::Animation::Interpolation DEFAULT_INTERPOLATION( Dali::Animation::Linear );
85 AnimationPtr Animation::New(float durationSeconds)
87 ThreadLocalStorage& tls = ThreadLocalStorage::Get();
88 UpdateManager& updateManager = tls.GetUpdateManager();
90 AnimationPlaylist& playlist = Stage::GetCurrent()->GetAnimationPlaylist();
92 AnimationPtr animation = new Animation( updateManager, playlist, durationSeconds, DEFAULT_END_ACTION, DEFAULT_DISCONNECT_ACTION, Dali::AlphaFunctions::Linear );
94 // Second-phase construction
95 animation->Initialize();
100 Animation::Animation( UpdateManager& updateManager, AnimationPlaylist& playlist, float durationSeconds, EndAction endAction, EndAction disconnectAction, AlphaFunction defaultAlpha )
101 : mUpdateManager( updateManager ),
102 mPlaylist( playlist ),
104 mNotificationCount( 0 ),
105 mFinishedCallback( NULL ),
106 mFinishedCallbackObject( NULL ),
107 mDurationSeconds( durationSeconds ),
110 mPlayRange( Vector2(0.0f,1.0f)),
111 mEndAction( endAction ),
112 mDisconnectAction( disconnectAction ),
113 mDefaultAlpha( defaultAlpha )
117 void Animation::Initialize()
119 // Connect to the animation playlist
120 mPlaylist.AnimationCreated( *this );
127 Animation::~Animation()
129 // Guard to allow handle destruction after Core has been destroyed
130 if ( Stage::IsInstalled() )
132 // Disconnect from the animation playlist
133 mPlaylist.AnimationDestroyed( *this );
135 DestroySceneObject();
141 void Animation::CreateSceneObject()
143 DALI_ASSERT_DEBUG( mAnimation == NULL );
145 // Create a new animation, temporarily owned
146 SceneGraph::Animation* animation = SceneGraph::Animation::New( mDurationSeconds, mSpeedFactor, mPlayRange, mIsLooping, mEndAction, mDisconnectAction );
148 // Keep a const pointer to the animation.
149 mAnimation = animation;
151 // Transfer animation ownership to the update manager through a message
152 AddAnimationMessage( mUpdateManager, animation );
155 void Animation::DestroySceneObject()
157 if ( mAnimation != NULL )
159 // Remove animation using a message to the update manager
160 RemoveAnimationMessage( mUpdateManager, *mAnimation );
165 void Animation::SetDuration(float seconds)
167 // Cache for public getters
168 mDurationSeconds = seconds;
170 // mAnimation is being used in a separate thread; queue a message to set the value
171 SetDurationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, seconds );
174 float Animation::GetDuration() const
176 // This is not animatable; the cached value is up-to-date.
177 return mDurationSeconds;
180 void Animation::SetLooping(bool looping)
182 // Cache for public getters
183 mIsLooping = looping;
185 // mAnimation is being used in a separate thread; queue a message to set the value
186 SetLoopingMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, looping );
189 bool Animation::IsLooping() const
191 // This is not animatable; the cached value is up-to-date.
195 void Animation::SetEndAction(EndAction action)
197 // Cache for public getters
200 // mAnimation is being used in a separate thread; queue a message to set the value
201 SetEndActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
204 Dali::Animation::EndAction Animation::GetEndAction() const
206 // This is not animatable; the cached value is up-to-date.
210 void Animation::SetDisconnectAction(EndAction action)
212 // Cache for public getters
213 mDisconnectAction = action;
215 // mAnimation is being used in a separate thread; queue a message to set the value
216 SetDisconnectActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
219 Dali::Animation::EndAction Animation::GetDisconnectAction() const
221 // This is not animatable; the cached value is up-to-date.
222 return mDisconnectAction;
225 void Animation::Play()
227 // Update the current playlist
228 mPlaylist.OnPlay( *this );
230 // mAnimation is being used in a separate thread; queue a Play message
231 PlayAnimationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation );
234 void Animation::PlayFrom( float progress )
236 if( progress >= mPlayRange.x && progress <= mPlayRange.y )
238 // Update the current playlist
239 mPlaylist.OnPlay( *this );
241 // mAnimation is being used in a separate thread; queue a Play message
242 PlayAnimationFromMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, progress );
246 void Animation::Pause()
248 // mAnimation is being used in a separate thread; queue a Pause message
249 PauseAnimationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation );
252 void Animation::Stop()
254 // mAnimation is being used in a separate thread; queue a Stop message
255 StopAnimationMessage( mUpdateManager, *mAnimation );
258 void Animation::Clear()
260 DALI_ASSERT_DEBUG(mAnimation);
262 // Remove all the connectors
265 // Replace the old scene-object with a new one
266 DestroySceneObject();
269 // Reset the notification count, since the new scene-object has never been played
270 mNotificationCount = 0;
272 // Update the current playlist
273 mPlaylist.OnClear( *this );
276 void Animation::AnimateBy(Property& target, Property::Value& relativeValue)
278 AnimateBy(target, relativeValue, AlphaFunctions::Default, mDurationSeconds);
281 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha)
283 AnimateBy(target, relativeValue, alpha, mDurationSeconds);
286 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, TimePeriod period)
288 AnimateBy(target, relativeValue, AlphaFunctions::Default, period);
291 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha, TimePeriod period)
293 Object& object = dynamic_cast<Object&>( GetImplementation(target.object) );
295 ExtendDuration( period );
297 switch ( relativeValue.GetType() )
299 case Property::BOOLEAN:
301 AddAnimatorConnector( AnimatorConnector<bool>::New( object,
302 target.propertyIndex,
303 target.componentIndex,
304 new AnimateByBoolean(relativeValue.Get<bool>()),
310 case Property::FLOAT:
312 AddAnimatorConnector( AnimatorConnector<float>::New( object,
313 target.propertyIndex,
314 target.componentIndex,
315 new AnimateByFloat(relativeValue.Get<float>()),
321 case Property::INTEGER:
323 AddAnimatorConnector( AnimatorConnector<int>::New( object,
324 target.propertyIndex,
325 target.componentIndex,
326 new AnimateByInteger(relativeValue.Get<int>()),
332 case Property::VECTOR2:
334 AddAnimatorConnector( AnimatorConnector<Vector2>::New( object,
335 target.propertyIndex,
336 target.componentIndex,
337 new AnimateByVector2(relativeValue.Get<Vector2>()),
343 case Property::VECTOR3:
345 AddAnimatorConnector( AnimatorConnector<Vector3>::New( object,
346 target.propertyIndex,
347 target.componentIndex,
348 new AnimateByVector3(relativeValue.Get<Vector3>()),
354 case Property::VECTOR4:
356 AddAnimatorConnector( AnimatorConnector<Vector4>::New( object,
357 target.propertyIndex,
358 target.componentIndex,
359 new AnimateByVector4(relativeValue.Get<Vector4>()),
365 case Property::ROTATION:
367 AngleAxis angleAxis = relativeValue.Get<AngleAxis>();
369 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( object,
370 target.propertyIndex,
371 target.componentIndex,
372 new RotateByAngleAxis(angleAxis.angle, angleAxis.axis),
379 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
384 void Animation::AnimateTo(Property& target, Property::Value& destinationValue)
386 AnimateTo(target, destinationValue, AlphaFunctions::Default, mDurationSeconds);
389 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha)
391 AnimateTo(target, destinationValue, alpha, mDurationSeconds);
394 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, TimePeriod period)
396 AnimateTo(target, destinationValue, AlphaFunctions::Default, period);
399 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
401 Object& object = dynamic_cast<Object&>( GetImplementation(target.object) );
403 AnimateTo( object, target.propertyIndex, target.componentIndex, destinationValue, alpha, period );
406 void Animation::AnimateTo(Object& targetObject, Property::Index targetPropertyIndex, int componentIndex, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
408 Property::Type type = targetObject.GetPropertyType(targetPropertyIndex);
409 if(componentIndex != Property::INVALID_COMPONENT_INDEX)
411 if( type == Property::VECTOR2
412 || type == Property::VECTOR3
413 || type == Property::VECTOR4 )
415 type = Property::FLOAT;
418 DALI_ASSERT_ALWAYS( type == destinationValue.GetType() && "DestinationValue does not match Target Property type" );
420 ExtendDuration( period );
422 switch (destinationValue.GetType())
424 case Property::BOOLEAN:
426 AddAnimatorConnector( AnimatorConnector<bool>::New( targetObject,
429 new AnimateToBoolean( destinationValue.Get<bool>() ),
435 case Property::FLOAT:
437 AddAnimatorConnector( AnimatorConnector<float>::New( targetObject,
440 new AnimateToFloat( destinationValue.Get<float>() ),
446 case Property::INTEGER:
448 AddAnimatorConnector( AnimatorConnector<int>::New( targetObject,
451 new AnimateToInteger( destinationValue.Get<int>() ),
457 case Property::VECTOR2:
459 AddAnimatorConnector( AnimatorConnector<Vector2>::New( targetObject,
462 new AnimateToVector2( destinationValue.Get<Vector2>() ),
468 case Property::VECTOR3:
470 if ( Dali::Actor::Property::SIZE == targetPropertyIndex )
472 // Test whether this is actually an Actor
473 Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
476 // Notify the actor that its size is being animated
477 maybeActor->NotifySizeAnimation( *this, destinationValue.Get<Vector3>() );
481 AddAnimatorConnector( AnimatorConnector<Vector3>::New( targetObject,
484 new AnimateToVector3( destinationValue.Get<Vector3>() ),
490 case Property::VECTOR4:
492 AddAnimatorConnector( AnimatorConnector<Vector4>::New( targetObject,
495 new AnimateToVector4( destinationValue.Get<Vector4>() ),
501 case Property::ROTATION:
503 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( targetObject,
506 new RotateToQuaternion( destinationValue.Get<Quaternion>() ),
513 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
518 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames)
520 AnimateBetween(target, keyFrames, mDefaultAlpha, mDurationSeconds, DEFAULT_INTERPOLATION );
523 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Interpolation interpolation )
525 AnimateBetween(target, keyFrames, mDefaultAlpha, mDurationSeconds, interpolation );
528 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period)
530 AnimateBetween(target, keyFrames, mDefaultAlpha, period, DEFAULT_INTERPOLATION);
533 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period, Interpolation interpolation)
535 AnimateBetween(target, keyFrames, mDefaultAlpha, period, interpolation);
538 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha)
540 AnimateBetween(target, keyFrames, alpha, mDurationSeconds, DEFAULT_INTERPOLATION);
543 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, Interpolation interpolation)
545 AnimateBetween(target, keyFrames, alpha, mDurationSeconds, interpolation);
548 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period)
550 AnimateBetween(target, keyFrames, alpha, period, DEFAULT_INTERPOLATION);
553 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period, Interpolation interpolation)
555 Object& object = dynamic_cast<Object&>( GetImplementation(target.object) );
557 ExtendDuration( period );
559 switch(keyFrames.GetType())
561 case Dali::Property::BOOLEAN:
563 const KeyFrameBoolean* kf;
564 GetSpecialization(keyFrames, kf);
565 KeyFrameBooleanPtr kfCopy = KeyFrameBoolean::Clone(*kf);
566 AddAnimatorConnector( AnimatorConnector<bool>::New( object,
567 target.propertyIndex,
568 target.componentIndex,
569 new KeyFrameBooleanFunctor(kfCopy),
575 case Dali::Property::FLOAT:
577 const KeyFrameNumber* kf;
578 GetSpecialization(keyFrames, kf);
579 KeyFrameNumberPtr kfCopy = KeyFrameNumber::Clone(*kf);
580 AddAnimatorConnector( AnimatorConnector<float>::New( object,
581 target.propertyIndex,
582 target.componentIndex,
583 new KeyFrameNumberFunctor(kfCopy,interpolation),
589 case Dali::Property::INTEGER:
591 const KeyFrameInteger* kf;
592 GetSpecialization(keyFrames, kf);
593 KeyFrameIntegerPtr kfCopy = KeyFrameInteger::Clone(*kf);
594 AddAnimatorConnector( AnimatorConnector<int>::New( object,
595 target.propertyIndex,
596 target.componentIndex,
597 new KeyFrameIntegerFunctor(kfCopy,interpolation),
603 case Dali::Property::VECTOR2:
605 const KeyFrameVector2* kf;
606 GetSpecialization(keyFrames, kf);
607 KeyFrameVector2Ptr kfCopy = KeyFrameVector2::Clone(*kf);
608 AddAnimatorConnector( AnimatorConnector<Vector2>::New( object,
609 target.propertyIndex,
610 target.componentIndex,
611 new KeyFrameVector2Functor(kfCopy,interpolation),
617 case Dali::Property::VECTOR3:
619 const KeyFrameVector3* kf;
620 GetSpecialization(keyFrames, kf);
621 KeyFrameVector3Ptr kfCopy = KeyFrameVector3::Clone(*kf);
622 AddAnimatorConnector( AnimatorConnector<Vector3>::New( object,
623 target.propertyIndex,
624 target.componentIndex,
625 new KeyFrameVector3Functor(kfCopy,interpolation),
631 case Dali::Property::VECTOR4:
633 const KeyFrameVector4* kf;
634 GetSpecialization(keyFrames, kf);
635 KeyFrameVector4Ptr kfCopy = KeyFrameVector4::Clone(*kf);
636 AddAnimatorConnector( AnimatorConnector<Vector4>::New( object,
637 target.propertyIndex,
638 target.componentIndex,
639 new KeyFrameVector4Functor(kfCopy,interpolation),
645 case Dali::Property::ROTATION:
647 const KeyFrameQuaternion* kf;
648 GetSpecialization(keyFrames, kf);
649 KeyFrameQuaternionPtr kfCopy = KeyFrameQuaternion::Clone(*kf);
650 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( object,
651 target.propertyIndex,
652 target.componentIndex,
653 new KeyFrameQuaternionFunctor(kfCopy),
659 default: // not all property types are animateable
664 bool Animation::HasFinished()
666 bool hasFinished(false);
667 const int playCount(mAnimation->GetPlayCount());
669 // If the play count has been incremented, then another notification is required
670 if (playCount > mNotificationCount)
672 // Note that only one signal is emitted, if the animation has been played repeatedly
673 mNotificationCount = playCount;
681 Dali::Animation::AnimationSignalType& Animation::FinishedSignal()
683 return mFinishedSignal;
686 void Animation::EmitSignalFinish()
688 if ( !mFinishedSignal.Empty() )
690 Dali::Animation handle( this );
691 mFinishedSignal.Emit( handle );
694 // This callback is used internally, to avoid the overhead of using a signal.
695 if ( mFinishedCallback )
697 mFinishedCallback( mFinishedCallbackObject );
701 bool Animation::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
703 bool connected( true );
704 Animation* animation = dynamic_cast<Animation*>(object);
706 if ( 0 == strcmp( signalName.c_str(), SIGNAL_FINISHED ) )
708 animation->FinishedSignal().Connect( tracker, functor );
712 // signalName does not match any signal
719 void Animation::SetFinishedCallback( FinishedCallback callback, Object* object )
721 mFinishedCallback = callback;
722 mFinishedCallbackObject = object;
725 void Animation::AddAnimatorConnector( AnimatorConnectorBase* connector )
727 DALI_ASSERT_DEBUG( NULL != connector );
729 connector->SetParent(*this);
731 mConnectors.PushBack( connector );
734 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward )
736 Animate( actor, path, forward, mDefaultAlpha, TimePeriod(0.0f,GetDuration()) );
739 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, AlphaFunction alpha )
741 Animate( actor, path, forward, alpha, TimePeriod(0.0f,GetDuration()) );
744 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, TimePeriod period )
746 Animate( actor, path, forward, mDefaultAlpha, period );
749 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, AlphaFunction alpha, TimePeriod period)
751 ExtendDuration( period );
753 PathPtr pathCopy = Path::Clone(path);
756 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
757 Dali::Actor::Property::POSITION,
758 Property::INVALID_COMPONENT_INDEX,
759 new PathPositionFunctor( pathCopy ),
763 //If forward is zero, PathRotationFunctor will always return the unit quaternion
764 if( forward != Vector3::ZERO )
767 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
768 Dali::Actor::Property::ORIENTATION,
769 Property::INVALID_COMPONENT_INDEX,
770 new PathRotationFunctor( pathCopy, forward ),
776 void Animation::MoveBy(Actor& actor, float x, float y, float z)
778 MoveBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
781 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha)
783 MoveBy(actor, displacement, alpha, 0.0f, GetDuration());
786 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha, float delaySeconds, float durationSeconds)
788 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
790 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
791 Dali::Actor::Property::POSITION,
792 Property::INVALID_COMPONENT_INDEX,
793 new AnimateByVector3(displacement),
795 TimePeriod(delaySeconds, durationSeconds) ) );
798 void Animation::MoveTo(Actor& actor, float x, float y, float z)
800 MoveTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
803 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha)
805 MoveTo(actor, position, alpha, 0.0f, GetDuration());
808 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha, float delaySeconds, float durationSeconds)
810 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
812 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
813 Dali::Actor::Property::POSITION,
814 Property::INVALID_COMPONENT_INDEX,
815 new AnimateToVector3(position),
817 TimePeriod(delaySeconds, durationSeconds) ) );
820 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis)
822 RotateBy(actor, angle, axis, mDefaultAlpha, 0.0f, GetDuration());
825 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
827 RotateBy(actor, angle, axis, alpha, 0.0f, GetDuration());
830 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
832 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
834 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
835 Dali::Actor::Property::ORIENTATION,
836 Property::INVALID_COMPONENT_INDEX,
837 new RotateByAngleAxis(angle, axis),
839 TimePeriod(delaySeconds, durationSeconds) ) );
842 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis)
844 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
845 normalizedAxis.Normalize();
847 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
849 RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
852 void Animation::RotateTo(Actor& actor, const Quaternion& orientation)
854 RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
857 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
859 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
860 normalizedAxis.Normalize();
862 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
864 RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
867 void Animation::RotateTo(Actor& actor, const Quaternion& orientation, AlphaFunction alpha)
869 RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
872 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
874 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
875 normalizedAxis.Normalize();
877 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
879 RotateTo(actor, orientation, alpha, delaySeconds, durationSeconds);
882 void Animation::RotateTo(Actor& actor, const Quaternion& rotation, AlphaFunction alpha, float delaySeconds, float durationSeconds)
884 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
886 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
887 Dali::Actor::Property::ORIENTATION,
888 Property::INVALID_COMPONENT_INDEX,
889 new RotateToQuaternion(rotation),
891 TimePeriod(delaySeconds, durationSeconds) ) );
894 void Animation::ScaleBy(Actor& actor, float x, float y, float z)
896 ScaleBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
899 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha)
901 ScaleBy(actor, scale, alpha, 0.0f, GetDuration());
904 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
906 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
908 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
909 Dali::Actor::Property::SCALE,
910 Property::INVALID_COMPONENT_INDEX,
911 new AnimateByVector3(scale),
913 TimePeriod(delaySeconds, durationSeconds) ) );
916 void Animation::ScaleTo(Actor& actor, float x, float y, float z)
918 ScaleTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
921 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha)
923 ScaleTo(actor, scale, alpha, 0.0f, GetDuration());
926 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
928 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
930 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
931 Dali::Actor::Property::SCALE,
932 Property::INVALID_COMPONENT_INDEX,
933 new AnimateToVector3(scale),
935 TimePeriod(delaySeconds, durationSeconds) ) );
938 void Animation::Show(Actor& actor, float delaySeconds)
940 ExtendDuration( TimePeriod(delaySeconds, 0) );
942 AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
943 Dali::Actor::Property::VISIBLE,
944 Property::INVALID_COMPONENT_INDEX,
945 new AnimateToBoolean(SHOW_VALUE),
946 AlphaFunctions::Default,
947 TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
950 void Animation::Hide(Actor& actor, float delaySeconds)
952 ExtendDuration( TimePeriod(delaySeconds, 0) );
954 AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
955 Dali::Actor::Property::VISIBLE,
956 Property::INVALID_COMPONENT_INDEX,
957 new AnimateToBoolean(HIDE_VALUE),
958 AlphaFunctions::Default,
959 TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
962 void Animation::OpacityBy(Actor& actor, float opacity)
964 OpacityBy(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
967 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha)
969 OpacityBy(actor, opacity, alpha, 0.0f, GetDuration());
972 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
974 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
976 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
977 Dali::Actor::Property::COLOR,
978 Property::INVALID_COMPONENT_INDEX,
979 new AnimateByOpacity(opacity),
981 TimePeriod(delaySeconds, durationSeconds) ) );
984 void Animation::OpacityTo(Actor& actor, float opacity)
986 OpacityTo(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
989 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha)
991 OpacityTo(actor, opacity, alpha, 0.0f, GetDuration());
994 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
996 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
998 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
999 Dali::Actor::Property::COLOR,
1000 Property::INVALID_COMPONENT_INDEX,
1001 new AnimateToOpacity(opacity),
1003 TimePeriod(delaySeconds, durationSeconds) ) );
1006 void Animation::ColorBy(Actor& actor, const Vector4& color)
1008 ColorBy(actor, color, mDefaultAlpha, 0.0f, GetDuration());
1011 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha)
1013 ColorBy(actor, color, alpha, 0.0f, GetDuration());
1016 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1018 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1020 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
1021 Dali::Actor::Property::COLOR,
1022 Property::INVALID_COMPONENT_INDEX,
1023 new AnimateByVector4(color),
1025 TimePeriod(delaySeconds, durationSeconds) ) );
1028 void Animation::ColorTo(Actor& actor, const Vector4& color)
1030 ColorTo(actor, color, mDefaultAlpha, 0.0f, GetDuration());
1033 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha)
1035 ColorTo(actor, color, alpha, 0.0f, GetDuration());
1038 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1040 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1042 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
1043 Dali::Actor::Property::COLOR,
1044 Property::INVALID_COMPONENT_INDEX,
1045 new AnimateToVector4(color),
1047 TimePeriod(delaySeconds, durationSeconds) ) );
1050 void Animation::Resize(Actor& actor, float width, float height)
1052 Resize(actor, width, height, mDefaultAlpha, 0.0f, GetDuration());
1055 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha)
1057 Resize(actor, width, height, alpha, 0.0f, GetDuration());
1060 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1062 Vector3 targetSize( width, height, std::min(width, height) );
1064 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1066 // Notify the actor impl that its size is being animated
1067 actor.NotifySizeAnimation( *this, targetSize );
1069 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1070 Dali::Actor::Property::SIZE,
1071 Property::INVALID_COMPONENT_INDEX,
1072 new AnimateToVector3(targetSize),
1074 TimePeriod(delaySeconds, durationSeconds) ) );
1077 void Animation::Resize(Actor& actor, const Vector3& size)
1079 Resize(actor, size, mDefaultAlpha, 0.0f, GetDuration());
1082 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha)
1084 Resize(actor, size, alpha, 0.0f, GetDuration());
1087 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1089 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1091 // Notify the actor impl that its size is being animated
1092 actor.NotifySizeAnimation( *this, size );
1094 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1095 Dali::Actor::Property::SIZE,
1096 Property::INVALID_COMPONENT_INDEX,
1097 new AnimateToVector3(size),
1099 TimePeriod(delaySeconds, durationSeconds) ) );
1102 bool Animation::DoAction( BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes )
1105 Animation* animation = dynamic_cast<Animation*>( object );
1109 if( 0 == strcmp( actionName.c_str(), ACTION_PLAY ) )
1111 if( attributes.size() > 0 )
1113 animation->SetDuration( attributes[0].Get<float>() );
1119 else if( 0 == strcmp( actionName.c_str(), ACTION_STOP ) )
1124 else if( 0 == strcmp( actionName.c_str(), ACTION_PAUSE ) )
1134 void Animation::SetCurrentProgress(float progress)
1136 if( mAnimation && progress >= mPlayRange.x && progress <= mPlayRange.y )
1138 // mAnimation is being used in a separate thread; queue a message to set the current progress
1139 SetCurrentProgressMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, progress );
1143 float Animation::GetCurrentProgress()
1147 return mAnimation->GetCurrentProgress();
1153 void Animation::ExtendDuration( const TimePeriod& timePeriod )
1155 float duration = timePeriod.delaySeconds + timePeriod.durationSeconds;
1157 if( duration > mDurationSeconds )
1159 SetDuration( duration );
1163 void Animation::SetSpeedFactor( float factor )
1167 mSpeedFactor = factor;
1168 SetSpeedFactorMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, factor );
1172 float Animation::GetSpeedFactor() const
1174 return mSpeedFactor;
1177 void Animation::SetPlayRange( const Vector2& range)
1179 //Make sure the range specified is between 0.0 and 1.0
1180 if( range.x >= 0.0f && range.x <= 1.0f && range.y >= 0.0f && range.y <= 1.0f )
1182 Vector2 orderedRange( range );
1183 //If the range is not in order swap values
1184 if( range.x > range.y )
1186 orderedRange = Vector2(range.y, range.x);
1189 // Cache for public getters
1190 mPlayRange = orderedRange;
1192 // mAnimation is being used in a separate thread; queue a message to set play range
1193 SetPlayRangeMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, orderedRange );
1197 Vector2 Animation::GetPlayRange() const
1203 } // namespace Internal