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 const char* const SIGNAL_FINISHED = "finished";
59 const char* const ACTION_PLAY = "play";
60 const char* const ACTION_STOP = "stop";
61 const char* const ACTION_PAUSE = "pause";
65 return Dali::Animation::New(0.f);
68 TypeRegistration mType( typeid(Dali::Animation), typeid(Dali::BaseHandle), Create );
70 SignalConnectorType signalConnector1( mType, SIGNAL_FINISHED, &Animation::DoConnectSignal );
72 TypeAction action1( mType, ACTION_PLAY, &Animation::DoAction );
73 TypeAction action2( mType, ACTION_STOP, &Animation::DoAction );
74 TypeAction action3( mType, ACTION_PAUSE, &Animation::DoAction );
76 const Dali::Animation::EndAction DEFAULT_END_ACTION( Dali::Animation::Bake );
77 const Dali::Animation::EndAction DEFAULT_DISCONNECT_ACTION( Dali::Animation::BakeFinal );
78 const Dali::Animation::Interpolation DEFAULT_INTERPOLATION( Dali::Animation::Linear );
83 AnimationPtr Animation::New(float durationSeconds)
85 ThreadLocalStorage& tls = ThreadLocalStorage::Get();
86 UpdateManager& updateManager = tls.GetUpdateManager();
88 AnimationPlaylist& playlist = Stage::GetCurrent()->GetAnimationPlaylist();
90 AnimationPtr animation = new Animation( updateManager, playlist, durationSeconds, DEFAULT_END_ACTION, DEFAULT_DISCONNECT_ACTION, Dali::AlphaFunctions::Linear );
92 // Second-phase construction
93 animation->Initialize();
98 Animation::Animation( UpdateManager& updateManager, AnimationPlaylist& playlist, float durationSeconds, EndAction endAction, EndAction disconnectAction, AlphaFunction defaultAlpha )
99 : mUpdateManager( updateManager ),
100 mPlaylist( playlist ),
102 mNotificationCount( 0 ),
103 mFinishedCallback( NULL ),
104 mFinishedCallbackObject( NULL ),
105 mDurationSeconds( durationSeconds ),
108 mPlayRange( Vector2(0.0f,1.0f)),
109 mEndAction( endAction ),
110 mDisconnectAction( disconnectAction ),
111 mDefaultAlpha( defaultAlpha )
115 void Animation::Initialize()
117 // Connect to the animation playlist
118 mPlaylist.AnimationCreated( *this );
125 Animation::~Animation()
127 // Guard to allow handle destruction after Core has been destroyed
128 if ( Stage::IsInstalled() )
130 // Disconnect from the animation playlist
131 mPlaylist.AnimationDestroyed( *this );
133 DestroySceneObject();
139 void Animation::CreateSceneObject()
141 DALI_ASSERT_DEBUG( mAnimation == NULL );
143 // Create a new animation, temporarily owned
144 SceneGraph::Animation* animation = SceneGraph::Animation::New( mDurationSeconds, mSpeedFactor, mPlayRange, mIsLooping, mEndAction, mDisconnectAction );
146 // Keep a const pointer to the animation.
147 mAnimation = animation;
149 // Transfer animation ownership to the update manager through a message
150 AddAnimationMessage( mUpdateManager, animation );
153 void Animation::DestroySceneObject()
155 if ( mAnimation != NULL )
157 // Remove animation using a message to the update manager
158 RemoveAnimationMessage( mUpdateManager, *mAnimation );
163 void Animation::SetDuration(float seconds)
165 // Cache for public getters
166 mDurationSeconds = seconds;
168 // mAnimation is being used in a separate thread; queue a message to set the value
169 SetDurationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, seconds );
172 float Animation::GetDuration() const
174 // This is not animatable; the cached value is up-to-date.
175 return mDurationSeconds;
178 void Animation::SetLooping(bool looping)
180 // Cache for public getters
181 mIsLooping = looping;
183 // mAnimation is being used in a separate thread; queue a message to set the value
184 SetLoopingMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, looping );
187 bool Animation::IsLooping() const
189 // This is not animatable; the cached value is up-to-date.
193 void Animation::SetEndAction(EndAction action)
195 // Cache for public getters
198 // mAnimation is being used in a separate thread; queue a message to set the value
199 SetEndActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
202 Dali::Animation::EndAction Animation::GetEndAction() const
204 // This is not animatable; the cached value is up-to-date.
208 void Animation::SetDisconnectAction(EndAction action)
210 // Cache for public getters
211 mDisconnectAction = action;
213 // mAnimation is being used in a separate thread; queue a message to set the value
214 SetDisconnectActionMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, action );
217 Dali::Animation::EndAction Animation::GetDisconnectAction() const
219 // This is not animatable; the cached value is up-to-date.
220 return mDisconnectAction;
223 void Animation::Play()
225 // Update the current playlist
226 mPlaylist.OnPlay( *this );
228 // mAnimation is being used in a separate thread; queue a Play message
229 PlayAnimationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation );
232 void Animation::PlayFrom( float progress )
234 if( progress >= mPlayRange.x && progress <= mPlayRange.y )
236 // Update the current playlist
237 mPlaylist.OnPlay( *this );
239 // mAnimation is being used in a separate thread; queue a Play message
240 PlayAnimationFromMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, progress );
244 void Animation::Pause()
246 // mAnimation is being used in a separate thread; queue a Pause message
247 PauseAnimationMessage( mUpdateManager.GetEventToUpdate(), *mAnimation );
250 void Animation::Stop()
252 // mAnimation is being used in a separate thread; queue a Stop message
253 StopAnimationMessage( mUpdateManager, *mAnimation );
256 void Animation::Clear()
258 DALI_ASSERT_DEBUG(mAnimation);
260 // Remove all the connectors
263 // Replace the old scene-object with a new one
264 DestroySceneObject();
267 // Reset the notification count, since the new scene-object has never been played
268 mNotificationCount = 0;
270 // Update the current playlist
271 mPlaylist.OnClear( *this );
274 void Animation::AnimateBy(Property& target, Property::Value& relativeValue)
276 AnimateBy(target, relativeValue, AlphaFunctions::Default, mDurationSeconds);
279 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha)
281 AnimateBy(target, relativeValue, alpha, mDurationSeconds);
284 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, TimePeriod period)
286 AnimateBy(target, relativeValue, AlphaFunctions::Default, period);
289 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha, TimePeriod period)
291 Object& object = dynamic_cast<Object&>( GetImplementation(target.object) );
293 ExtendDuration( period );
295 switch ( relativeValue.GetType() )
297 case Property::BOOLEAN:
299 AddAnimatorConnector( AnimatorConnector<bool>::New( object,
300 target.propertyIndex,
301 target.componentIndex,
302 new AnimateByBoolean(relativeValue.Get<bool>()),
308 case Property::FLOAT:
310 AddAnimatorConnector( AnimatorConnector<float>::New( object,
311 target.propertyIndex,
312 target.componentIndex,
313 new AnimateByFloat(relativeValue.Get<float>()),
319 case Property::INTEGER:
321 AddAnimatorConnector( AnimatorConnector<int>::New( object,
322 target.propertyIndex,
323 target.componentIndex,
324 new AnimateByInteger(relativeValue.Get<int>()),
330 case Property::VECTOR2:
332 AddAnimatorConnector( AnimatorConnector<Vector2>::New( object,
333 target.propertyIndex,
334 target.componentIndex,
335 new AnimateByVector2(relativeValue.Get<Vector2>()),
341 case Property::VECTOR3:
343 AddAnimatorConnector( AnimatorConnector<Vector3>::New( object,
344 target.propertyIndex,
345 target.componentIndex,
346 new AnimateByVector3(relativeValue.Get<Vector3>()),
352 case Property::VECTOR4:
354 AddAnimatorConnector( AnimatorConnector<Vector4>::New( object,
355 target.propertyIndex,
356 target.componentIndex,
357 new AnimateByVector4(relativeValue.Get<Vector4>()),
363 case Property::ROTATION:
365 AngleAxis angleAxis = relativeValue.Get<AngleAxis>();
367 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( object,
368 target.propertyIndex,
369 target.componentIndex,
370 new RotateByAngleAxis(angleAxis.angle, angleAxis.axis),
377 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
382 void Animation::AnimateTo(Property& target, Property::Value& destinationValue)
384 AnimateTo(target, destinationValue, AlphaFunctions::Default, mDurationSeconds);
387 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha)
389 AnimateTo(target, destinationValue, alpha, mDurationSeconds);
392 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, TimePeriod period)
394 AnimateTo(target, destinationValue, AlphaFunctions::Default, period);
397 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
399 Object& object = dynamic_cast<Object&>( GetImplementation(target.object) );
401 AnimateTo( object, target.propertyIndex, target.componentIndex, destinationValue, alpha, period );
404 void Animation::AnimateTo(Object& targetObject, Property::Index targetPropertyIndex, int componentIndex, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
406 Property::Type type = targetObject.GetPropertyType(targetPropertyIndex);
407 if(componentIndex != Property::INVALID_COMPONENT_INDEX)
409 if( type == Property::VECTOR2
410 || type == Property::VECTOR3
411 || type == Property::VECTOR4 )
413 type = Property::FLOAT;
416 DALI_ASSERT_ALWAYS( type == destinationValue.GetType() && "DestinationValue does not match Target Property type" );
418 ExtendDuration( period );
420 switch (destinationValue.GetType())
422 case Property::BOOLEAN:
424 AddAnimatorConnector( AnimatorConnector<bool>::New(targetObject,
427 new AnimateToBoolean(destinationValue.Get<bool>()),
433 case Property::FLOAT:
435 AddAnimatorConnector( AnimatorConnector<float>::New(targetObject,
438 new AnimateToFloat(destinationValue.Get<float>()),
444 case Property::INTEGER:
446 AddAnimatorConnector( AnimatorConnector<int>::New(targetObject,
449 new AnimateToInteger(destinationValue.Get<int>()),
455 case Property::VECTOR2:
457 AddAnimatorConnector( AnimatorConnector<Vector2>::New(targetObject,
460 new AnimateToVector2(destinationValue.Get<Vector2>()),
466 case Property::VECTOR3:
468 if ( Dali::Actor::SIZE == targetPropertyIndex )
470 // Test whether this is actually an Actor
471 Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
474 // Notify the actor that its size is being animated
475 maybeActor->NotifySizeAnimation( *this, destinationValue.Get<Vector3>() );
479 AddAnimatorConnector( AnimatorConnector<Vector3>::New(targetObject,
482 new AnimateToVector3(destinationValue.Get<Vector3>()),
488 case Property::VECTOR4:
490 AddAnimatorConnector( AnimatorConnector<Vector4>::New(targetObject,
493 new AnimateToVector4(destinationValue.Get<Vector4>()),
499 case Property::ROTATION:
501 AddAnimatorConnector( AnimatorConnector<Quaternion>::New(targetObject,
504 new RotateToQuaternion(destinationValue.Get<Quaternion>()),
511 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
516 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames)
518 AnimateBetween(target, keyFrames, mDefaultAlpha, mDurationSeconds, DEFAULT_INTERPOLATION );
521 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Interpolation interpolation )
523 AnimateBetween(target, keyFrames, mDefaultAlpha, mDurationSeconds, interpolation );
526 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period)
528 AnimateBetween(target, keyFrames, mDefaultAlpha, period, DEFAULT_INTERPOLATION);
531 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period, Interpolation interpolation)
533 AnimateBetween(target, keyFrames, mDefaultAlpha, period, interpolation);
536 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha)
538 AnimateBetween(target, keyFrames, alpha, mDurationSeconds, DEFAULT_INTERPOLATION);
541 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, Interpolation interpolation)
543 AnimateBetween(target, keyFrames, alpha, mDurationSeconds, interpolation);
546 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period)
548 AnimateBetween(target, keyFrames, alpha, period, DEFAULT_INTERPOLATION);
551 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period, Interpolation interpolation)
553 Object& object = dynamic_cast<Object&>( GetImplementation(target.object) );
555 ExtendDuration( period );
557 switch(keyFrames.GetType())
559 case Dali::Property::BOOLEAN:
561 const KeyFrameBoolean* kf;
562 GetSpecialization(keyFrames, kf);
563 KeyFrameBooleanPtr kfCopy = KeyFrameBoolean::Clone(*kf);
564 AddAnimatorConnector( AnimatorConnector<bool>::New( object,
565 target.propertyIndex,
566 target.componentIndex,
567 new KeyFrameBooleanFunctor(kfCopy),
573 case Dali::Property::FLOAT:
575 const KeyFrameNumber* kf;
576 GetSpecialization(keyFrames, kf);
577 KeyFrameNumberPtr kfCopy = KeyFrameNumber::Clone(*kf);
578 AddAnimatorConnector( AnimatorConnector<float>::New( object,
579 target.propertyIndex,
580 target.componentIndex,
581 new KeyFrameNumberFunctor(kfCopy,interpolation),
587 case Dali::Property::INTEGER:
589 const KeyFrameInteger* kf;
590 GetSpecialization(keyFrames, kf);
591 KeyFrameIntegerPtr kfCopy = KeyFrameInteger::Clone(*kf);
592 AddAnimatorConnector( AnimatorConnector<int>::New( object,
593 target.propertyIndex,
594 target.componentIndex,
595 new KeyFrameIntegerFunctor(kfCopy,interpolation),
601 case Dali::Property::VECTOR2:
603 const KeyFrameVector2* kf;
604 GetSpecialization(keyFrames, kf);
605 KeyFrameVector2Ptr kfCopy = KeyFrameVector2::Clone(*kf);
606 AddAnimatorConnector( AnimatorConnector<Vector2>::New( object,
607 target.propertyIndex,
608 target.componentIndex,
609 new KeyFrameVector2Functor(kfCopy,interpolation),
615 case Dali::Property::VECTOR3:
617 const KeyFrameVector3* kf;
618 GetSpecialization(keyFrames, kf);
619 KeyFrameVector3Ptr kfCopy = KeyFrameVector3::Clone(*kf);
620 AddAnimatorConnector( AnimatorConnector<Vector3>::New( object,
621 target.propertyIndex,
622 target.componentIndex,
623 new KeyFrameVector3Functor(kfCopy,interpolation),
629 case Dali::Property::VECTOR4:
631 const KeyFrameVector4* kf;
632 GetSpecialization(keyFrames, kf);
633 KeyFrameVector4Ptr kfCopy = KeyFrameVector4::Clone(*kf);
634 AddAnimatorConnector( AnimatorConnector<Vector4>::New( object,
635 target.propertyIndex,
636 target.componentIndex,
637 new KeyFrameVector4Functor(kfCopy,interpolation),
643 case Dali::Property::ROTATION:
645 const KeyFrameQuaternion* kf;
646 GetSpecialization(keyFrames, kf);
647 KeyFrameQuaternionPtr kfCopy = KeyFrameQuaternion::Clone(*kf);
648 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( object,
649 target.propertyIndex,
650 target.componentIndex,
651 new KeyFrameQuaternionFunctor(kfCopy),
657 default: // not all property types are animateable
662 bool Animation::HasFinished()
664 bool hasFinished(false);
665 const int playCount(mAnimation->GetPlayCount());
667 // If the play count has been incremented, then another notification is required
668 if (playCount > mNotificationCount)
670 // Note that only one signal is emitted, if the animation has been played repeatedly
671 mNotificationCount = playCount;
679 Dali::Animation::AnimationSignalType& Animation::FinishedSignal()
681 return mFinishedSignal;
684 void Animation::EmitSignalFinish()
686 if ( !mFinishedSignal.Empty() )
688 Dali::Animation handle( this );
689 mFinishedSignal.Emit( handle );
692 // This callback is used internally, to avoid the overhead of using a signal.
693 if ( mFinishedCallback )
695 mFinishedCallback( mFinishedCallbackObject );
699 bool Animation::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
701 bool connected( true );
702 Animation* animation = dynamic_cast<Animation*>(object);
704 if ( 0 == strcmp( signalName.c_str(), SIGNAL_FINISHED ) )
706 animation->FinishedSignal().Connect( tracker, functor );
710 // signalName does not match any signal
717 void Animation::SetFinishedCallback( FinishedCallback callback, Object* object )
719 mFinishedCallback = callback;
720 mFinishedCallbackObject = object;
723 void Animation::AddAnimatorConnector( AnimatorConnectorBase* connector )
725 DALI_ASSERT_DEBUG( NULL != connector );
727 connector->SetParent(*this);
729 mConnectors.PushBack( connector );
732 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward )
734 Animate( actor, path, forward, mDefaultAlpha, TimePeriod(0.0f,GetDuration()) );
737 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, AlphaFunction alpha )
739 Animate( actor, path, forward, alpha, TimePeriod(0.0f,GetDuration()) );
742 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, TimePeriod period )
744 Animate( actor, path, forward, mDefaultAlpha, period );
747 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, AlphaFunction alpha, TimePeriod period)
749 ExtendDuration( period );
751 PathPtr pathCopy = Path::Clone(path);
754 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
755 Dali::Actor::POSITION,
756 Property::INVALID_COMPONENT_INDEX,
757 new PathPositionFunctor( pathCopy ),
761 //If forward is zero, PathRotationFunctor will always return the unit quaternion
762 if( forward != Vector3::ZERO )
765 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
766 Dali::Actor::ROTATION,
767 Property::INVALID_COMPONENT_INDEX,
768 new PathRotationFunctor( pathCopy, forward ),
774 void Animation::MoveBy(Actor& actor, float x, float y, float z)
776 MoveBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
779 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha)
781 MoveBy(actor, displacement, alpha, 0.0f, GetDuration());
784 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha, float delaySeconds, float durationSeconds)
786 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
788 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
789 Dali::Actor::POSITION,
790 Property::INVALID_COMPONENT_INDEX,
791 new AnimateByVector3(displacement),
793 TimePeriod(delaySeconds, durationSeconds) ) );
796 void Animation::MoveTo(Actor& actor, float x, float y, float z)
798 MoveTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
801 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha)
803 MoveTo(actor, position, alpha, 0.0f, GetDuration());
806 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha, float delaySeconds, float durationSeconds)
808 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
810 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
811 Dali::Actor::POSITION,
812 Property::INVALID_COMPONENT_INDEX,
813 new AnimateToVector3(position),
815 TimePeriod(delaySeconds, durationSeconds) ) );
818 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis)
820 RotateBy(actor, angle, axis, mDefaultAlpha, 0.0f, GetDuration());
823 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
825 RotateBy(actor, angle, axis, alpha, 0.0f, GetDuration());
828 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
830 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
832 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
833 Dali::Actor::ROTATION,
834 Property::INVALID_COMPONENT_INDEX,
835 new RotateByAngleAxis(angle, axis),
837 TimePeriod(delaySeconds, durationSeconds) ) );
840 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis)
842 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
843 normalizedAxis.Normalize();
845 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
847 RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
850 void Animation::RotateTo(Actor& actor, const Quaternion& orientation)
852 RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
855 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
857 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
858 normalizedAxis.Normalize();
860 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
862 RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
865 void Animation::RotateTo(Actor& actor, const Quaternion& orientation, AlphaFunction alpha)
867 RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
870 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
872 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
873 normalizedAxis.Normalize();
875 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
877 RotateTo(actor, orientation, alpha, delaySeconds, durationSeconds);
880 void Animation::RotateTo(Actor& actor, const Quaternion& rotation, AlphaFunction alpha, float delaySeconds, float durationSeconds)
882 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
884 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
885 Dali::Actor::ROTATION,
886 Property::INVALID_COMPONENT_INDEX,
887 new RotateToQuaternion(rotation),
889 TimePeriod(delaySeconds, durationSeconds) ) );
892 void Animation::ScaleBy(Actor& actor, float x, float y, float z)
894 ScaleBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
897 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha)
899 ScaleBy(actor, scale, alpha, 0.0f, GetDuration());
902 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
904 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
906 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
908 Property::INVALID_COMPONENT_INDEX,
909 new AnimateByVector3(scale),
911 TimePeriod(delaySeconds, durationSeconds) ) );
914 void Animation::ScaleTo(Actor& actor, float x, float y, float z)
916 ScaleTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
919 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha)
921 ScaleTo(actor, scale, alpha, 0.0f, GetDuration());
924 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
926 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
928 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
930 Property::INVALID_COMPONENT_INDEX,
931 new AnimateToVector3(scale),
933 TimePeriod(delaySeconds, durationSeconds) ) );
936 void Animation::Show(Actor& actor, float delaySeconds)
938 ExtendDuration( TimePeriod(delaySeconds, 0) );
940 AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
941 Dali::Actor::VISIBLE,
942 Property::INVALID_COMPONENT_INDEX,
943 new AnimateToBoolean(SHOW_VALUE),
944 AlphaFunctions::Default,
945 TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
948 void Animation::Hide(Actor& actor, float delaySeconds)
950 ExtendDuration( TimePeriod(delaySeconds, 0) );
952 AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
953 Dali::Actor::VISIBLE,
954 Property::INVALID_COMPONENT_INDEX,
955 new AnimateToBoolean(HIDE_VALUE),
956 AlphaFunctions::Default,
957 TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
960 void Animation::OpacityBy(Actor& actor, float opacity)
962 OpacityBy(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
965 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha)
967 OpacityBy(actor, opacity, alpha, 0.0f, GetDuration());
970 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
972 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
974 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
976 Property::INVALID_COMPONENT_INDEX,
977 new AnimateByOpacity(opacity),
979 TimePeriod(delaySeconds, durationSeconds) ) );
982 void Animation::OpacityTo(Actor& actor, float opacity)
984 OpacityTo(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
987 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha)
989 OpacityTo(actor, opacity, alpha, 0.0f, GetDuration());
992 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
994 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
996 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
998 Property::INVALID_COMPONENT_INDEX,
999 new AnimateToOpacity(opacity),
1001 TimePeriod(delaySeconds, durationSeconds) ) );
1004 void Animation::ColorBy(Actor& actor, const Vector4& color)
1006 ColorBy(actor, color, mDefaultAlpha, 0.0f, GetDuration());
1009 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha)
1011 ColorBy(actor, color, alpha, 0.0f, GetDuration());
1014 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1016 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1018 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
1020 Property::INVALID_COMPONENT_INDEX,
1021 new AnimateByVector4(color),
1023 TimePeriod(delaySeconds, durationSeconds) ) );
1026 void Animation::ColorTo(Actor& actor, const Vector4& color)
1028 ColorTo(actor, color, mDefaultAlpha, 0.0f, GetDuration());
1031 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha)
1033 ColorTo(actor, color, alpha, 0.0f, GetDuration());
1036 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1038 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1040 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
1042 Property::INVALID_COMPONENT_INDEX,
1043 new AnimateToVector4(color),
1045 TimePeriod(delaySeconds, durationSeconds) ) );
1048 void Animation::Resize(Actor& actor, float width, float height)
1050 Resize(actor, width, height, mDefaultAlpha, 0.0f, GetDuration());
1053 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha)
1055 Resize(actor, width, height, alpha, 0.0f, GetDuration());
1058 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1060 Vector3 targetSize( width, height, std::min(width, height) );
1062 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1064 // Notify the actor impl that its size is being animated
1065 actor.NotifySizeAnimation( *this, targetSize );
1067 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1069 Property::INVALID_COMPONENT_INDEX,
1070 new AnimateToVector3(targetSize),
1072 TimePeriod(delaySeconds, durationSeconds) ) );
1075 void Animation::Resize(Actor& actor, const Vector3& size)
1077 Resize(actor, size, mDefaultAlpha, 0.0f, GetDuration());
1080 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha)
1082 Resize(actor, size, alpha, 0.0f, GetDuration());
1085 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1087 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1089 // Notify the actor impl that its size is being animated
1090 actor.NotifySizeAnimation( *this, size );
1092 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1094 Property::INVALID_COMPONENT_INDEX,
1095 new AnimateToVector3(size),
1097 TimePeriod(delaySeconds, durationSeconds) ) );
1100 bool Animation::DoAction( BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes )
1103 Animation* animation = dynamic_cast<Animation*>( object );
1107 if( 0 == strcmp( actionName.c_str(), ACTION_PLAY ) )
1109 if( attributes.size() > 0 )
1111 animation->SetDuration( attributes[0].Get<float>() );
1117 else if( 0 == strcmp( actionName.c_str(), ACTION_STOP ) )
1122 else if( 0 == strcmp( actionName.c_str(), ACTION_PAUSE ) )
1132 void Animation::SetCurrentProgress(float progress)
1134 if( mAnimation && progress >= mPlayRange.x && progress <= mPlayRange.y )
1136 // mAnimation is being used in a separate thread; queue a message to set the current progress
1137 SetCurrentProgressMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, progress );
1141 float Animation::GetCurrentProgress()
1145 return mAnimation->GetCurrentProgress();
1151 void Animation::ExtendDuration( const TimePeriod& timePeriod )
1153 float duration = timePeriod.delaySeconds + timePeriod.durationSeconds;
1155 if( duration > mDurationSeconds )
1157 SetDuration( duration );
1161 void Animation::SetSpeedFactor( float factor )
1165 mSpeedFactor = factor;
1166 SetSpeedFactorMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, factor );
1170 float Animation::GetSpeedFactor() const
1172 return mSpeedFactor;
1175 void Animation::SetPlayRange( const Vector2& range)
1177 //Make sure the range specified is between 0.0 and 1.0
1178 if( range.x >= 0.0f && range.x <= 1.0f && range.y >= 0.0f && range.y <= 1.0f )
1180 Vector2 orderedRange( range );
1181 //If the range is not in order swap values
1182 if( range.x > range.y )
1184 orderedRange = Vector2(range.y, range.x);
1187 // Cache for public getters
1188 mPlayRange = orderedRange;
1190 // mAnimation is being used in a separate thread; queue a message to set play range
1191 SetPlayRangeMessage( mUpdateManager.GetEventToUpdate(), *mAnimation, orderedRange );
1195 Vector2 Animation::GetPlayRange() const
1201 } // namespace Internal