fix: interpolator in cpp runtime (#10752) 01c1b43af9

* fix: interpolator in cpp runtime

Co-authored-by: hernan <hernan@rive.app>
This commit is contained in:
bodymovin
2025-10-14 02:43:50 +00:00
parent e4dae96988
commit a839f067b0
13 changed files with 49 additions and 11 deletions

View File

@@ -1 +1 @@
a3f6433c00cac824852ba6eb383ce8a8d53fcf3c
01c1b43af9ac51debb54e99a326405460b873fda

View File

@@ -70,6 +70,7 @@ void InterpolatorAdvancer::advanceAnimationData(float elapsedTime)
}
return;
}
animationData->elapsedSeconds += elapsedTime;
float f =
std::fmin(1.0f,
m_converter->duration() > 0
@@ -80,21 +81,23 @@ void InterpolatorAdvancer::advanceAnimationData(float elapsedTime)
f = m_converter->interpolator()->transform(f);
}
animationData->interpolate(f, m_currentValue);
animationData->elapsedSeconds += elapsedTime;
}
bool InterpolatorAdvancer::advance(float elapsedTime)
{
auto animationData = currentAnimationData();
if (animationData->to->compare(m_currentValue))
if (animationData->to->compare(m_currentValue) || elapsedTime == 0)
{
return false;
}
auto prevTime = animationData->elapsedSeconds;
advanceAnimationData(elapsedTime);
if (animationData->elapsedSeconds < m_converter->duration())
if (prevTime < m_converter->duration())
{
m_converter->markConverterDirty();
}
if (animationData->elapsedSeconds < m_converter->duration())
{
return true;
}
return false;
@@ -142,10 +145,6 @@ bool DataConverterInterpolator::advance(float elapsedTime)
{
return false;
}
if (elapsedTime == 0)
{
return false;
}
// Advance can be called multiple times in a single frame.
// We want to make sure that two advances with time > 0 have elapsed before
// considering the state as second frame.

Binary file not shown.

View File

@@ -883,7 +883,7 @@ TEST_CASE("Reset randomization only once", "[silver]")
artboard->draw(renderer.get());
}
// Random generation hasn't been called again
// Random generation has been called again
REQUIRE(RandomProvider::totalCalls() == 1);
RandomProvider::clearRandoms();
CHECK(silver.matches("formula_random-once"));
@@ -920,7 +920,6 @@ TEST_CASE("Reset randomization on every change", "[silver]")
silver.addFrame();
RandomProvider::addRandomValue(1.0f);
numProp->propertyValue(500);
stateMachine->advanceAndApply(0.1f);
artboard->draw(renderer.get());
@@ -1048,4 +1047,44 @@ TEST_CASE("interactive and non interactive scrolling", "[silver]")
artboard->draw(renderer.get());
CHECK(silver.matches("interactive_scrolling"));
}
TEST_CASE("Interpolator returns advance status as true until it settles",
"[silver]")
{
SerializingFactory silver;
auto file = ReadRiveFile("assets/interpolate_to_end.riv", &silver);
auto artboard = file->artboardNamed("child");
silver.frameSize(artboard->width(), artboard->height());
REQUIRE(artboard != nullptr);
auto stateMachine = artboard->stateMachineAt(0);
int viewModelId = artboard.get()->viewModelId();
auto vmi = viewModelId == -1
? file->createViewModelInstance(artboard.get())
: file->createViewModelInstance(viewModelId, 0);
auto numProp = vmi->propertyValue("num")->as<ViewModelInstanceNumber>();
stateMachine->bindViewModelInstance(vmi);
stateMachine->advanceAndApply(0.1f);
auto renderer = silver.makeRenderer();
artboard->draw(renderer.get());
numProp->propertyValue(1000);
stateMachine->advanceAndApply(0.001f);
auto shouldAdvance = true;
while (shouldAdvance)
{
silver.addFrame();
shouldAdvance = stateMachine->advanceAndApply(0.25f);
artboard->draw(renderer.get());
}
CHECK(silver.matches("interpolate_to_end"));
}

Binary file not shown.