From c65103acd0b02b22bdb6ad629c9b498def523bc8 Mon Sep 17 00:00:00 2001 From: Eunki Hong Date: Tue, 10 Oct 2017 11:41:13 +0900 Subject: [PATCH] Fix LoopingMode::AUTO_REVERSE behavior when LoopCount is 1 Let's think some animation s.t. start = 0, target = 2, duration = 2. if LoopingMode is RESTART, animation will works like RESTART +---------------------------------> t LoopCount = 0 | 0 - 1 - 2`- 1 - 2`- 1 - 2`- 1 - ... LoopCount = 3 | 0 - 1 - 2`- 1 - 2`- 1 - 2 - 2 - ... LoopCount = 2 | 0 - 1 - 2`- 1 - 2 - 2 - 2 - 2 - ... LoopCount = 1 | 0 - 1 - 2 - 2 - 2 - 2 - 2 - 2 - ... (2` mean value become 0 after value become 2) But if Looping Mode is AUTO_REVERSE, animation will works like AUTO_REVERSE +---------------------------------> t LoopCount = 0 | 0 - 2 - 0 - 2 - 0 - 2 - 0 - 2 - ... LoopCount = 3 | 0 - 2 - 0 - 2 - 0 - 2 - 0 - 0 - ... LoopCount = 2 | 0 - 2 - 0 - 2 - 0 - 0 - 0 - 0 - ... LoopCount = 1 | 0 - 1 - 2 - 2 - 2 - 2 - 2 - 2 - ... Previous code think that LoopCount == 1 is not looping mode. But "ONLY IF LoopCount == 1, We don't auto reversing your animation" is non-sense This patch change animation works like AUTO_REVERSE +---------------------------------> t LoopCount = 1 | 0 - 2 - 0 - 0 - 0 - 0 - 0 - 0 - ... Note : Patch set 4 is previous code. so, Fail at UtcDaliAnimationSetLoopingModeP3 Change-Id: Ie938864ba17c1b923021f87c29859f98f7241a43 Signed-off-by: Eunki Hong --- automated-tests/src/dali/utc-Dali-Animation.cpp | 119 +++++++++++++++++++++ .../update/animation/scene-graph-animator.h | 8 +- 2 files changed, 125 insertions(+), 2 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-Animation.cpp b/automated-tests/src/dali/utc-Dali-Animation.cpp index 3327cb7..d9f1934 100644 --- a/automated-tests/src/dali/utc-Dali-Animation.cpp +++ b/automated-tests/src/dali/utc-Dali-Animation.cpp @@ -11819,6 +11819,125 @@ int UtcDaliAnimationSetLoopingModeP2(void) END_TEST; } +int UtcDaliAnimationSetLoopingModeP3(void) +{ + // Test Loop Count is 1 (== default) and Loop mode being set + TestApplication application; + Stage stage( Stage::GetCurrent() ); + + // LoopingMode::AUTO_REVERSE + { + Actor actor = Actor::New(); + stage.Add( actor ); + + float durationSeconds( 1.0f ); + Animation animation = Animation::New( durationSeconds ); + DALI_TEST_CHECK(1 == animation.GetLoopCount()); + + bool signalReceived( false ); + AnimationFinishCheck finishCheck( signalReceived ); + animation.FinishedSignal().Connect( &application, finishCheck ); + application.SendNotification(); + + Vector3 targetPosition(100.0f, 100.0f, 100.0f); + animation.AnimateTo( Property( actor, Actor::Property::POSITION ), targetPosition ); + + animation.SetLoopingMode( Animation::AUTO_REVERSE ); + DALI_TEST_CHECK( animation.GetLoopingMode() == Animation::AUTO_REVERSE ); + + // Start the animation + animation.Play(); + application.Render(0); + application.SendNotification(); + + application.Render( static_cast< unsigned int >( durationSeconds * 0.5f * 1000.0f )/* 50% time progress */ ); + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + + // AUTO_REVERSE mode means, for Animation duration time, the actor starts from the beginning, passes the targetPosition, + // and arrives at the beginning. + DALI_TEST_EQUALS( actor.GetCurrentPosition(), targetPosition, TEST_LOCATION ); + + application.SendNotification(); + application.Render( static_cast< unsigned int >( durationSeconds * 0.5f * 1000.0f )/* 100% time progress */ ); + + application.SendNotification(); + DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), TEST_LOCATION ); + + application.SendNotification(); + application.Render( static_cast< unsigned int >( durationSeconds * 1.0f * 1000.0f ) + 1u /*just beyond the animation duration*/ ); + + application.SendNotification(); + application.Render(0); + application.SendNotification(); + finishCheck.CheckSignalReceived(); + + // After all animation finished, arrives at the beginning. + DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), TEST_LOCATION ); + + finishCheck.Reset(); + } + + // LoopingMode::AUTO_REVERSE in Reverse mode, which begin from the end + { + Actor actor = Actor::New(); + stage.Add( actor ); + + float durationSeconds( 1.0f ); + Animation animation = Animation::New( durationSeconds ); + DALI_TEST_CHECK(1 == animation.GetLoopCount()); + + bool signalReceived( false ); + AnimationFinishCheck finishCheck( signalReceived ); + animation.FinishedSignal().Connect( &application, finishCheck ); + application.SendNotification(); + + // Specify a negative multiplier to play the animation in reverse + animation.SetSpeedFactor( -1.0f ); + + Vector3 targetPosition(100.0f, 100.0f, 100.0f); + animation.AnimateTo( Property( actor, Actor::Property::POSITION ), targetPosition ); + + animation.SetLoopingMode( Animation::AUTO_REVERSE ); + DALI_TEST_CHECK( animation.GetLoopingMode() == Animation::AUTO_REVERSE ); + + // Start the animation + animation.Play(); + application.Render(0); + application.SendNotification(); + + application.Render( static_cast< unsigned int >( durationSeconds * 0.5f * 1000.0f )/* 50% time progress */ ); + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + + // Setting a negative speed factor is to play the animation in reverse. + // So, when LoopingMode::AUTO_REVERSE and SetSpeedFactor( -1.0f ) is, for Animation duration time, + // the actor starts from the targetPosition, passes the beginning, and arrives at the targetPosition. + DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3( 0.0f, 0.0f, 0.0f ), TEST_LOCATION ); + + application.SendNotification(); + application.Render( static_cast< unsigned int >( durationSeconds * 0.5f * 1000.0f )/* 100% time progress */ ); + + application.SendNotification(); + DALI_TEST_EQUALS( actor.GetCurrentPosition(), targetPosition, TEST_LOCATION ); + + application.SendNotification(); + application.Render( static_cast< unsigned int >( durationSeconds * 1.0f * 1000.0f ) + 1u /*just beyond the animation duration*/ ); + + application.SendNotification(); + application.Render(0); + application.SendNotification(); + finishCheck.CheckSignalReceived(); + + // After all animation finished, arrives at the target. + DALI_TEST_EQUALS( actor.GetCurrentPosition(), targetPosition, TEST_LOCATION ); + + finishCheck.Reset(); + } + + END_TEST; +} + int UtcDaliAnimationGetLoopingModeP(void) { TestApplication application; diff --git a/dali/internal/update/animation/scene-graph-animator.h b/dali/internal/update/animation/scene-graph-animator.h index 19d4ecc..aff2b2c 100644 --- a/dali/internal/update/animation/scene-graph-animator.h +++ b/dali/internal/update/animation/scene-graph-animator.h @@ -140,6 +140,10 @@ public: value = 2.0f * std::abs( progress - 0.5f ); } } + else + { + value = progress; + } return value; } @@ -509,7 +513,7 @@ public: */ virtual void Update( BufferIndex bufferIndex, float progress, bool bake ) { - if( mLoopCount != 1 ) // Looping mode + if( mLoopCount >= 0 ) { // Update the progress value progress = SetProgress( progress ); @@ -668,7 +672,7 @@ public: */ virtual void Update( BufferIndex bufferIndex, float progress, bool bake ) { - if( mLoopCount != 1 ) // Looping mode + if( mLoopCount >= 0 ) { // Update the progress value progress = SetProgress( progress ); -- 2.7.4