From e0c08bc57e2e62cd39413bec69e10d832a815b30 Mon Sep 17 00:00:00 2001 From: Erik Date: Tue, 12 May 2026 18:00:01 +0200 Subject: [PATCH] feat(phys L.2a slice 2): include hit object guid in [resolve] probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- src/AcDream.Core/Physics/PhysicsEngine.cs | 28 +++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/AcDream.Core/Physics/PhysicsEngine.cs b/src/AcDream.Core/Physics/PhysicsEngine.cs index 696a635..4bfcb3e 100644 --- a/src/AcDream.Core/Physics/PhysicsEngine.cs +++ b/src/AcDream.Core/Physics/PhysicsEngine.cs @@ -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}")); }