using XFEEDToolBox.Core.Galaxy; using XFEEDToolBox.Core.Models; using XFEEDToolBox.Core.Navigation; using XFEExtension.NetCore.XUnit.Attributes; namespace XFEEDToolBox.Test; [TestFixture] public class GalaxyMapGeometryTests { private static Coordinates OnGridPlane(GalaxyCamera camera, double x, double y) { var ray = camera.Forward + camera.Right * ((x - camera.Width / 2) / camera.FocalLength) + camera.Up * ((camera.Height / 2 - y) / camera.FocalLength); var distance = (camera.Focus.Y - camera.Eye.Y) / ray.Y; return new(camera.Eye.X + ray.X * distance, camera.Focus.Y, camera.Eye.Z + ray.Z * distance); } [Test] public void PerspectiveGridStaysBoundedAndSnappedToActualGalacticCoordinates() { Span lines = stackalloc MapSegment[InfiniteGalaxyGrid.MaximumLines]; foreach (var (focus, yaw, pitch, scale) in new[] { (new Coordinates(0, 0, 0), .3, .45, 4d), (new Coordinates(49985, -610, 24105), 2.7, -.7, .001), (new Coordinates(-43187, 287, 38116), -1.4, 1.45, 1000d), (new Coordinates(133, 49, -95), .8, .02, 4d) }) { var camera = GalaxyCamera.Create(focus, 3840, 2088, yaw, pitch, scale, 391, -173); var count = GalaxyMapGeometry.WriteGrid(lines, camera, out var step); Check.That(count is > 0 and <= InfiniteGalaxyGrid.MaximumLines && step > 0); foreach (var line in lines[..count]) { foreach (var (x, y) in new[] { (line.X1, line.Y1), (line.X2, line.Y2) }) Check.That(double.IsFinite(x + y) && x >= -1e-6 && x <= camera.Width + 1e-6 && y >= -1e-6 && y <= camera.Height + 1e-6); var a = OnGridPlane(camera, line.X1, line.Y1); var b = OnGridPlane(camera, line.X2, line.Y2); var fixedX = Math.Abs(a.X - b.X) / step < 1e-5 && Math.Abs(a.X / step - Math.Round(a.X / step)) < 1e-5; var fixedZ = Math.Abs(a.Z - b.Z) / step < 1e-5 && Math.Abs(a.Z / step - Math.Round(a.Z / step)) < 1e-5; Check.That(fixedX || fixedZ, "Grid lines must retain their absolute Galactic lattice after pan, orbit and zoom."); } } } [Test] public void RouteCrossingTheEyePlaneIsClippedToTheViewportInsteadOfMirrored() { var camera = GalaxyCamera.Create(new(150, 29, -300), 1600, 900, .7, .5, 4); Coordinates At(Vector3d delta) => new(camera.Focus.X + delta.X, camera.Focus.Y + delta.Y, camera.Focus.Z + delta.Z); var from = At(camera.Forward * (-camera.Distance * 2) + camera.Right * -camera.Distance); var to = At(camera.Forward * camera.Distance + camera.Right * camera.Distance); Check.That(GalaxyMapGeometry.TryProjectSegment(camera, from, to, out var segment)); foreach (var (x, y) in new[] { (segment.X1, segment.Y1), (segment.X2, segment.Y2) }) Check.That(double.IsFinite(x + y) && x >= -1e-6 && x <= camera.Width + 1e-6 && y >= -1e-6 && y <= camera.Height + 1e-6); Check.That(!GalaxyMapGeometry.TryProjectSegment(camera, from, At(camera.Forward * (-camera.Distance * 3)), out _)); } [Test] public void EdgeOnGridAndUndersizedOutputDoNotEmitPartialGeometry() { Span lines = stackalloc MapSegment[InfiniteGalaxyGrid.MaximumLines]; var camera = GalaxyCamera.Create(new(0, 0, 0), 1600, 900, .3, 0, 4); Check.Equal(0, GalaxyMapGeometry.WriteGrid(lines, camera, out _)); camera = GalaxyCamera.Create(new(0, 0, 0), 1600, 900, .3, .5, 4); Check.Equal(0, GalaxyMapGeometry.WriteGrid(lines[..7], camera, out _)); } }