mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-09-15 14:52:35 +02:00
* Removed the Interfaces folder. * All objects inside the GameObjects subfolders are now in the GameObjects namespace. * Added a Resharper DotSettings file to mark the GameObjects subfolders as not providing namespaces. * Simplified Robust.client.Graphics namespace. * Automated remove redundant using statements.
131 lines
4.0 KiB
C#
131 lines
4.0 KiB
C#
using System.Collections.Generic;
|
|
using Robust.Shared.Maths;
|
|
|
|
namespace Robust.Shared.Map
|
|
{
|
|
/// <summary>
|
|
/// Partitions a grid chunk into a set of non-overlapping rectangles.
|
|
/// </summary>
|
|
internal static class GridChunkPartition
|
|
{
|
|
public static void PartitionChunk(IMapChunk chunk, ref IList<Box2> rectangles, out Box2i bounds)
|
|
{
|
|
rectangles.Clear();
|
|
|
|
var size = chunk.ChunkSize;
|
|
|
|
// copy 2d img
|
|
bool[,] image = new bool[size,size];
|
|
|
|
for(ushort x=0;x<size;x++)
|
|
for (ushort y = 0; y < size; y++)
|
|
image[x, y] = !chunk.GetTile(x, y).IsEmpty;
|
|
|
|
Partition(size, size, image, out var blocks, out var blockCount);
|
|
|
|
bounds = new Box2i();
|
|
|
|
// convert blocks to rectangles array.
|
|
for(int i=0;i< blockCount; i++)
|
|
{
|
|
var block = blocks[i];
|
|
|
|
// block are in indices and rotated 90 degrees :(
|
|
|
|
var left = block.y1;
|
|
var right = block.y2 + 1;
|
|
var bottom = block.x1;
|
|
var top = block.x2 + 1;
|
|
|
|
rectangles.Add(new Box2(left, bottom, right, top));
|
|
|
|
if(bounds.Size.Equals(Vector2i.Zero))
|
|
bounds = new Box2i(left, bottom, right, top);
|
|
else
|
|
bounds = bounds.Union(new Box2i(left, bottom, right, top));
|
|
}
|
|
}
|
|
|
|
private struct Block
|
|
{
|
|
public int x1;
|
|
public int x2;
|
|
public int y1;
|
|
public int y2;
|
|
}
|
|
|
|
private static void Partition(in int L, in int W, in bool[,] img, out Block[] block, out int blockno)
|
|
{
|
|
// Credit: http://utopia.duth.gr/spiliot/papers/j7.pdf
|
|
|
|
block = new Block[L*W];
|
|
|
|
int[] p = new int[W];
|
|
int[] c = new int[W];
|
|
|
|
int kp = 0;
|
|
blockno = 0;
|
|
|
|
for (int y = 0; y < L; y++)
|
|
{
|
|
int x1 = 0;
|
|
int x2 = 0;
|
|
int kc = 0;
|
|
bool intervalfound = false;
|
|
int j_last = 0;
|
|
int j_curr = 0;
|
|
for (int x = 0; x < W; x++)
|
|
{
|
|
bool try2match = false;
|
|
if (img[y,x] && !intervalfound)
|
|
{
|
|
intervalfound = true;
|
|
x1 = x;
|
|
}
|
|
if (!img[y,x] && intervalfound)
|
|
{
|
|
intervalfound = false;
|
|
x2 = x - 1;
|
|
try2match = true;
|
|
}
|
|
if (x == W - 1 && img[y,x] && intervalfound)
|
|
{
|
|
x2 = x;
|
|
try2match = true;
|
|
}
|
|
if (try2match)
|
|
{
|
|
bool intervalmatched = false;
|
|
for (int j = j_last; j < kp && x1 >= block[p[j]].x1; j++)
|
|
if (x1 == block[p[j]].x1 && x2 == block[p[j]].x2)
|
|
{
|
|
c[kc] = p[j];
|
|
block[p[j]].y2 = y;
|
|
intervalmatched = true;
|
|
j_curr = j;
|
|
}
|
|
|
|
j_last = j_curr;
|
|
if (!intervalmatched)
|
|
{
|
|
block[blockno].x1 = x1;
|
|
block[blockno].x2 = x2;
|
|
block[blockno].y1 = y;
|
|
block[blockno].y2 = y;
|
|
c[kc] = blockno++;
|
|
}
|
|
|
|
if (!intervalmatched)
|
|
kc++;
|
|
}
|
|
}
|
|
|
|
for (var i = 0; i < kc; i++)
|
|
p[i] = c[i];
|
|
|
|
kp = kc;
|
|
}
|
|
}
|
|
}
|
|
}
|