Fix keepGoing when a work area is used. Fixes an issue introduced here https://github.com/rive-app/rive/pull/5849 where we added some extra smarts to keepGoing which didn't take the work area into account. Adds tests to both editor and runtime! Diffs= 853ae7de1 Fix keepGoing when a work area is used. (#5939) Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>
diff --git a/.rive_head b/.rive_head index 6b700cd..290281e 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -33aec1b20028fed8d1cf790378db26241212784f +853ae7de1d020bc13e84359f816215764923215c
diff --git a/include/rive/animation/linear_animation_instance.hpp b/include/rive/animation/linear_animation_instance.hpp index 36656d5..d7f6b25 100644 --- a/include/rive/animation/linear_animation_instance.hpp +++ b/include/rive/animation/linear_animation_instance.hpp
@@ -31,6 +31,9 @@ // Returns the direction that we are currently playing in float direction() const { return m_direction; } + // Returns speed in the current direction of the animation. + float directedSpeed() const { return m_direction * speed(); } + // Update the direction of the animation instance, positive value for // forwards Negative for backwards void direction(int direction) @@ -60,8 +63,8 @@ bool keepGoing() const { return this->loopValue() != static_cast<int>(rive::Loop::oneShot) || - (m_direction > 0 && m_time < m_animation->durationSeconds()) || - (m_direction < 0 && m_time > 0); + (directedSpeed() > 0 && m_time < m_animation->endSeconds()) || + (directedSpeed() < 0 && m_time > m_animation->startSeconds()); } float totalTime() const { return m_totalTime; }
diff --git a/test/linear_animation_test.cpp b/test/linear_animation_test.cpp index 8b073ce..fe59c28 100644 --- a/test/linear_animation_test.cpp +++ b/test/linear_animation_test.cpp
@@ -1,5 +1,6 @@ #include <rive/artboard.hpp> #include <rive/animation/linear_animation.hpp> +#include <rive/animation/linear_animation_instance.hpp> #include "utils/no_op_factory.hpp" #include "rive_file_reader.hpp" #include "rive_testing.hpp" @@ -79,4 +80,32 @@ animation->quantize(false); animation->apply(artboard, 0.5f); REQUIRE(ellipse->x() == 200.0f); +} + +TEST_CASE("LinearAnimation reports when to keep going correctly", "[animation]") +{ + rive::NoOpFactory emptyFactory; + // For each of these tests, we cons up a dummy artboard/instance + // just to make the animations happy. + rive::Artboard ab(&emptyFactory); + auto abi = ab.instance(); + + rive::LinearAnimation* linearAnimation = new rive::LinearAnimation(); + linearAnimation->duration(60); + linearAnimation->fps(60); + linearAnimation->speed(1); + linearAnimation->enableWorkArea(true); + linearAnimation->workStart(30); + linearAnimation->workEnd(42); + + auto animationInstance = rive::LinearAnimationInstance(linearAnimation, abi.get()); + + REQUIRE(animationInstance.advance(0.0f)); + REQUIRE(animationInstance.time() == 0.5f); + REQUIRE(animationInstance.advance(0.1f)); + REQUIRE(animationInstance.time() == 0.6f); + REQUIRE(!animationInstance.advance(0.2f)); + REQUIRE(animationInstance.time() == 0.7f); + + delete linearAnimation; } \ No newline at end of file