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 sealed record GalaxyQueryBounds(Coordinates Minimum,Coordinates Maximum)
{
    public bool Contains(Coordinates p)=>p.X>=Minimum.X&&p.X<=Maximum.X&&p.Y>=Minimum.Y&&p.Y<=Maximum.Y&&p.Z>=Minimum.Z&&p.Z<=Maximum.Z;
    public static GalaxyQueryBounds FromViewport(GalaxyViewport viewport)
    {
        var points=new List<Coordinates>();
        if(viewport.Camera is {} camera)
        {
            foreach(var depth in new[]{camera.Near,camera.QueryFar})foreach(var sx in new[]{-1,1})foreach(var sy in new[]{-1,1})
            {
                var delta=camera.Forward*depth+camera.Right*(sx*depth*camera.Width/(2*camera.FocalLength))+camera.Up*(sy*depth*camera.Height/(2*camera.FocalLength));
                points.Add(new(camera.Eye.X+delta.X,camera.Eye.Y+delta.Y,camera.Eye.Z+delta.Z));
            }
        }
        else foreach(var sx in new[]{-1,1})foreach(var sy in new[]{-1,1})foreach(var sz in new[]{-1,1})
        {
            var d=viewport.Right*(sx*viewport.HalfWidth)+viewport.Up*(sy*viewport.HalfHeight)+viewport.Depth*(sz*viewport.HalfDepth);
            points.Add(new(viewport.Focus.X+d.X,viewport.Focus.Y+d.Y,viewport.Focus.Z+d.Z));
        }
        return new(new(points.Min(p=>p.X),points.Min(p=>p.Y),points.Min(p=>p.Z)),new(points.Max(p=>p.X),points.Max(p=>p.Y),points.Max(p=>p.Z)));
    }
    public GalaxyQueryBounds Child(int index)
    {
        var mid=new Coordinates((Minimum.X+Maximum.X)/2,(Minimum.Y+Maximum.Y)/2,(Minimum.Z+Maximum.Z)/2);
        return new(new((index&1)==0?Minimum.X:mid.X,(index&2)==0?Minimum.Y:mid.Y,(index&4)==0?Minimum.Z:mid.Z),new((index&1)==0?mid.X:Maximum.X,(index&2)==0?mid.Y:Maximum.Y,(index&4)==0?mid.Z:Maximum.Z));
    }
    public Coordinates Centre=>new((Minimum.X+Maximum.X)/2,(Minimum.Y+Maximum.Y)/2,(Minimum.Z+Maximum.Z)/2);
    public double Radius=>Minimum.DistanceTo(Maximum)/2;
}