XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
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<MapSegment> 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<MapSegment> 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 _));
    }
}