fix(runtime): prevent IK constraint pose pop from stale FK base (#13301) e17fbf4aa8 Co-authored-by: hernan <hernan@rive.app>
diff --git a/.rive_head b/.rive_head index 348efd1..6143029 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -289d353ac57d5bd7b7264b258745abc3d9c8a8b6 +e17fbf4aa8f011ec64e94b982b4e7aa7e9874010
diff --git a/src/constraints/ik_constraint.cpp b/src/constraints/ik_constraint.cpp index 666f1c1..d56a5e2 100644 --- a/src/constraints/ik_constraint.cpp +++ b/src/constraints/ik_constraint.cpp
@@ -232,9 +232,9 @@ const Mat2D& parentWorld = getParentWorld(*bone); item.parentWorldInverse = parentWorld.invertOrIdentity(); - Mat2D& boneTransform = bone->mutableTransform(); - boneTransform = item.parentWorldInverse * bone->worldTransform(); - item.transformComponents = boneTransform.decompose(); + bone->updateTransform(); + bone->mutableWorldTransform() = parentWorld * bone->transform(); + item.transformComponents = bone->transform().decompose(); } int count = (int)m_FkChain.size();
diff --git a/tests/unit_tests/assets/ik_anim_test.riv b/tests/unit_tests/assets/ik_anim_test.riv new file mode 100644 index 0000000..4ddc70a --- /dev/null +++ b/tests/unit_tests/assets/ik_anim_test.riv Binary files differ
diff --git a/tests/unit_tests/runtime/ik_constraint_test.cpp b/tests/unit_tests/runtime/ik_constraint_test.cpp index 26f1f4c..868ab91 100644 --- a/tests/unit_tests/runtime/ik_constraint_test.cpp +++ b/tests/unit_tests/runtime/ik_constraint_test.cpp
@@ -7,6 +7,8 @@ #include <rive/bones/bone.hpp> #include "rive_file_reader.hpp" #include "rive_testing.hpp" +#include "utils/serializing_factory.hpp" +#include "rive/animation/state_machine_instance.hpp" #include <cstdio> TEST_CASE("ik with skinned bones orders correctly", "[file]") @@ -36,3 +38,37 @@ REQUIRE(skin->graphOrder() > one->graphOrder()); REQUIRE(skin->graphOrder() > two->graphOrder()); } + +TEST_CASE("IK constraint with non full strength", "[silver]") +{ + rive::SerializingFactory silver; + auto file = ReadRiveFile("assets/ik_anim_test.riv", &silver); + + auto artboard = file->artboardDefault(); + + silver.frameSize(artboard->width(), artboard->height()); + + auto renderer = silver.makeRenderer(); + + auto stateMachine = artboard->stateMachineAt(0); + + auto vmi = file->createViewModelInstance(artboard.get()->viewModelId(), 0); + + stateMachine->bindViewModelInstance(vmi); + stateMachine->advanceAndApply(0); + artboard->draw(renderer.get()); + + silver.addFrame(); + stateMachine->advanceAndApply(0.1f); + artboard->draw(renderer.get()); + + int frames = (int)(2.0f / 0.5f); + for (int i = 0; i < frames; i++) + { + silver.addFrame(); + stateMachine->advanceAndApply(0.5f); + artboard->draw(renderer.get()); + } + + CHECK(silver.matches("ik_anim_test")); +}
diff --git a/tests/unit_tests/silvers/ik_anim_test.sriv b/tests/unit_tests/silvers/ik_anim_test.sriv new file mode 100644 index 0000000..9a6f397 --- /dev/null +++ b/tests/unit_tests/silvers/ik_anim_test.sriv Binary files differ