From 2653896832abfe990f5a1cbf6f873e8362cf4f51 Mon Sep 17 00:00:00 2001 From: a-baran-orhan Date: Fri, 10 Jul 2026 21:05:11 +0300 Subject: [PATCH] fix: run reach-IK before the floor safety clamp so reaching limbs bend to the floor From a prone base, an authored reach pose (cobra: shoulders flex 50 + reach: hands floor) swung the arms through the floor via FK. The frame loop's floor safety clamp ran before reach-IK, so it resolved the penetration by lifting the entire rigid body until the hands cleared the floor - legs and pelvis levitating in mid-air. - Apply reaches after ground-lock/pins but before the clamp, so the arms solve down to the floor and the clamp becomes a no-op for grounded poses. - Make the 'floor' reach target mesh-aware: rest the visible palm on the floor instead of driving the wrist bone to y=0, removing the residual body lift from the bone-vs-mesh gap. --- packages/posecode-render/src/index.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/posecode-render/src/index.ts b/packages/posecode-render/src/index.ts index 8fe07fb..e8bed73 100644 --- a/packages/posecode-render/src/index.ts +++ b/packages/posecode-render/src/index.ts @@ -346,8 +346,12 @@ export function createViewer( effector: THREE.Object3D, ): THREE.Vector3 | null { if (target === "floor") { + // Rest the effector's MESH on the floor, not its bone origin: the hand + // mesh extends below the wrist bone, so a bone target of y=0 would sink + // the palm and force the floor safety clamp to lift the whole body. const p = effector.getWorldPosition(new THREE.Vector3()); - p.y = 0; + const box = new THREE.Box3().setFromObject(effector); + p.y = Number.isFinite(box.min.y) ? Math.max(0, p.y - box.min.y) : 0; return p; } const anchor = propAnchors.get(target); @@ -458,6 +462,14 @@ export function createViewer( depenetrate(mannequin); applyGroundLockTo(mannequin, info.groundLock, frameAnchors(info.rootYaw, info.rootOffset)); applyPins(info.pins); + // Reach-IK BEFORE the floor safety clamp. When authored FK pushes a + // reaching limb through the floor (cobra: prone + shoulders flex 50), + // the limb must bend to meet the floor. Running reaches after the clamp + // let the clamp "solve" the penetration first by hoisting the whole + // rigid body into the air — legs floating, the classic levitating-cobra + // bug. Ground-lock and pins have already fixed the root placement that + // floor/landmark targets resolve against. + applyReaches(info.reaches); // Safety net: nothing above ever intentionally pushes part of the body // below the floor, so clamp the root up whenever the lowest point dips // below y=0, a no-op whenever the pose is legitimately grounded or @@ -473,7 +485,6 @@ export function createViewer( mannequin.root.position.y -= box.min.y; mannequin.root.updateMatrixWorld(true); } - applyReaches(info.reaches); if (info.phaseName !== lastPhaseName) { lastPhaseName = info.phaseName; phaseCb({ phaseName: info.phaseName, ...(info.cue ? { cue: info.cue } : {}) });