fix: foot-IK pelvis drop ignores feet over drop-offs (+ solver perf)#80
Merged
Conversation
Pelvis-drop correctness:
The pelvis lowers to accommodate the lowest planted foot. But a foot over a
gap or a drop-off — whose ground raycast can hit up to foot_ik_max_adjustment
(0.5 m) below the foot — was treated as a deep plant and dragged the whole
pelvis down to foot_ik_max_pelvis_drop (0.35 m), sinking the body and breaking
the OTHER, genuinely-planted foot's ground contact.
Now a foot only informs the pelvis drop when it found ground the body can
actually reach (within foot_ik_max_pelvis_drop); feet over a gap (no hit) or a
deeper drop-off are excluded from the min. offset_* feed only the pelvis drop —
the per-leg solves already target the raw ground hit — so the legs still reach
toward real ground; only the spurious whole-body sink is removed.
New regression test (test_foot_ik.gd): split ground, solid under one foot and a
~1 m drop-off under the other, asserts the planted foot still plants and the
pelvis stays near neutral instead of being yanked to -0.35.
Solver per-frame perf (no behavior change):
- The override dictionary handed to the SpringResolver is now a reused buffer
instead of a fresh {} each solve. Safe: the controller's solve and the
spring's read never interleave within a physics frame.
- Animation bone globals are memoized per solve (_anim_global / _anim_cache),
so the hip/leg reads and the full-body shift no longer re-walk shared parent
chains.
Validated: headless import clean; GUT 113/113 (3x stable, no orphans);
scene-smoke clean on foot_ik_demo.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This was referenced Jun 19, 2026
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a foot-IK pelvis-drop bug where one foot over a gap/drop-off dragged the whole body down, plus removes the solver's per-frame allocations. Part of the 0.3.x finalization gate.
The bug (correctness)
The pelvis lowers to accommodate the lowest planted foot. But
offset_*(which feed the pelvis drop) come from a ground raycast that can hit up tofoot_ik_max_adjustment(0.5 m) below the foot. So a foot stepping out over a ledge/pit — its raycast hitting ground far below — was treated as a deep plant and pulled the pelvis down tofoot_ik_max_pelvis_drop(0.35 m). That sank the body and lifted the other, genuinely-planted foot off its ground.The fix
A foot now only informs the pelvis drop when it found ground the body can actually reach (within
foot_ik_max_pelvis_drop). Feet over a gap (no raycast hit) or a deeper drop-off are excluded from theminf. Key property:offset_*feed only the pelvis drop — the per-leg IK solves already target the raw ground hit (gpos.y) — so legs still reach toward real ground; only the spurious whole-body sink is removed. On flat/normal terrain both feet are supported, so behavior is identical (existing flat-ground tests unchanged).Regression test
test_pelvis_ignores_foot_over_dropoffbuilds split ground — solid under the left foot, a ~1 m drop-off under the right — and asserts the left foot still plants and the pelvis stays near neutral (> -0.1). On the old code the pelvis converged to-0.35, so the test genuinely distinguishes the fix.Solver per-frame perf (no behavior change)
Dictionaryhanded to theSpringResolvereach solve is now a reused buffer instead of a fresh{}. Safe because the controller's solve and the spring's read never interleave within a physics frame (each node's_physics_processruns to completion in turn)._anim_global/_anim_cache), so the hip/leg reads and the full-body shift no longer re-walk shared parent chains.Validation
--quit-after 150): clean onfoot_ik_demoVisual sign-off
Wants an in-editor pass on varied terrain before merge — specifically: stand a character with one foot on a platform edge and the other over a gap/lower step, and confirm the body no longer sinks/crouches when a foot overhangs a drop-off, while normal uneven ground (stairs/slopes within reach) still drops the pelvis as before.
🤖 Generated with Claude Code