thief-mission-viewer/project/code/TMV/RectPacker.cs

61 lines
1.5 KiB
C#
Raw Normal View History

2024-08-28 20:39:30 +00:00
using System;
namespace KeepersCompound.TMV;
public static class RectPacker
{
public struct Rect
{
public int Id;
public ushort X;
public ushort Y;
public ushort Width;
public ushort Height;
}
public static Rect Pack(Rect[] rectangles, ushort width = 2048, ushort minHeight = 512)
2024-08-28 20:39:30 +00:00
{
ArgumentNullException.ThrowIfNull(rectangles);
ArgumentOutOfRangeException.ThrowIfZero(width);
2024-08-28 20:39:30 +00:00
ArgumentOutOfRangeException.ThrowIfZero(minHeight);
var bounds = new Rect
{
Width = width,
2024-08-28 20:39:30 +00:00
Height = minHeight
};
if (rectangles.Length == 0)
{
return bounds;
}
Array.Sort(rectangles, (a, b) => b.Height.CompareTo(a.Height));
2024-08-28 20:39:30 +00:00
// Naively try to pack into the row, wrapping when we reach the end
// and expanding the bounds when needed
ushort rowMaxH = rectangles[0].Height;
2024-08-28 20:39:30 +00:00
ushort x = 0;
ushort y = 0;
var rectCount = rectangles.Length;
for (var i = 0; i < rectCount; i++)
{
var rect = rectangles[i];
if (x + rect.Width > width)
2024-08-28 20:39:30 +00:00
{
x = 0;
2024-08-28 20:39:30 +00:00
y += rowMaxH;
rowMaxH = rect.Height;
2024-08-28 20:39:30 +00:00
}
rect.X = x;
rect.Y = y;
rectangles[i] = rect;
x += rect.Width;
}
bounds.Height = (ushort)(y + rowMaxH);
2024-08-28 20:39:30 +00:00
return bounds;
}
}