diag(physics): #42 add ACDREAM_AIRBORNE_DIAG [SWEEP] trace
Phase 1 of #42 root-cause investigation per the handoff doc. We
A/B confirmed (commit b37b713) that the ~1m XY drift on retail-
observed stationary jumps comes from inside ResolveWithTransition
when the per-tick airborne sweep runs (CellId fix at GameWindow.cs
3467). What we don't yet know: whether the drift originates in
H1 (initial-overlap depenetration along a tilted-terrain normal),
H2 (step-down probe firing despite isOnGround=false), or H3
(EdgeSlide on near-vertical motion grazing a wall).
This diagnostic gates a one-line Console trace on
ACDREAM_AIRBORNE_DIAG=1 AND !isOnGround so it doesn't pollute
grounded movement, and prints:
[SWEEP] airborne pre=(...) target=(...) post=(...)
cell=PRE->POST ok=BOOL deltaXY=(dx,dy)
cp=valid|none cpN=(nx,ny,nz)
deltaXY = post - target — for a clean stationary +Z jump we
expect (0,0). Non-zero with cp=valid and a tilted cpN confirms
H1; non-zero direction tracking actor facing instead of terrain
orientation points to H2/H3.
Code-walk findings recorded for the next investigation pass:
- K-fix7 already prevents seeding ContactPlane on entry for
airborne (PhysicsEngine.cs:493-519), so step 0's AdjustOffset
cannot consume a stale plane.
- BUT ValidateWalkable can still SET ContactPlane during step 0's
collision pass via the "below plane" branch (TransitionTypes.cs
1320-1352) when sphere lowPoint dips below the tilted terrain
triangle. Step 1's AdjustOffset would then consume that fresh
plane and the "moving away from contact plane" branch
(TransitionTypes.cs:1749-1754) projects the +Z offset along the
slope normal, redirecting Z motion into XY.
- Step-down branch is correctly gated on oi.Contact (matches
retail CTransition::transitional_insert at named-retail
acclient_2013_pseudo_c.txt:273249, "(state & 1) == 0" returns
OK without firing step-down).
- Retail's IS_VIEWER_OI=0x4 branch in OBJECTINFO::validate_walkable
(acclient.h:6185) is never set anywhere in the named decomp,
so the airborne path runs the same code in retail as in acdream.
User repros at flat plaza / east hillside / north hillside; the
direction-correlation of deltaXY with local terrain orientation
identifies which hypothesis is firing.
Build green; 13 PhysicsEngine tests green. No behavior change
when ACDREAM_AIRBORNE_DIAG is unset.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ce638eb56f
commit
a36369d8ca
1 changed files with 27 additions and 0 deletions
|
|
@ -625,6 +625,33 @@ public sealed class PhysicsEngine
|
|||
bool collisionNormalValid = ci.CollisionNormalValid;
|
||||
Vector3 collisionNormal = ci.CollisionNormal;
|
||||
|
||||
// #42 diagnostic (2026-05-05): trace airborne sweeps to identify the
|
||||
// source of the ~1m XY drift on retail-observed stationary jumps.
|
||||
// Gated on ACDREAM_AIRBORNE_DIAG=1 and !isOnGround. One line per
|
||||
// resolve call. deltaXY = post - target tells us how much the sweep
|
||||
// diverged from the requested target; for a clean stationary +Z
|
||||
// jump we expect (0,0). cp=valid with a tilted normal would confirm
|
||||
// H1 (initial-overlap depenetration → next-step AdjustOffset projects
|
||||
// the +Z offset along a non-+Z normal). User repros at flat plaza /
|
||||
// east hillside / north hillside; if drift direction tracks terrain
|
||||
// orientation, H1 is the cause; if it tracks actor facing, H2 / H3.
|
||||
if (!isOnGround
|
||||
&& Environment.GetEnvironmentVariable("ACDREAM_AIRBORNE_DIAG") == "1")
|
||||
{
|
||||
var post = sp.CheckPos;
|
||||
float dx = post.X - targetPos.X;
|
||||
float dy = post.Y - targetPos.Y;
|
||||
string cpInfo = ci.ContactPlaneValid
|
||||
? $"valid cpN=({ci.ContactPlane.Normal.X:F3},{ci.ContactPlane.Normal.Y:F3},{ci.ContactPlane.Normal.Z:F3})"
|
||||
: "none";
|
||||
Console.WriteLine(
|
||||
$"[SWEEP] airborne pre=({currentPos.X:F3},{currentPos.Y:F3},{currentPos.Z:F3}) " +
|
||||
$"target=({targetPos.X:F3},{targetPos.Y:F3},{targetPos.Z:F3}) " +
|
||||
$"post=({post.X:F3},{post.Y:F3},{post.Z:F3}) " +
|
||||
$"cell={cellId:X8}->{sp.CheckCellId:X8} ok={ok} " +
|
||||
$"deltaXY=({dx:F3},{dy:F3}) cp={cpInfo}");
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
bool onGround = ci.ContactPlaneValid
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue