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 Stage* stage = Stage::GetCurrent();
89 AnimationPlaylist& playlist = stage->GetAnimationPlaylist();
91 AnimationPtr animation = new Animation( *stage, playlist, durationSeconds, DEFAULT_END_ACTION, DEFAULT_DISCONNECT_ACTION, Dali::AlphaFunctions::Linear );
93 // Second-phase construction
94 animation->Initialize();
99 Animation::Animation( EventThreadServices& eventThreadServices, AnimationPlaylist& playlist, float durationSeconds, EndAction endAction, EndAction disconnectAction, AlphaFunction defaultAlpha )
100 : mEventThreadServices( eventThreadServices ),
101 mPlaylist( playlist ),
103 mNotificationCount( 0 ),
104 mFinishedCallback( NULL ),
105 mFinishedCallbackObject( NULL ),
106 mDurationSeconds( durationSeconds ),
109 mPlayRange( Vector2(0.0f,1.0f)),
110 mEndAction( endAction ),
111 mDisconnectAction( disconnectAction ),
112 mDefaultAlpha( defaultAlpha )
116 void Animation::Initialize()
118 // Connect to the animation playlist
119 mPlaylist.AnimationCreated( *this );
126 Animation::~Animation()
128 // Guard to allow handle destruction after Core has been destroyed
129 if ( Stage::IsInstalled() )
131 // Disconnect from the animation playlist
132 mPlaylist.AnimationDestroyed( *this );
134 DestroySceneObject();
140 void Animation::CreateSceneObject()
142 DALI_ASSERT_DEBUG( mAnimation == NULL );
144 // Create a new animation, temporarily owned
145 SceneGraph::Animation* animation = SceneGraph::Animation::New( mDurationSeconds, mSpeedFactor, mPlayRange, mIsLooping, mEndAction, mDisconnectAction );
147 // Keep a const pointer to the animation.
148 mAnimation = animation;
150 // Transfer animation ownership to the update manager through a message
151 AddAnimationMessage( mEventThreadServices.GetUpdateManager(), animation );
154 void Animation::DestroySceneObject()
156 if ( mAnimation != NULL )
158 // Remove animation using a message to the update manager
159 RemoveAnimationMessage( mEventThreadServices.GetUpdateManager(), *mAnimation );
164 void Animation::SetDuration(float seconds)
166 // Cache for public getters
167 mDurationSeconds = seconds;
169 // mAnimation is being used in a separate thread; queue a message to set the value
170 SetDurationMessage( mEventThreadServices, *mAnimation, seconds );
173 float Animation::GetDuration() const
175 // This is not animatable; the cached value is up-to-date.
176 return mDurationSeconds;
179 void Animation::SetLooping(bool looping)
181 // Cache for public getters
182 mIsLooping = looping;
184 // mAnimation is being used in a separate thread; queue a message to set the value
185 SetLoopingMessage( mEventThreadServices, *mAnimation, looping );
188 bool Animation::IsLooping() const
190 // This is not animatable; the cached value is up-to-date.
194 void Animation::SetEndAction(EndAction action)
196 // Cache for public getters
199 // mAnimation is being used in a separate thread; queue a message to set the value
200 SetEndActionMessage( mEventThreadServices, *mAnimation, action );
203 Dali::Animation::EndAction Animation::GetEndAction() const
205 // This is not animatable; the cached value is up-to-date.
209 void Animation::SetDisconnectAction(EndAction action)
211 // Cache for public getters
212 mDisconnectAction = action;
214 // mAnimation is being used in a separate thread; queue a message to set the value
215 SetDisconnectActionMessage( mEventThreadServices, *mAnimation, action );
218 Dali::Animation::EndAction Animation::GetDisconnectAction() const
220 // This is not animatable; the cached value is up-to-date.
221 return mDisconnectAction;
224 void Animation::Play()
226 // Update the current playlist
227 mPlaylist.OnPlay( *this );
229 // mAnimation is being used in a separate thread; queue a Play message
230 PlayAnimationMessage( mEventThreadServices, *mAnimation );
233 void Animation::PlayFrom( float progress )
235 if( progress >= mPlayRange.x && progress <= mPlayRange.y )
237 // Update the current playlist
238 mPlaylist.OnPlay( *this );
240 // mAnimation is being used in a separate thread; queue a Play message
241 PlayAnimationFromMessage( mEventThreadServices, *mAnimation, progress );
245 void Animation::Pause()
247 // mAnimation is being used in a separate thread; queue a Pause message
248 PauseAnimationMessage( mEventThreadServices, *mAnimation );
251 void Animation::Stop()
253 // mAnimation is being used in a separate thread; queue a Stop message
254 StopAnimationMessage( mEventThreadServices.GetUpdateManager(), *mAnimation );
257 void Animation::Clear()
259 DALI_ASSERT_DEBUG(mAnimation);
261 // Remove all the connectors
264 // Replace the old scene-object with a new one
265 DestroySceneObject();
268 // Reset the notification count, since the new scene-object has never been played
269 mNotificationCount = 0;
271 // Update the current playlist
272 mPlaylist.OnClear( *this );
275 void Animation::AnimateBy(Property& target, Property::Value& relativeValue)
277 AnimateBy(target, relativeValue, AlphaFunctions::Default, mDurationSeconds);
280 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha)
282 AnimateBy(target, relativeValue, alpha, mDurationSeconds);
285 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, TimePeriod period)
287 AnimateBy(target, relativeValue, AlphaFunctions::Default, period);
290 void Animation::AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha, TimePeriod period)
292 Object& object = dynamic_cast<Object&>( GetImplementation(target.object) );
294 ExtendDuration( period );
296 switch ( relativeValue.GetType() )
298 case Property::BOOLEAN:
300 AddAnimatorConnector( AnimatorConnector<bool>::New( object,
301 target.propertyIndex,
302 target.componentIndex,
303 new AnimateByBoolean(relativeValue.Get<bool>()),
309 case Property::FLOAT:
311 AddAnimatorConnector( AnimatorConnector<float>::New( object,
312 target.propertyIndex,
313 target.componentIndex,
314 new AnimateByFloat(relativeValue.Get<float>()),
320 case Property::INTEGER:
322 AddAnimatorConnector( AnimatorConnector<int>::New( object,
323 target.propertyIndex,
324 target.componentIndex,
325 new AnimateByInteger(relativeValue.Get<int>()),
331 case Property::VECTOR2:
333 AddAnimatorConnector( AnimatorConnector<Vector2>::New( object,
334 target.propertyIndex,
335 target.componentIndex,
336 new AnimateByVector2(relativeValue.Get<Vector2>()),
342 case Property::VECTOR3:
344 AddAnimatorConnector( AnimatorConnector<Vector3>::New( object,
345 target.propertyIndex,
346 target.componentIndex,
347 new AnimateByVector3(relativeValue.Get<Vector3>()),
353 case Property::VECTOR4:
355 AddAnimatorConnector( AnimatorConnector<Vector4>::New( object,
356 target.propertyIndex,
357 target.componentIndex,
358 new AnimateByVector4(relativeValue.Get<Vector4>()),
364 case Property::ROTATION:
366 AngleAxis angleAxis = relativeValue.Get<AngleAxis>();
368 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( object,
369 target.propertyIndex,
370 target.componentIndex,
371 new RotateByAngleAxis(angleAxis.angle, angleAxis.axis),
378 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
383 void Animation::AnimateTo(Property& target, Property::Value& destinationValue)
385 AnimateTo(target, destinationValue, AlphaFunctions::Default, mDurationSeconds);
388 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha)
390 AnimateTo(target, destinationValue, alpha, mDurationSeconds);
393 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, TimePeriod period)
395 AnimateTo(target, destinationValue, AlphaFunctions::Default, period);
398 void Animation::AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
400 Object& object = dynamic_cast<Object&>( GetImplementation(target.object) );
402 AnimateTo( object, target.propertyIndex, target.componentIndex, destinationValue, alpha, period );
405 void Animation::AnimateTo(Object& targetObject, Property::Index targetPropertyIndex, int componentIndex, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period)
407 Property::Type type = targetObject.GetPropertyType(targetPropertyIndex);
408 if(componentIndex != Property::INVALID_COMPONENT_INDEX)
410 if( type == Property::VECTOR2
411 || type == Property::VECTOR3
412 || type == Property::VECTOR4 )
414 type = Property::FLOAT;
417 DALI_ASSERT_ALWAYS( type == destinationValue.GetType() && "DestinationValue does not match Target Property type" );
419 ExtendDuration( period );
421 switch (destinationValue.GetType())
423 case Property::BOOLEAN:
425 AddAnimatorConnector( AnimatorConnector<bool>::New( targetObject,
428 new AnimateToBoolean( destinationValue.Get<bool>() ),
434 case Property::FLOAT:
436 AddAnimatorConnector( AnimatorConnector<float>::New( targetObject,
439 new AnimateToFloat( destinationValue.Get<float>() ),
445 case Property::INTEGER:
447 AddAnimatorConnector( AnimatorConnector<int>::New( targetObject,
450 new AnimateToInteger( destinationValue.Get<int>() ),
456 case Property::VECTOR2:
458 AddAnimatorConnector( AnimatorConnector<Vector2>::New( targetObject,
461 new AnimateToVector2( destinationValue.Get<Vector2>() ),
467 case Property::VECTOR3:
469 if ( Dali::Actor::Property::SIZE == targetPropertyIndex )
471 // Test whether this is actually an Actor
472 Actor* maybeActor = dynamic_cast<Actor*>( &targetObject );
475 // Notify the actor that its size is being animated
476 maybeActor->NotifySizeAnimation( *this, destinationValue.Get<Vector3>() );
480 AddAnimatorConnector( AnimatorConnector<Vector3>::New( targetObject,
483 new AnimateToVector3( destinationValue.Get<Vector3>() ),
489 case Property::VECTOR4:
491 AddAnimatorConnector( AnimatorConnector<Vector4>::New( targetObject,
494 new AnimateToVector4( destinationValue.Get<Vector4>() ),
500 case Property::ROTATION:
502 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( targetObject,
505 new RotateToQuaternion( destinationValue.Get<Quaternion>() ),
512 DALI_ASSERT_ALWAYS( false && "Property type enumeration out of bounds" ); // should never come here
517 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames)
519 AnimateBetween(target, keyFrames, mDefaultAlpha, mDurationSeconds, DEFAULT_INTERPOLATION );
522 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Interpolation interpolation )
524 AnimateBetween(target, keyFrames, mDefaultAlpha, mDurationSeconds, interpolation );
527 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period)
529 AnimateBetween(target, keyFrames, mDefaultAlpha, period, DEFAULT_INTERPOLATION);
532 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period, Interpolation interpolation)
534 AnimateBetween(target, keyFrames, mDefaultAlpha, period, interpolation);
537 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha)
539 AnimateBetween(target, keyFrames, alpha, mDurationSeconds, DEFAULT_INTERPOLATION);
542 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, Interpolation interpolation)
544 AnimateBetween(target, keyFrames, alpha, mDurationSeconds, interpolation);
547 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period)
549 AnimateBetween(target, keyFrames, alpha, period, DEFAULT_INTERPOLATION);
552 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period, Interpolation interpolation)
554 Object& object = dynamic_cast<Object&>( GetImplementation(target.object) );
556 ExtendDuration( period );
558 switch(keyFrames.GetType())
560 case Dali::Property::BOOLEAN:
562 const KeyFrameBoolean* kf;
563 GetSpecialization(keyFrames, kf);
564 KeyFrameBooleanPtr kfCopy = KeyFrameBoolean::Clone(*kf);
565 AddAnimatorConnector( AnimatorConnector<bool>::New( object,
566 target.propertyIndex,
567 target.componentIndex,
568 new KeyFrameBooleanFunctor(kfCopy),
574 case Dali::Property::FLOAT:
576 const KeyFrameNumber* kf;
577 GetSpecialization(keyFrames, kf);
578 KeyFrameNumberPtr kfCopy = KeyFrameNumber::Clone(*kf);
579 AddAnimatorConnector( AnimatorConnector<float>::New( object,
580 target.propertyIndex,
581 target.componentIndex,
582 new KeyFrameNumberFunctor(kfCopy,interpolation),
588 case Dali::Property::INTEGER:
590 const KeyFrameInteger* kf;
591 GetSpecialization(keyFrames, kf);
592 KeyFrameIntegerPtr kfCopy = KeyFrameInteger::Clone(*kf);
593 AddAnimatorConnector( AnimatorConnector<int>::New( object,
594 target.propertyIndex,
595 target.componentIndex,
596 new KeyFrameIntegerFunctor(kfCopy,interpolation),
602 case Dali::Property::VECTOR2:
604 const KeyFrameVector2* kf;
605 GetSpecialization(keyFrames, kf);
606 KeyFrameVector2Ptr kfCopy = KeyFrameVector2::Clone(*kf);
607 AddAnimatorConnector( AnimatorConnector<Vector2>::New( object,
608 target.propertyIndex,
609 target.componentIndex,
610 new KeyFrameVector2Functor(kfCopy,interpolation),
616 case Dali::Property::VECTOR3:
618 const KeyFrameVector3* kf;
619 GetSpecialization(keyFrames, kf);
620 KeyFrameVector3Ptr kfCopy = KeyFrameVector3::Clone(*kf);
621 AddAnimatorConnector( AnimatorConnector<Vector3>::New( object,
622 target.propertyIndex,
623 target.componentIndex,
624 new KeyFrameVector3Functor(kfCopy,interpolation),
630 case Dali::Property::VECTOR4:
632 const KeyFrameVector4* kf;
633 GetSpecialization(keyFrames, kf);
634 KeyFrameVector4Ptr kfCopy = KeyFrameVector4::Clone(*kf);
635 AddAnimatorConnector( AnimatorConnector<Vector4>::New( object,
636 target.propertyIndex,
637 target.componentIndex,
638 new KeyFrameVector4Functor(kfCopy,interpolation),
644 case Dali::Property::ROTATION:
646 const KeyFrameQuaternion* kf;
647 GetSpecialization(keyFrames, kf);
648 KeyFrameQuaternionPtr kfCopy = KeyFrameQuaternion::Clone(*kf);
649 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( object,
650 target.propertyIndex,
651 target.componentIndex,
652 new KeyFrameQuaternionFunctor(kfCopy),
658 default: // not all property types are animateable
663 bool Animation::HasFinished()
665 bool hasFinished(false);
666 const int playCount(mAnimation->GetPlayCount());
668 // If the play count has been incremented, then another notification is required
669 if (playCount > mNotificationCount)
671 // Note that only one signal is emitted, if the animation has been played repeatedly
672 mNotificationCount = playCount;
680 Dali::Animation::AnimationSignalType& Animation::FinishedSignal()
682 return mFinishedSignal;
685 void Animation::EmitSignalFinish()
687 if ( !mFinishedSignal.Empty() )
689 Dali::Animation handle( this );
690 mFinishedSignal.Emit( handle );
693 // This callback is used internally, to avoid the overhead of using a signal.
694 if ( mFinishedCallback )
696 mFinishedCallback( mFinishedCallbackObject );
700 bool Animation::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
702 bool connected( true );
703 Animation* animation = dynamic_cast<Animation*>(object);
705 if ( 0 == strcmp( signalName.c_str(), SIGNAL_FINISHED ) )
707 animation->FinishedSignal().Connect( tracker, functor );
711 // signalName does not match any signal
718 void Animation::SetFinishedCallback( FinishedCallback callback, Object* object )
720 mFinishedCallback = callback;
721 mFinishedCallbackObject = object;
724 void Animation::AddAnimatorConnector( AnimatorConnectorBase* connector )
726 DALI_ASSERT_DEBUG( NULL != connector );
728 connector->SetParent(*this);
730 mConnectors.PushBack( connector );
733 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward )
735 Animate( actor, path, forward, mDefaultAlpha, TimePeriod(0.0f,GetDuration()) );
738 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, AlphaFunction alpha )
740 Animate( actor, path, forward, alpha, TimePeriod(0.0f,GetDuration()) );
743 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, TimePeriod period )
745 Animate( actor, path, forward, mDefaultAlpha, period );
748 void Animation::Animate( Actor& actor, const Path& path, const Vector3& forward, AlphaFunction alpha, TimePeriod period)
750 ExtendDuration( period );
752 PathPtr pathCopy = Path::Clone(path);
755 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
756 Dali::Actor::Property::POSITION,
757 Property::INVALID_COMPONENT_INDEX,
758 new PathPositionFunctor( pathCopy ),
762 //If forward is zero, PathRotationFunctor will always return the unit quaternion
763 if( forward != Vector3::ZERO )
766 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
767 Dali::Actor::Property::ORIENTATION,
768 Property::INVALID_COMPONENT_INDEX,
769 new PathRotationFunctor( pathCopy, forward ),
775 void Animation::MoveBy(Actor& actor, float x, float y, float z)
777 MoveBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
780 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha)
782 MoveBy(actor, displacement, alpha, 0.0f, GetDuration());
785 void Animation::MoveBy(Actor& actor, const Vector3& displacement, AlphaFunction alpha, float delaySeconds, float durationSeconds)
787 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
789 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
790 Dali::Actor::Property::POSITION,
791 Property::INVALID_COMPONENT_INDEX,
792 new AnimateByVector3(displacement),
794 TimePeriod(delaySeconds, durationSeconds) ) );
797 void Animation::MoveTo(Actor& actor, float x, float y, float z)
799 MoveTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
802 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha)
804 MoveTo(actor, position, alpha, 0.0f, GetDuration());
807 void Animation::MoveTo(Actor& actor, const Vector3& position, AlphaFunction alpha, float delaySeconds, float durationSeconds)
809 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
811 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
812 Dali::Actor::Property::POSITION,
813 Property::INVALID_COMPONENT_INDEX,
814 new AnimateToVector3(position),
816 TimePeriod(delaySeconds, durationSeconds) ) );
819 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis)
821 RotateBy(actor, angle, axis, mDefaultAlpha, 0.0f, GetDuration());
824 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
826 RotateBy(actor, angle, axis, alpha, 0.0f, GetDuration());
829 void Animation::RotateBy(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
831 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
833 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
834 Dali::Actor::Property::ORIENTATION,
835 Property::INVALID_COMPONENT_INDEX,
836 new RotateByAngleAxis(angle, axis),
838 TimePeriod(delaySeconds, durationSeconds) ) );
841 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis)
843 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
844 normalizedAxis.Normalize();
846 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
848 RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
851 void Animation::RotateTo(Actor& actor, const Quaternion& orientation)
853 RotateTo(actor, orientation, mDefaultAlpha, 0.0f, GetDuration());
856 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha)
858 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
859 normalizedAxis.Normalize();
861 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
863 RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
866 void Animation::RotateTo(Actor& actor, const Quaternion& orientation, AlphaFunction alpha)
868 RotateTo(actor, orientation, alpha, 0.0f, GetDuration());
871 void Animation::RotateTo(Actor& actor, Radian angle, const Vector3& axis, AlphaFunction alpha, float delaySeconds, float durationSeconds)
873 Vector4 normalizedAxis(axis.x, axis.y, axis.z, 0.0f);
874 normalizedAxis.Normalize();
876 Quaternion orientation(Quaternion::FromAxisAngle(normalizedAxis, angle));
878 RotateTo(actor, orientation, alpha, delaySeconds, durationSeconds);
881 void Animation::RotateTo(Actor& actor, const Quaternion& rotation, AlphaFunction alpha, float delaySeconds, float durationSeconds)
883 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
885 AddAnimatorConnector( AnimatorConnector<Quaternion>::New( actor,
886 Dali::Actor::Property::ORIENTATION,
887 Property::INVALID_COMPONENT_INDEX,
888 new RotateToQuaternion(rotation),
890 TimePeriod(delaySeconds, durationSeconds) ) );
893 void Animation::ScaleBy(Actor& actor, float x, float y, float z)
895 ScaleBy(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
898 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha)
900 ScaleBy(actor, scale, alpha, 0.0f, GetDuration());
903 void Animation::ScaleBy(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
905 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
907 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
908 Dali::Actor::Property::SCALE,
909 Property::INVALID_COMPONENT_INDEX,
910 new AnimateByVector3(scale),
912 TimePeriod(delaySeconds, durationSeconds) ) );
915 void Animation::ScaleTo(Actor& actor, float x, float y, float z)
917 ScaleTo(actor, Vector3(x, y, z), mDefaultAlpha, 0.0f, GetDuration());
920 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha)
922 ScaleTo(actor, scale, alpha, 0.0f, GetDuration());
925 void Animation::ScaleTo(Actor& actor, const Vector3& scale, AlphaFunction alpha, float delaySeconds, float durationSeconds)
927 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
929 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
930 Dali::Actor::Property::SCALE,
931 Property::INVALID_COMPONENT_INDEX,
932 new AnimateToVector3(scale),
934 TimePeriod(delaySeconds, durationSeconds) ) );
937 void Animation::Show(Actor& actor, float delaySeconds)
939 ExtendDuration( TimePeriod(delaySeconds, 0) );
941 AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
942 Dali::Actor::Property::VISIBLE,
943 Property::INVALID_COMPONENT_INDEX,
944 new AnimateToBoolean(SHOW_VALUE),
945 AlphaFunctions::Default,
946 TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
949 void Animation::Hide(Actor& actor, float delaySeconds)
951 ExtendDuration( TimePeriod(delaySeconds, 0) );
953 AddAnimatorConnector( AnimatorConnector<bool>::New( actor,
954 Dali::Actor::Property::VISIBLE,
955 Property::INVALID_COMPONENT_INDEX,
956 new AnimateToBoolean(HIDE_VALUE),
957 AlphaFunctions::Default,
958 TimePeriod(delaySeconds, 0.0f/*immediate*/) ) );
961 void Animation::OpacityBy(Actor& actor, float opacity)
963 OpacityBy(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
966 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha)
968 OpacityBy(actor, opacity, alpha, 0.0f, GetDuration());
971 void Animation::OpacityBy(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
973 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
975 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
976 Dali::Actor::Property::COLOR,
977 Property::INVALID_COMPONENT_INDEX,
978 new AnimateByOpacity(opacity),
980 TimePeriod(delaySeconds, durationSeconds) ) );
983 void Animation::OpacityTo(Actor& actor, float opacity)
985 OpacityTo(actor, opacity, mDefaultAlpha, 0.0f, GetDuration());
988 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha)
990 OpacityTo(actor, opacity, alpha, 0.0f, GetDuration());
993 void Animation::OpacityTo(Actor& actor, float opacity, AlphaFunction alpha, float delaySeconds, float durationSeconds)
995 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
997 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
998 Dali::Actor::Property::COLOR,
999 Property::INVALID_COMPONENT_INDEX,
1000 new AnimateToOpacity(opacity),
1002 TimePeriod(delaySeconds, durationSeconds) ) );
1005 void Animation::ColorBy(Actor& actor, const Vector4& color)
1007 ColorBy(actor, color, mDefaultAlpha, 0.0f, GetDuration());
1010 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha)
1012 ColorBy(actor, color, alpha, 0.0f, GetDuration());
1015 void Animation::ColorBy(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1017 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1019 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
1020 Dali::Actor::Property::COLOR,
1021 Property::INVALID_COMPONENT_INDEX,
1022 new AnimateByVector4(color),
1024 TimePeriod(delaySeconds, durationSeconds) ) );
1027 void Animation::ColorTo(Actor& actor, const Vector4& color)
1029 ColorTo(actor, color, mDefaultAlpha, 0.0f, GetDuration());
1032 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha)
1034 ColorTo(actor, color, alpha, 0.0f, GetDuration());
1037 void Animation::ColorTo(Actor& actor, const Vector4& color, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1039 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1041 AddAnimatorConnector( AnimatorConnector<Vector4>::New( actor,
1042 Dali::Actor::Property::COLOR,
1043 Property::INVALID_COMPONENT_INDEX,
1044 new AnimateToVector4(color),
1046 TimePeriod(delaySeconds, durationSeconds) ) );
1049 void Animation::Resize(Actor& actor, float width, float height)
1051 Resize(actor, width, height, mDefaultAlpha, 0.0f, GetDuration());
1054 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha)
1056 Resize(actor, width, height, alpha, 0.0f, GetDuration());
1059 void Animation::Resize(Actor& actor, float width, float height, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1061 Vector3 targetSize( width, height, std::min(width, height) );
1063 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1065 // Notify the actor impl that its size is being animated
1066 actor.NotifySizeAnimation( *this, targetSize );
1068 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1069 Dali::Actor::Property::SIZE,
1070 Property::INVALID_COMPONENT_INDEX,
1071 new AnimateToVector3(targetSize),
1073 TimePeriod(delaySeconds, durationSeconds) ) );
1076 void Animation::Resize(Actor& actor, const Vector3& size)
1078 Resize(actor, size, mDefaultAlpha, 0.0f, GetDuration());
1081 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha)
1083 Resize(actor, size, alpha, 0.0f, GetDuration());
1086 void Animation::Resize(Actor& actor, const Vector3& size, AlphaFunction alpha, float delaySeconds, float durationSeconds)
1088 ExtendDuration( TimePeriod(delaySeconds, durationSeconds) );
1090 // Notify the actor impl that its size is being animated
1091 actor.NotifySizeAnimation( *this, size );
1093 AddAnimatorConnector( AnimatorConnector<Vector3>::New( actor,
1094 Dali::Actor::Property::SIZE,
1095 Property::INVALID_COMPONENT_INDEX,
1096 new AnimateToVector3(size),
1098 TimePeriod(delaySeconds, durationSeconds) ) );
1101 bool Animation::DoAction( BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes )
1104 Animation* animation = dynamic_cast<Animation*>( object );
1108 if( 0 == strcmp( actionName.c_str(), ACTION_PLAY ) )
1110 if( attributes.size() > 0 )
1112 animation->SetDuration( attributes[0].Get<float>() );
1118 else if( 0 == strcmp( actionName.c_str(), ACTION_STOP ) )
1123 else if( 0 == strcmp( actionName.c_str(), ACTION_PAUSE ) )
1133 void Animation::SetCurrentProgress(float progress)
1135 if( mAnimation && progress >= mPlayRange.x && progress <= mPlayRange.y )
1137 // mAnimation is being used in a separate thread; queue a message to set the current progress
1138 SetCurrentProgressMessage( mEventThreadServices, *mAnimation, progress );
1142 float Animation::GetCurrentProgress()
1146 return mAnimation->GetCurrentProgress();
1152 void Animation::ExtendDuration( const TimePeriod& timePeriod )
1154 float duration = timePeriod.delaySeconds + timePeriod.durationSeconds;
1156 if( duration > mDurationSeconds )
1158 SetDuration( duration );
1162 void Animation::SetSpeedFactor( float factor )
1166 mSpeedFactor = factor;
1167 SetSpeedFactorMessage( mEventThreadServices, *mAnimation, factor );
1171 float Animation::GetSpeedFactor() const
1173 return mSpeedFactor;
1176 void Animation::SetPlayRange( const Vector2& range)
1178 //Make sure the range specified is between 0.0 and 1.0
1179 if( range.x >= 0.0f && range.x <= 1.0f && range.y >= 0.0f && range.y <= 1.0f )
1181 Vector2 orderedRange( range );
1182 //If the range is not in order swap values
1183 if( range.x > range.y )
1185 orderedRange = Vector2(range.y, range.x);
1188 // Cache for public getters
1189 mPlayRange = orderedRange;
1191 // mAnimation is being used in a separate thread; queue a message to set play range
1192 SetPlayRangeMessage( mEventThreadServices, *mAnimation, orderedRange );
1196 Vector2 Animation::GetPlayRange() const
1202 } // namespace Internal