using XFEEDToolBox.Core.Rendering;
namespace XFEEDToolBox.Rendering;
// This derives coverage only from actual GZM ID transitions. It contains no
// procedural regions, catalogue positions, or synthetic point stars.
internal sealed record GalaxyZoneMip(int Width,int Height,byte[] Pixels);
internal sealed record GalaxyZoneRaster(GalaxyOriginalZoneMap Map,byte[] Ids,GalaxyZoneMip[] BoundaryMips)
{
internal static GalaxyZoneRaster Create(GalaxyOriginalZoneMap map)
{
var ids=map.Values.ToArray();var width=map.Width;var height=map.Height;
var boundary=new byte[ids.Length];
for(var y=0;y<height;y++)for(var x=0;x<width;x++)
{
var index=y*width+x;var id=ids[index];
if(x>0&&ids[index-1]!=id||x+1<width&&ids[index+1]!=id||
y>0&&ids[index-width]!=id||y+1<height&&ids[index+width]!=id)boundary[index]=255;
}
List<GalaxyZoneMip> levels=[new(width,height,boundary)];
while(width>1||height>1)
{
var nextWidth=Math.Max(1,width/2);var nextHeight=Math.Max(1,height/2);var next=new byte[nextWidth*nextHeight];
for(var y=0;y<nextHeight;y++)for(var x=0;x<nextWidth;x++)
{
var x0=x*2;var x1=Math.Min(width-1,x0+1);var y0=y*2;var y1=Math.Min(height-1,y0+1);
next[y*nextWidth+x]=(byte)((boundary[y0*width+x0]+boundary[y0*width+x1]+boundary[y1*width+x0]+boundary[y1*width+x1]+2)/4);
}
width=nextWidth;height=nextHeight;boundary=next;levels.Add(new(width,height,boundary));
}
return new(map,ids,levels.ToArray());
}
}
using XFEEDToolBox.Core.Rendering;
namespace XFEEDToolBox.Rendering;
// This derives coverage only from actual GZM ID transitions. It contains no
// procedural regions, catalogue positions, or synthetic point stars.
internal sealed record GalaxyZoneMip(int Width,int Height,byte[] Pixels);
internal sealed record GalaxyZoneRaster(GalaxyOriginalZoneMap Map,byte[] Ids,GalaxyZoneMip[] BoundaryMips)
{
internal static GalaxyZoneRaster Create(GalaxyOriginalZoneMap map)
{
var ids=map.Values.ToArray();var width=map.Width;var height=map.Height;
var boundary=new byte[ids.Length];
for(var y=0;y<height;y++)for(var x=0;x<width;x++)
{
var index=y*width+x;var id=ids[index];
if(x>0&&ids[index-1]!=id||x+1<width&&ids[index+1]!=id||
y>0&&ids[index-width]!=id||y+1<height&&ids[index+width]!=id)boundary[index]=255;
}
List<GalaxyZoneMip> levels=[new(width,height,boundary)];
while(width>1||height>1)
{
var nextWidth=Math.Max(1,width/2);var nextHeight=Math.Max(1,height/2);var next=new byte[nextWidth*nextHeight];
for(var y=0;y<nextHeight;y++)for(var x=0;x<nextWidth;x++)
{
var x0=x*2;var x1=Math.Min(width-1,x0+1);var y0=y*2;var y1=Math.Min(height-1,y0+1);
next[y*nextWidth+x]=(byte)((boundary[y0*width+x0]+boundary[y0*width+x1]+boundary[y1*width+x0]+boundary[y1*width+x1]+2)/4);
}
width=nextWidth;height=nextHeight;boundary=next;levels.Add(new(width,height,boundary));
}
return new(map,ids,levels.ToArray());
}
}