using Kav.Data; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System.Collections.Generic; using System.IO; namespace Kav { public struct TextureAtlasSlice { public int X { get; } public int Y { get; } public int W { get; } public int H { get; } public UVData UVData { get; } // for use with tiling public Vector2 TiledUVOffset { get; } public TextureAtlasSlice(int x, int y, int w, int h, int totalW, int totalH) { X = x; Y = y; W = w; H = h; UVData = new UVData(new Vector2(x, y), new Vector2(w, h), new Vector2(totalW, totalH)); TiledUVOffset = new Vector2(x / (float)totalW, y / (float)totalH); } } public class TextureAtlas { public Texture2D Texture { get; } protected List Names { get; } = new List(); protected Dictionary Slices { get; } = new Dictionary(); public TextureAtlas(GraphicsDevice graphicsDevice, FileInfo atlasMetadataFile) { var atlasData = CrunchAtlasReader.ReadTextureAtlas(atlasMetadataFile); var textureData = atlasData.Textures[0]; using var stream = File.OpenRead(Path.Combine(atlasMetadataFile.DirectoryName, textureData.Name + ".png")); Texture = Texture2D.FromStream(graphicsDevice, stream); foreach (var slice in textureData.Images) { Names.Add(slice.N); Slices.Add( slice.N, new TextureAtlasSlice( slice.X, slice.Y, slice.W, slice.H, Texture.Width, Texture.Height ) ); } } public TextureAtlasSlice Lookup(string name) { return Slices[name]; } public string Name(int index) { return Names[index]; } public int Count() { return Names.Count; } } // Assumes all subimages are the same size public class TiledTextureAtlas : TextureAtlas { public int NumRows { get; } public int NumColumns { get; } public TiledTextureAtlas(GraphicsDevice graphicsDevice, FileInfo atlasMetadataFile) : base(graphicsDevice, atlasMetadataFile) { var subImageSlice = Slices[Names[0]]; NumRows = Texture.Height / subImageSlice.H; NumColumns = Texture.Width / subImageSlice.W; } } }