probe(physics): ACDREAM_PROBE_SUPPORT + ACDREAM_WIRE_MESH — separate #337's three candidates
The user is wedged at the top of Neftet rock plateaus, jumps sink into the mesh, and a corpse falls straight through. ACDREAM_PROBE_REACH already ruled out its own domain: blocked=0, every candidate tested-ok. Three candidates remain — terrain support, a collision mesh not where its visual is, or the transition wedging on an unobstructed path. ACDREAM_PROBE_RESOLVE alone cannot separate them. It prints a three-value contact-plane token, no plane normal, no plane height, no terrain sample and no plane provenance, so all three produce the same line. Two additions: [support] — one line per resolve for EVERY body, not just the player. A corpse is a plain physics body with no player-specific logic, so its fall-through is the cheapest available control on "movement code vs geometry data", and it is invisible to any player-filtered probe. The line samples the outdoor terrain INDEPENDENTLY at the body's own out-XY and prints the contact plane's own height at that same XY. Two heights at one point make support=terrain / object / none a measurement rather than an inference, and cpSrc= names the site that asserted the plane so provenance and classification cross-check. [geom] — once per GfxObj that comes near a mover: the object's physics-BSP vertex cloud against its visual mesh AABB in the same local frame, through the same prepared accessors the resolver queries. verdict=coincident REFUTES the working hypothesis for that object outright; no-physics-bsp / empty-physics-bsp / displaced / extent-mismatch each name a specific data defect. Built to refute, not to confirm — two diagnoses on this defect's lineage have already been refuted by measurement. ACDREAM_WIRE_MESH upgrades the existing F2 overlay, which drew a broadphase proxy cylinder for BSP objects and so could not answer the question at all, to the real physics-BSP polygon edges (cyan) beside the visual mesh box (magenta) and the terrain surface (yellow). Own class per code-structure rule 1. The provenance latch lives on PhysicsDiagnostics, not on CollisionInfo. Two fields there first — the obvious home — broke the flat/graph differential referee and the scratch-reset poison test, both of which compare CollisionInfo member-for-member. Teaching either to skip a member is a one-line green fix that puts a permanent hole in a referee whose whole job is comparing everything. Captured as feedback_probe_state_off_compared_types. Seven tests cover the support classifier's boundaries: a wrong classifier does not fail to answer, it answers confidently wrong. Gates: Release build 0 errors; complete suite 11,225 passed / 4 skipped / 0 failed from a cleaned tree — baseline 11,218/4/0 plus exactly the seven new tests, skips unchanged. Issue #337 filed with the symptom set, what is ruled out, and a table of what each possible output means. All of this is TEMPORARY and recorded for stripping with the physics-probe family. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
13fcf38138
commit
49a7e90652
9 changed files with 1376 additions and 1 deletions
|
|
@ -783,4 +783,52 @@ public static class RenderingDiagnostics
|
|||
/// </summary>
|
||||
public static string? FrameHistoryPath { get; } =
|
||||
Environment.GetEnvironmentVariable("ACDREAM_FRAME_HISTORY");
|
||||
|
||||
// ── #337 collision-mesh wireframe (2026-08-06 — TEMPORARY) ──────────────
|
||||
//
|
||||
// The F2 collision overlay already existed, but for a BSP object it drew a
|
||||
// proxy cylinder sized from the REGISTERED BROADPHASE RADIUS. That shows
|
||||
// where the collision system thinks the object roughly is; it cannot show
|
||||
// where the collision SURFACES are, which is the only thing that answers
|
||||
// "is the collision geometry where the visual geometry is". The knobs
|
||||
// below turn F2 into the real answer: the actual physics-BSP polygon
|
||||
// edges, in world space, next to the same object's visual mesh box.
|
||||
//
|
||||
// Off by default, so F2 keeps its old cheap behaviour for anyone who wants
|
||||
// it and this costs nothing until asked for.
|
||||
|
||||
/// <summary>
|
||||
/// When true, the F2 collision overlay draws each nearby object's REAL
|
||||
/// physics-BSP polygon edges (cyan) and, beside them, the same object's
|
||||
/// visual mesh bounding box (magenta), plus the terrain triangle under the
|
||||
/// player (yellow). Any separation between the cyan surfaces and the
|
||||
/// object you can see is the "collision is not where the visual is"
|
||||
/// defect, read directly off the screen instead of inferred from a log.
|
||||
/// Initial state from <c>ACDREAM_WIRE_MESH=1</c>.
|
||||
/// TEMPORARY — strip with the #337 probe family.
|
||||
/// </summary>
|
||||
public static bool CollisionMeshWireframeEnabled { get; set; } =
|
||||
Environment.GetEnvironmentVariable("ACDREAM_WIRE_MESH") == "1";
|
||||
|
||||
/// <summary>
|
||||
/// Radius in metres around the player within which
|
||||
/// <see cref="CollisionMeshWireframeEnabled"/> resolves polygon geometry.
|
||||
/// A whole landblock of rock is far more geometry than a line list wants;
|
||||
/// 30 m covers everything you can wedge against. Override with
|
||||
/// <c>ACDREAM_WIRE_RADIUS=<metres></c>.
|
||||
/// </summary>
|
||||
public static float CollisionMeshWireframeRadius { get; set; } =
|
||||
ParsePositiveFloat(
|
||||
Environment.GetEnvironmentVariable("ACDREAM_WIRE_RADIUS"),
|
||||
fallback: 30f);
|
||||
|
||||
private static float ParsePositiveFloat(string? raw, float fallback)
|
||||
=> float.TryParse(
|
||||
raw,
|
||||
System.Globalization.NumberStyles.Float,
|
||||
System.Globalization.CultureInfo.InvariantCulture,
|
||||
out float value)
|
||||
&& value > 0f
|
||||
? value
|
||||
: fallback;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue