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.Rendering;
using System.Numerics;
using XFEExtension.NetCore.XUnit.Attributes;

namespace XFEEDToolBox.Test;

[TestFixture]
public class GalaxyAppearanceTests
{
    [Test] public void SpectralColoursUseActualTypesAndUnknownTypesStayNeutral()
    {
        Check.Equal(0,StellarAppearance.ColourIndex("O (Blue-White) Star"));Check.Equal(5,StellarAppearance.ColourIndex("K"));
        Check.Equal(6,StellarAppearance.ColourIndex("M (Red dwarf) Star"));Check.Equal(10,StellarAppearance.ColourIndex("DA"));
        Check.Equal(11,StellarAppearance.ColourIndex("Neutron Star"));Check.Equal(13,StellarAppearance.ColourIndex(""));
        Check.That(StellarAppearance.Palette[0].B>StellarAppearance.Palette[0].R);
        Check.That(StellarAppearance.Palette[6].R>StellarAppearance.Palette[6].B);
        Check.Equal(10,"OBAFGKMLTY".Select(c=>StellarAppearance.Palette[StellarAppearance.ColourIndex(c.ToString())]).Distinct().Count());
        Check.Equal(6,StellarAppearance.ColourIndex("CJ"));Check.Equal(5,StellarAppearance.ColourIndex("TTS"));
        Check.Equal(12,StellarAppearance.ColourIndex("Supermassive Black Hole"));
    }
    [Test] public void StellarSpritesAttenuateWithDistanceAndKeepSelectionSeparateFromThePhotosphere()
    {
        var nearby=StellarAppearance.Sprite(4,0,4);var distant=StellarAppearance.Sprite(4,400,4);
        Check.That(nearby.CoreRadius>distant.CoreRadius&&nearby.Opacity>distant.Opacity);
        Check.That(nearby.CoreRadius<2&&nearby.Radius<12,"Normal stars must remain compact luminous points at the default map scale.");
        foreach(var importance in new[]{1,2,3})
        {
            var marked=StellarAppearance.Sprite(4,0,4,importance);
            Check.Equal(nearby.CoreRadius,marked.CoreRadius);Check.Equal(nearby.Opacity,marked.Opacity);
            if(importance>=2)Check.That(marked.Radius>=20,"Marker geometry must have enough space without enlarging the star.");
        }
        Check.That(StellarAppearance.Sprite(4,0,1000).CoreRadius>nearby.CoreRadius);
        Check.That(StellarAppearance.Sprite(4,0,.001).CoreRadius<nearby.CoreRadius);
    }
    [Test] public void CompactObjectsAndBrownDwarfsHaveTheirOwnStellarMorphology()
    {
        Check.Equal(StellarMorphology.BrownDwarf,StellarAppearance.Sprite(7,0,4).Morphology);
        Check.Equal(StellarMorphology.WhiteDwarf,StellarAppearance.Sprite(10,0,4).Morphology);
        Check.Equal(StellarMorphology.NeutronStar,StellarAppearance.Sprite(11,0,4).Morphology);
        Check.Equal(StellarMorphology.BlackHole,StellarAppearance.Sprite(12,0,4).Morphology);
        Check.Equal(0f,StellarAppearance.Sprite(12,0,4).Corona);
        Check.That(StellarAppearance.Sprite(9,0,4).Opacity<StellarAppearance.Sprite(4,0,4).Opacity);
        var invalid=StellarAppearance.Sprite(-1,double.NaN,double.PositiveInfinity);
        Check.That(float.IsFinite(invalid.Radius+invalid.CoreRadius+invalid.Opacity));
    }
    [Test] public void OriginalCompactSizeReplacesSpectralEstimatesAndPreservesItsRatios()
    {
        var blue=StellarAppearance.Sprite(0,0,4,originalSize:.7f);
        var red=StellarAppearance.Sprite(6,0,4,originalSize:.7f);
        Check.Equal(blue.CoreRadius,red.CoreRadius);
        var small=StellarAppearance.Sprite(4,0,4,originalSize:.3f);
        var large=StellarAppearance.Sprite(4,0,4,originalSize:1.2f);
        Check.That(Math.Abs(large.CoreRadius/small.CoreRadius-4)<.0001f);
        Check.That(StellarAppearance.Sprite(4,0,4,originalSize:.05f).CoreRadius<.2f);
        var marked=StellarAppearance.Sprite(4,0,4,3,originalSize:.3f);
        Check.Equal(small.CoreRadius,marked.CoreRadius);Check.That(marked.Radius>=26);
        Check.Equal(StellarAppearance.Sprite(4,0,4),StellarAppearance.Sprite(4,0,4,originalSize:float.NaN));
        Check.Equal(StellarAppearance.Sprite(4,0,4,realistic:false),StellarAppearance.Sprite(4,0,4,realistic:false,originalSize:1.2f));
    }
    [Test] public void TerritoryPointsUseOriginalBoundedCameraDistanceTerm()
    {
        foreach(var distance in new[]{-1d,0d,10d,25d})Check.Equal(1f,StellarAppearance.PowerTerritoryDistanceScale(distance));
        Check.Equal(1.5f,StellarAppearance.PowerTerritoryDistanceScale(37.5));
        Check.Equal(2f,StellarAppearance.PowerTerritoryDistanceScale(50));
        Check.Equal(2f,StellarAppearance.PowerTerritoryDistanceScale(50000));
        Check.Equal(1f,StellarAppearance.PowerTerritoryDistanceScale(double.NaN));
        Check.Equal(1f,StellarAppearance.PowerTerritoryDistanceScale(double.PositiveInfinity));
    }
    [Test] public void OriginalPhysicalSpriteUsesNativeLuminosityOverrideAndSeparateCompactObjects()
    {
        const int regular=25<<10;
        foreach(var pair in new[]{(0,0),(2,1),(7,2),(9,3),(12,4),(17,5),(40,7),(41,8),(42,8),(43,9),(46,10),(48,13),(63,13)})
            Check.Equal(pair.Item2,StellarAppearance.OriginalSprite((ushort)(regular|pair.Item1)));
        for(var luminosity=0;luminosity<=13;luminosity++)
            Check.Equal(5,StellarAppearance.OriginalSprite((ushort)(luminosity<<10|2)));
        Check.Equal(6,StellarAppearance.OriginalSprite((ushort)(24<<10|2)));
        Check.Equal(8,StellarAppearance.OriginalSprite(41));
        Check.Equal(8,StellarAppearance.OriginalSprite((ushort)(24<<10|42)));
    }
    [Test] public void OriginalStellarHalfExtentMatchesProjectedUnitQuadWithoutPixelMinimum()
    {
        var camera=GalaxyCamera.Create(new(0,0,0),1600,900,.3,.45,4,20,-10);
        foreach(var depth in new[]{camera.Distance*.1,camera.Distance,camera.Distance*3})
        foreach(var size in new[]{.05f,.3f,.7f,2f})
        {
            var centre=new XFEEDToolBox.Core.Models.Coordinates(camera.Eye.X+camera.Forward.X*depth,camera.Eye.Y+camera.Forward.Y*depth,camera.Eye.Z+camera.Forward.Z*depth);
            var half=(float)(Half)size;
            var corner=new XFEEDToolBox.Core.Models.Coordinates(centre.X+camera.Right.X*half,centre.Y+camera.Right.Y*half,centre.Z+camera.Right.Z*half);
            var expected=camera.Project(corner).X-camera.Project(centre).X;
            var actual=StellarAppearance.OriginalProjectedHalfExtent(size,camera.Project(centre).Scale);
            Check.That(Math.Abs(actual-expected)<.0001);
        }
        Check.That(StellarAppearance.OriginalProjectedHalfExtent(.05f,.001)<.0001f);
        Check.Equal(0f,StellarAppearance.OriginalProjectedHalfExtent(float.NaN,4));
        Check.Equal(0f,StellarAppearance.OriginalProjectedHalfExtent(.7f,double.PositiveInfinity));
    }
    [Test] public void NebulaTransmissionStopsAtThePerspectiveCameraInsideTheCloud()
    {
        var volume=new NebulaVolume(4,Enumerable.Range(0,4*4*4*4).Select(i=>i%4==3?(byte)255:(byte)0).ToArray(),Enumerable.Repeat(new Vector4(0,0,0,1),256).ToArray());
        var atStar=volume.Transmission(Vector3.Zero,Vector3.UnitZ,0);
        var closeCamera=volume.Transmission(Vector3.Zero,Vector3.UnitZ,.25f);
        var outsideCamera=volume.Transmission(Vector3.Zero,Vector3.UnitZ,3);
        Check.Equal(1f,atStar);Check.That(atStar>closeCamera&&closeCamera>outsideCamera);
        Check.That(Math.Abs(closeCamera-MathF.Exp(-.25f*1.8f))<.0001f);
        Check.Equal(volume.Transmission(Vector3.Zero,Vector3.UnitZ),outsideCamera);
    }
    [Test] public void InfiniteGridReachesEveryViewportEdgeUnderRotationPanAndZoom()
    {
        Span<MapSegment> lines=stackalloc MapSegment[InfiniteGalaxyGrid.MaximumLines];
        foreach(var (yaw,pitch,scale,panX,panY) in new[]{(.3,.45,4d,0d,0d),(2.8,-.7,.001,183247d,-95378d),(-2d,1.45,1000d,-93714d,924815d),(.8,.02,4d,9000d,-3000d)})
        {
            var count=InfiniteGalaxyGrid.Write(lines,3840,2088,yaw,pitch,scale,panX,panY,out var step);
            Check.That(count is >0 and <=InfiniteGalaxyGrid.MaximumLines);Check.That(step>0);
            var left=false;var right=false;var top=false;var bottom=false;
            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>=-.001&&x<=3840.001&&y>=-.001&&y<=2088.001);
                    left|=Math.Abs(x)<.001;right|=Math.Abs(x-3840)<.001;top|=Math.Abs(y)<.001;bottom|=Math.Abs(y-2088)<.001;
                }
            }
            Check.That(left&&right&&top&&bottom,"Projected infinite grid must cross all viewport edges.");
        }
    }
    [Test] public void EdgeOnGridIsHiddenAndInvalidCameraDoesNotEmitGeometry()
    {
        Span<MapSegment> lines=stackalloc MapSegment[InfiniteGalaxyGrid.MaximumLines];
        Check.Equal(0,InfiniteGalaxyGrid.Write(lines,1000,800,.3,0,4,0,0,out _));
        Check.Equal(0,InfiniteGalaxyGrid.Write(lines,1000,800,.3,.4,0,0,0,out _));
        Check.Equal(0,InfiniteGalaxyGrid.Write(lines,1000,800,.3,.4,4,double.NaN,0,out _));
    }
}