using System.Numerics; using AcDream.Core.Physics; using AcDream.Core.Selection; using DatReaderWriter.Enums; using Xunit; namespace AcDream.Core.Tests.Selection; public class CellBspRayOccluderTests { // Build a CellPhysics with a single triangular poly at world-Y=10. // Triangle vertices in local space, world transform = identity. // Uses the Resolved-only constructor path (BSP = null is allowed after Phase 1 relaxation). private static CellPhysics MakeWallCell() { var verts = new[] { new Vector3(-5, 10, 0), new Vector3( 5, 10, 0), new Vector3( 0, 10, 5), }; var poly = new ResolvedPolygon { Vertices = verts, Plane = new System.Numerics.Plane(new Vector3(0, -1, 0), 10f), NumPoints = 3, SidesType = CullMode.None, }; return new CellPhysics { BSP = null, // Occluder doesn't use BSP — direct poly iteration. Resolved = new() { [0] = poly }, WorldTransform = Matrix4x4.Identity, InverseWorldTransform = Matrix4x4.Identity, }; } [Fact] public void NearestWallT_RayHitsTriangle_ReturnsHitDistance() { var cell = MakeWallCell(); var origin = new Vector3(0, 0, 1); var direction = Vector3.UnitY; // travels +Y toward the wall at Y=10 float t = CellBspRayOccluder.NearestWallT(origin, direction, new[] { cell }); Assert.True(t > 9.9f && t < 10.1f, $"expected ~10, got {t}"); } [Fact] public void NearestWallT_RayMisses_ReturnsPositiveInfinity() { var cell = MakeWallCell(); var origin = new Vector3(0, 0, 1); var direction = -Vector3.UnitY; // travels AWAY from the wall float t = CellBspRayOccluder.NearestWallT(origin, direction, new[] { cell }); Assert.True(float.IsPositiveInfinity(t), $"expected +inf, got {t}"); } [Fact] public void NearestWallT_EmptyCellList_ReturnsPositiveInfinity() { var origin = Vector3.Zero; var direction = Vector3.UnitY; float t = CellBspRayOccluder.NearestWallT(origin, direction, System.Array.Empty()); Assert.True(float.IsPositiveInfinity(t)); } [Fact] public void NearestWallT_TwoCells_ReturnsNearer() { var nearCell = MakeWallCell(); // wall at Y=10 var farCell = MakeWallCell(); // Move farCell's transform to push it to Y=20. farCell = new CellPhysics { BSP = null, Resolved = nearCell.Resolved, WorldTransform = Matrix4x4.CreateTranslation(0, 10, 0), InverseWorldTransform = Matrix4x4.CreateTranslation(0, -10, 0), }; var origin = new Vector3(0, 0, 1); var direction = Vector3.UnitY; float t = CellBspRayOccluder.NearestWallT(origin, direction, new[] { farCell, nearCell }); Assert.True(t < 11f, $"expected near-cell hit ~10, got {t}"); } }