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));
                }
            }
        }
Example #2
0
        private static string SerializeTiles(IMapChunk chunk)
        {
            // number of bytes written per tile, because sizeof(Tile) is useless.
            const int structSize = 4;

            var nTiles = chunk.ChunkSize * chunk.ChunkSize * structSize;
            var barr   = new byte[nTiles];

            using (var stream = new MemoryStream(barr))
                using (var writer = new BinaryWriter(stream))
                {
                    for (ushort y = 0; y < chunk.ChunkSize; y++)
                    {
                        for (ushort x = 0; x < chunk.ChunkSize; x++)
                        {
                            var tile = chunk.GetTile(x, y);
                            writer.Write(tile.TypeId);
                            writer.Write(tile.Data);
                        }
                    }
                }

            return(Convert.ToBase64String(barr));
        }
        /// <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(IMapChunk 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);
            }
        }