#region License // Copyright 2021 Kastellanos Nikolaos // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #endregion using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content.Pipeline; using Microsoft.Xna.Framework.Content.Pipeline.Graphics; namespace nkast.Aether.Content.Pipeline { public class TilemapContent : Texture2DContent { public Texture2DContent TextureAtlas { get { return this; } } public Texture2DContent TextureMap; public readonly Dictionary Tiles = new Dictionary(); public TilesetContent Tileset; internal readonly List DestinationTiles = new List(); internal int MapColumns, MapRows; internal int TileWidth, TileHeight; internal int Width, Height; internal string Renderorder; internal int Firstgid; internal int LayerColumns, LayerRows; internal int[] MapData; internal static void PackTiles(TilemapContent output, int tileWidth, int tileHeight) { IList dstTiles = TilePacker.ArrangeGlyphs(output.Tileset.SourceTiles, tileWidth, tileHeight, true, true); foreach (TileContent dstTile in dstTiles) { output.DestinationTiles.Add(dstTile); string name = dstTile.SrcTexture.Name; if (output.Tiles.ContainsKey(name)) name = name + dstTile.Id; output.Tiles.Add(name, dstTile); } } internal static void RenderAtlas(TilemapContent output) { Rectangle s = new Rectangle(0,0,1,1); foreach (TileContent dstTile in output.DestinationTiles) { s = Rectangle.Union(s,dstTile.DstBounds); } var outputBmp = new PixelBitmapContent(s.Width, s.Height); foreach (TileContent dstTile in output.DestinationTiles) { Rectangle srcBounds = dstTile.SrcBounds; Rectangle dstBounds = new Rectangle(dstTile.DstBounds.X, dstTile.DstBounds.Y, srcBounds.Width, srcBounds.Height); int offsetX = 0; int offsetY = dstTile.DstBounds.Height - srcBounds.Height; dstBounds.X += offsetX; dstBounds.Y += offsetY; BitmapContent srcBmp = dstTile.SrcTexture.Faces[0][0]; BitmapContent.Copy(srcBmp, srcBounds, outputBmp, dstBounds); } MipmapChain mipmapChain = new MipmapChain(outputBmp); output.TextureAtlas.Mipmaps = mipmapChain; } internal static void RenderMap(TilemapContent output) { byte[] mp = new byte[output.MapData.Length * 4]; for (int i = 0; i < output.MapData.Length; i++) { int id = output.MapData[i] - output.Firstgid; TileContent tile = null; foreach (TileContent t in output.DestinationTiles) { if (t.Id == id) { tile = t; break; } } byte x = (byte)(tile.DstBounds.X / output.TileWidth); byte y = (byte)(tile.DstBounds.Y / output.TileHeight); mp[i * 4 + 0] = x; mp[i * 4 + 1] = y; mp[i * 4 + 2] = 0; mp[i * 4 + 3] = 255; } BitmapContent bm = new PixelBitmapContent(output.MapColumns, output.MapRows); bm.SetPixelData(mp); Texture2DContent mt = new Texture2DContent(); mt.Faces[0].Add(bm); output.TextureMap = mt; } } }