Files
RobustToolbox/Robust.Shared/Map/GridChunkPartition.cs
Acruid 08a52fb892 MapChunk Cleanup (#2555)
* All IPhysShapes now expose a property to get the local AABB.

* Removed IMapChunk. It's internal, we only have 1 implementation in the engine, no need for abstraction, and removing it helps perf.

* Cleaned up issues in MapChunk file.

* Encapsulate _tiles access inside MapChunk.

* Remove IEnumerable<TileRef> from MapChunk.

* Remove CollidesWithChunk

* Move CalcWorldAABB and RegenerateCollision from MapChunk to MapGrid.
Remove MapChunk.GridId.

* Removed MapChunk.GetAllTiles

* Removed the terrible mocked unit tests.

* Moved the GetTileRef functions from MapChunk to MapGrid.

* Add an event raised on MapChunk when a tile is modified.
Completely remove the IMapGrid dependency from MapChunk.

* Fix bug where you cannot change the tile damage of a tile.
2022-02-21 20:49:30 -08:00

82 lines
2.6 KiB
C#

using System;
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
{
/// <summary>
///
/// </summary>
/// <param name="chunk"></param>
/// <param name="bounds">The overall bounds that covers every rectangle.</param>
/// <param name="rectangles">Each individual rectangle comprising the chunk's bounds</param>
public static void PartitionChunk(MapChunk chunk, out Box2i bounds, out List<Box2i> rectangles)
{
rectangles = new List<Box2i>();
// TODO: Use the existing PartitionChunk version because that one is likely faster and you can Span that shit.
// Convert each line into boxes as long as they can be.
for (ushort y = 0; y < chunk.ChunkSize; y++)
{
var origin = 0;
var running = false;
for (ushort x = 0; x < chunk.ChunkSize; x++)
{
if (!chunk.GetTile(x, y).IsEmpty)
{
running = true;
continue;
}
// Still empty
if (running)
{
rectangles.Add(new Box2i(origin, y, x, y + 1));
}
origin = x + 1;
running = false;
}
if (running)
rectangles.Add(new Box2i(origin, y, chunk.ChunkSize, y + 1));
}
// Patch them together as available
for (var i = rectangles.Count - 1; i >= 0; i--)
{
var box = rectangles[i];
for (var j = i - 1; j >= 0; j--)
{
var other = rectangles[j];
// Gone down as far as we can go.
if (other.Top < box.Bottom) break;
if (box.Left == other.Left && box.Right == other.Right)
{
box = new Box2i(box.Left, other.Bottom, box.Right, box.Top);
rectangles[i] = box;
rectangles.RemoveAt(j);
i -= 1;
continue;
}
}
}
bounds = new Box2i();
foreach (var rectangle in rectangles)
{
bounds = bounds.IsEmpty() ? rectangle : bounds.Union(rectangle);
}
}
}
}