diag(render): camera-collision indoor non-engagement — RED test + diagnosis
Root cause (b): ShadowObjectRegistry.GetNearbyObjects (line 480) returns early when primaryCellId is an indoor cell, skipping the outdoor radial sweep that contains the landblock-baked cottage exterior-shell GfxObj. The issue-#98 fix that prevents the player's head sphere from being capped by the cottage floor also prevents the IsViewer camera sweep from finding the exterior building shell. Result: camera passes through exterior walls unimpeded, driving the residual transparent-walls symptom after the U.4c flap fix. Evidence: live capture shows eyeInRoot=n ~90% of frames, eye-player distance 3.43m (full chase, no pull-in). RED test deterministically reproduces: synthetic indoor cell (0xA9B40175) + exterior GfxObj registered at cellScope=0; probe SweepEye returns pulledIn=0.0000m (full eye distance Y=5.0, wall at Y=4.0). Fix design: exempt IsViewer from the indoor-primary early-return gate in GetNearbyObjects — retail's find_obj_collisions (named-retail :308918) has no indoor/outdoor cell gate; the acdream fix is correct only for IsPlayer. Apparatus committed: - tests/AcDream.App.Tests/Rendering/CameraCollisionIndoorTests.cs (RED test) - docs/research/2026-05-31-camera-collision-indoor-diagnosis.md (findings + design) - PhysicsCameraCollisionProbe.cs [flap-sweep] diagnostic retained (U.4c spike) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
95b6874c12
commit
3066460370
3 changed files with 520 additions and 1 deletions
|
|
@ -56,7 +56,31 @@ public sealed class PhysicsCameraCollisionProbe : ICameraCollisionProbe
|
|||
| ObjectInfoState.FreeRotate | ObjectInfoState.PerfectClip,
|
||||
movingEntityId: selfEntityId); // skip the player's own ShadowEntry
|
||||
|
||||
return FromSpherePath(r.Position, ViewerSphereRadius);
|
||||
Vector3 eye = FromSpherePath(r.Position, ViewerSphereRadius);
|
||||
|
||||
// Phase U.4c spike apparatus (THROWAWAY — strip with ACDREAM_PROBE_FLAP).
|
||||
// The post-fix [flap-cam] capture shows the eye flying to full chase distance
|
||||
// (eyeInRoot=n ~90%) in cells like 0xA9B40174/0175 — i.e. this sweep is not
|
||||
// stopping it. This line answers WHY, the fork that picks the primary residual
|
||||
// fix: pulledIn≈0 with resolved=Y bsp=ok ⇒ the sweep ran but found NOTHING in
|
||||
// that cell (space genuinely open, or wall geometry the per-cell sweep can't
|
||||
// reach → clip-robustness is primary); resolved=n / bsp=nobsp/noroot ⇒ collision
|
||||
// can't even run there (cell/BSP not loaded → camera-collision reliability is
|
||||
// primary); pulledIn large ⇒ collision IS engaging (eye leaving is then expected
|
||||
// through an opening). Paired per-frame with the builder's [flap]/[flap-cam].
|
||||
if (AcDream.Core.Rendering.RenderingDiagnostics.ProbeFlapEnabled)
|
||||
{
|
||||
var cp = _physics.DataCache?.GetCellStruct(cellId);
|
||||
string bsp = cp?.BSP is null ? "nobsp" : (cp.BSP.Root is null ? "noroot" : "ok");
|
||||
float desiredBack = Vector3.Distance(pivot, desiredEye);
|
||||
float eyeBack = Vector3.Distance(pivot, eye);
|
||||
System.Console.WriteLine(
|
||||
$"[flap-sweep] cell=0x{cellId:X8} resolved={(cp is not null ? "Y" : "n")} bsp={bsp} " +
|
||||
$"desiredBack={desiredBack:F2} eyeBack={eyeBack:F2} pulledIn={desiredBack - eyeBack:F2} " +
|
||||
$"collNormValid={r.CollisionNormalValid}");
|
||||
}
|
||||
|
||||
return eye;
|
||||
}
|
||||
|
||||
/// <summary>Eye/pivot point → InitPath path point (subtract the sphere-center offset).</summary>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue