using System.Numerics; using AcDream.App.Rendering; using Xunit; namespace AcDream.App.Tests.Rendering; public class OutdoorCellNodeTests { // A building cell at world-translate (10,0,0) with one exit portal (OtherCellId=0xFFFF) // whose local plane faces +X (InsideSide=0). The outdoor node must expose ONE portal // back into that building cell, with the entrance polygon moved to world space and the // inside-side flipped (so the outdoor half-space is "inside" the node). private static LoadedCell BuildingWithOneExit(uint cellId) { var cell = new LoadedCell { CellId = cellId }; cell.WorldTransform = Matrix4x4.CreateTranslation(10f, 0f, 0f); cell.InverseWorldTransform = Matrix4x4.CreateTranslation(-10f, 0f, 0f); cell.Portals.Add(new CellPortalInfo(OtherCellId: 0xFFFF, PolygonId: 0, Flags: 0, OtherPortalId: 0)); cell.ClipPlanes.Add(new PortalClipPlane { Normal = new Vector3(1, 0, 0), D = 0f, InsideSide = 0 }); cell.PortalPolygons.Add(new[] { new Vector3(0, -1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 2), new Vector3(0, -1, 2) }); return cell; } [Fact] public void Build_FromBuildingExit_AddsReversePortalIntoBuilding() { uint outdoorId = 0xA9B40031; var building = BuildingWithOneExit(0xA9B40170); var node = OutdoorCellNode.Build(outdoorId, new[] { building }); Assert.Equal(outdoorId, node.CellId); Assert.True(node.SeenOutside); Assert.True(node.IsOutdoorNode); // the flag PortalVisibilityBuilder keys the full-screen OutsideView on Assert.Equal(Matrix4x4.Identity, node.WorldTransform); Assert.Single(node.Portals); Assert.Equal((ushort)(0xA9B40170 & 0xFFFF), node.Portals[0].OtherCellId); // Reversed inside-side: the building's exit was InsideSide=0, the node's is 1. Assert.Equal(1, node.ClipPlanes[0].InsideSide); // Entrance polygon moved to world space (building translated +10 X): first vert x≈10. Assert.Equal(10f, node.PortalPolygons[0][0].X, 3); } [Fact] public void Build_NoBuildings_ReturnsEmptyPortalNode() { var node = OutdoorCellNode.Build(0xA9B40031, System.Array.Empty()); Assert.Empty(node.Portals); Assert.True(node.SeenOutside); Assert.True(node.IsOutdoorNode); } }