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

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using XFEEDToolBox.Core.Models;

namespace XFEEDToolBox.Core.Galaxy;

public readonly record struct GalaxyOriginalGridLine(double FromX,double FromY,double FromZ,double ToX,double ToY,double ToZ,float WidthMultiplier);

/// <summary>Original3A1EDE0 world grid. The downstream line material is separate.</summary>
public static class GalaxyOriginalGrid
{
    public const int MaximumLines=198;
    public const float BaseWidth=.02f;
    public static readonly GalaxyRawColour Colour=new(.3f,.9f,.9f,.15f);
    public static double Step(double actualDistance)=>actualDistance>6000?1000:actualDistance>600?100:actualDistance>60?10:1;
    public static int Write(Span<GalaxyOriginalGridLine> output,Coordinates focus,double actualDistance)
    {
        if(output.Length<MaximumLines||!focus.IsValid||!double.IsFinite(actualDistance)||actualDistance<=0)return 0;
        var step=Step(actualDistance);
        // The SIMD source masks snapped X/Z and preserves actual focusY. It
        // adds .5 before floor, including negative half-way coordinates.
        var x=Math.Floor(focus.X/step+.5)*step;var z=Math.Floor(focus.Z/step+.5)*step;var count=0;
        for(var index=-49;index<50;index++)
        {
            var at=x+index*step;
            output[count++]=new(at,focus.Y,z-50*step,at,focus.Y,z+50*step,Width(at,actualDistance));
        }
        for(var index=-49;index<50;index++)
        {
            var at=z+index*step;
            output[count++]=new(x-50*step,focus.Y,at,x+50*step,focus.Y,at,Width(at,actualDistance));
        }
        return count;
    }
    private static float Width(double at,double distance)
    {
        var value=Math.Truncate(Math.Abs(at));var width=1d;
        for(var divisor=10d;divisor<=10000;divisor*=10)
        {
            if(Math.Truncate(value/divisor)*divisor!=value)break;
            width*=5;
        }
        return (float)Math.Min(width,distance/10);
    }
}