// INTERNAL INCLUDES
#include <dali/internal/common/memory-pool-object-allocator.h>
#include <dali/internal/render/common/performance-monitor.h>
-
+#include <dali/public-api/math/math-utils.h>
namespace //Unnamed namespace
{
//Memory pool used to allocate new animations. Memory used by this pool will be released when shutting down DALi
/// Compares the end times of the animators and if the end time is less, then it is moved earlier in the list. If end times are the same, then no change.
bool CompareAnimatorEndTimes( const Dali::Internal::SceneGraph::AnimatorBase* lhs, const Dali::Internal::SceneGraph::AnimatorBase* rhs )
{
- return ( ( lhs->GetInitialDelay() + lhs->GetDuration() ) < ( rhs->GetInitialDelay() + rhs->GetDuration() ) );
+ return ( ( lhs->GetIntervalDelay() + lhs->GetDuration() ) < ( rhs->GetIntervalDelay() + rhs->GetDuration() ) );
}
} // unnamed namespace
}
Animation::Animation( float durationSeconds, float speedFactor, const Vector2& playRange, int loopCount, Dali::Animation::EndAction endAction, Dali::Animation::EndAction disconnectAction )
-: mDurationSeconds(durationSeconds),
+: mPlayRange( playRange ),
+ mDurationSeconds( durationSeconds ),
+ mDelaySeconds( 0.0f ),
+ mElapsedSeconds( playRange.x*mDurationSeconds ),
mSpeedFactor( speedFactor ),
+ mProgressMarker( 0.0f ),
+ mPlayedCount( 0 ),
+ mLoopCount(loopCount),
+ mCurrentLoop(0),
mEndAction(endAction),
mDisconnectAction(disconnectAction),
mState(Stopped),
- mElapsedSeconds(playRange.x*mDurationSeconds),
- mPlayedCount(0),
- mLoopCount(loopCount),
- mCurrentLoop(0),
- mPlayRange( playRange ),
- mProgressMarker(0.0f),
- mProgressReachedSignalRequired( false )
+ mProgressReachedSignalRequired( false ),
+ mAutoReverseEnabled( false )
{
}
}
}
+void Animation::PlayAfter( float delaySeconds )
+{
+ if( mState != Playing )
+ {
+ mDelaySeconds = delaySeconds;
+ mState = Playing;
+
+ if ( mSpeedFactor < 0.0f && mElapsedSeconds <= mPlayRange.x*mDurationSeconds )
+ {
+ mElapsedSeconds = mPlayRange.y * mDurationSeconds;
+ }
+
+ SetAnimatorsActive( true );
+
+ mCurrentLoop = 0;
+ }
+}
+
void Animation::Pause()
{
if (mState == Playing)
mState = Destroyed;
}
+void Animation::SetLoopingMode( bool loopingMode )
+{
+ mAutoReverseEnabled = loopingMode;
+
+ for ( AnimatorIter iter = mAnimators.Begin(), endIter = mAnimators.End(); iter != endIter; ++iter )
+ {
+ // Send some variables together to figure out the Animation status
+ (*iter)->SetSpeedFactor( mSpeedFactor );
+ (*iter)->SetLoopCount( mLoopCount );
+
+ (*iter)->SetLoopingMode( loopingMode );
+ }
+}
+
void Animation::AddAnimator( OwnerPointer<AnimatorBase>& animator )
{
animator->ConnectToSceneGraph();
// The animation must still be applied when Paused/Stopping
if (mState == Playing)
{
- mElapsedSeconds += elapsedSeconds * mSpeedFactor;
+ // If there is delay time before Animation starts, wait the Animation until mDelaySeconds.
+ if( mDelaySeconds > 0.0f )
+ {
+ float reduceSeconds = fabsf( elapsedSeconds * mSpeedFactor );
+ if( reduceSeconds > mDelaySeconds )
+ {
+ if( mSpeedFactor < 0.0f )
+ {
+ mElapsedSeconds -= reduceSeconds - mDelaySeconds;
+ }
+ else
+ {
+ mElapsedSeconds += reduceSeconds - mDelaySeconds;
+ }
+ mDelaySeconds = 0.0f;
+ }
+ else
+ {
+ mDelaySeconds -= reduceSeconds;
+ }
+ }
+ else
+ {
+ mElapsedSeconds += ( elapsedSeconds * mSpeedFactor );
+ }
if ( mProgressReachedSignalRequired && ( mElapsedSeconds >= mProgressMarker ) )
{
Vector2 playRangeSeconds = mPlayRange * mDurationSeconds;
- if( 0 == mLoopCount )
- {
- // loop forever
- WrapInPlayRange(mElapsedSeconds, playRangeSeconds);
-
- UpdateAnimators(bufferIndex, false, false );
-
- // don't increment mPlayedCount as event loop tracks this to indicate animation finished (end of all loops)
- }
- else if( mCurrentLoop < mLoopCount - 1) // '-1' here so last loop iteration uses play once below
+ if( 0 == mLoopCount || mCurrentLoop < mLoopCount - 1) // '-1' here so last loop iteration uses play once below
{
// looping
looped = (mState == Playing &&
if(looped)
{
- ++mCurrentLoop;
+ if( mLoopCount != 0 )
+ {
+ ++mCurrentLoop;
+ }
mProgressReachedSignalRequired = mProgressMarker > 0.0f;
// don't increment mPlayedCount until the finished final loop
}
{
if( animator->IsEnabled() )
{
- const float initialDelay( animator->GetInitialDelay() );
- if( elapsedSecondsClamped >= initialDelay )
+ const float intervalDelay( animator->GetIntervalDelay() );
+
+ if( elapsedSecondsClamped >= intervalDelay )
{
// Calculate a progress specific to each individual animator
float progress(1.0f);
const float animatorDuration = animator->GetDuration();
if (animatorDuration > 0.0f) // animators can be "immediate"
{
- progress = Clamp((elapsedSecondsClamped - initialDelay) / animatorDuration, 0.0f , 1.0f );
+ progress = Clamp((elapsedSecondsClamped - intervalDelay) / animatorDuration, 0.0f , 1.0f );
}
animator->Update(bufferIndex, progress, bake);
}