feat(phys L.2a slice 2): include hit object guid in [resolve] probe

Extends the existing [resolve] probe line to surface
ci.LastCollidedObjectGuid (hit object) + ci.CollidedWithEnvironment
(terrain hit flag) + ci.CollideObjectGuids.Count (when >1) so the
operator can tell WHICH entity the wall is, not just the wall normal.

Tonight's L.2a slice 1 trace caught a clean wall-slide at the
Holtburg-area doorway (n=(0,1,0), 122 hit=yes lines), but had no way
to attribute the hit to a specific entity — the L.2d sub-direction
call (door collision shape vs building wall mesh) needs the entity id
to pick the right fix. This extension provides it on the next run.

Format change for [resolve] hit field:
  Before: hit=yes n=(0.00,1.00,0.00)
  After:  hit=yes n=(0.00,1.00,0.00) obj=0xCC0CXXXX
          hit=yes n=(0.00,1.00,0.00) env
          hit=yes n=(0.00,1.00,0.00) obj=0xCC0CXXXX env nObj=3

Pure additive within the existing PhysicsDiagnostics.ProbeResolveEnabled
gate. No new env var, no new file. Build green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-12 18:00:01 +02:00
parent ebef82034e
commit e0c08bc57e

View file

@ -691,10 +691,30 @@ public sealed class PhysicsEngine
string probeCp = ci.ContactPlaneValid
? "valid"
: (ci.LastKnownContactPlaneValid ? "lastKnown" : "none");
string probeHit = collisionNormalValid
? System.FormattableString.Invariant(
$"yes n=({collisionNormal.X:F2},{collisionNormal.Y:F2},{collisionNormal.Z:F2})")
: "no";
string probeHit;
if (collisionNormalValid)
{
// L.2a slice 2 (2026-05-12): include the hit object's guid +
// environment flag so we can tell whether the wall is a building
// (CBuildingObj), a door (CC0Cxxxx range), an NPC, or terrain.
// Without this we know the wall normal but not the responsible
// entity — half the L.2d sub-direction call.
string objPart = ci.LastCollidedObjectGuid.HasValue
? System.FormattableString.Invariant(
$" obj=0x{ci.LastCollidedObjectGuid.Value:X8}")
: "";
string envPart = ci.CollidedWithEnvironment ? " env" : "";
int objCount = ci.CollideObjectGuids.Count;
string objCountPart = objCount > 1
? System.FormattableString.Invariant($" nObj={objCount}")
: "";
probeHit = System.FormattableString.Invariant(
$"yes n=({collisionNormal.X:F2},{collisionNormal.Y:F2},{collisionNormal.Z:F2}){objPart}{envPart}{objCountPart}");
}
else
{
probeHit = "no";
}
Console.WriteLine(System.FormattableString.Invariant(
$"[resolve] ent=0x{movingEntityId:X8} in=({currentPos.X:F3},{currentPos.Y:F3},{currentPos.Z:F3}) cell=0x{cellId:X8} tgt=({targetPos.X:F3},{targetPos.Y:F3},{targetPos.Z:F3}) out=({probePost.X:F3},{probePost.Y:F3},{probePost.Z:F3}) cell=0x{sp.CheckCellId:X8} ok={ok} groundedIn={isOnGround} cp={probeCp} hit={probeHit} walkable={sp.HasLastWalkablePolygon}"));
}