diff --git a/MLEM/Textures/DataTextureAtlas.cs b/MLEM/Textures/DataTextureAtlas.cs new file mode 100644 index 0000000..1c746da --- /dev/null +++ b/MLEM/Textures/DataTextureAtlas.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Text.RegularExpressions; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; + +namespace MLEM.Textures { + /// + /// This class represents an atlas of objects which are loaded from a special texture atlas file. + /// To load a data texture atlas, you can use . + /// + public class DataTextureAtlas { + + /// + /// The texture to use for this atlas + /// + public readonly Texture2D Texture; + /// + /// Returns the texture region with the given name. + /// + /// The region's name + public TextureRegion this[string name] => this.regions[name]; + /// + /// Returns an enumerable of all of the s in this atlas. + /// + public IEnumerable Regions => this.regions.Values; + + private readonly Dictionary regions = new Dictionary(); + + /// + /// Creates a new data texture atlas with the given texture and region amount. + /// + /// The texture to use for this atlas + public DataTextureAtlas(Texture2D texture) { + this.Texture = texture; + } + + internal static DataTextureAtlas Load(ContentManager content, string texturePath, string infoPath, bool pivotRelative) { + var info = new FileInfo(Path.Combine(content.RootDirectory, infoPath ?? $"{texturePath}.atlas")); + string text; + using (var reader = info.OpenText()) + text = reader.ReadToEnd(); + + var texture = content.Load(texturePath); + var atlas = new DataTextureAtlas(texture); + + // parse each texture region: " loc piv " + const string regex = @"(.+)\W+loc\W+([0-9]+)\W+([0-9]+)\W+([0-9]+)\W+([0-9]+)\W+(?:piv\W+([0-9.]+)\W+([0-9.]+))?"; + foreach (Match match in Regex.Matches(text, regex)) { + var name = match.Groups[1].Value.Trim(); + var loc = new Rectangle( + int.Parse(match.Groups[2].Value), int.Parse(match.Groups[3].Value), + int.Parse(match.Groups[4].Value), int.Parse(match.Groups[5].Value)); + var piv = Vector2.Zero; + if (match.Groups[6].Success) { + piv = new Vector2( + float.Parse(match.Groups[6].Value, CultureInfo.InvariantCulture) - (pivotRelative ? 0 : loc.X), + float.Parse(match.Groups[7].Value, CultureInfo.InvariantCulture) - (pivotRelative ? 0 : loc.Y)); + } + atlas.regions.Add(name, new TextureRegion(texture, loc) { + PivotPixels = piv, + Name = name + }); + } + + return atlas; + } + + } + + /// + /// A set of extension methods for dealing with . + /// + public static class DataTextureAtlasExtensions { + + /// + /// Loads a from the given texture and texture data file. + /// + /// The content manager to use for loading + /// The path to the texture file + /// The path, including extension, to the atlas info file, or null if ".atlas" should be used + /// If this value is true, then the pivot points passed in the info file will be relative to the coordinates of the texture region, not relative to the entire texture's origin. + /// A new data texture atlas with the given settings + public static DataTextureAtlas LoadTextureAtlas(this ContentManager content, string texturePath, string infoPath = null, bool pivotRelative = false) { + return DataTextureAtlas.Load(content, texturePath, infoPath, pivotRelative); + } + + } +} \ No newline at end of file diff --git a/Sandbox/Content/Content.mgcb b/Sandbox/Content/Content.mgcb index b3ff1d0..e4b5d48 100644 --- a/Sandbox/Content/Content.mgcb +++ b/Sandbox/Content/Content.mgcb @@ -41,6 +41,21 @@ #begin Test.json /copy:Test.json +#begin Textures/Furniture.atlas +/copy:Textures/Furniture.atlas + +#begin Textures/Furniture.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/Furniture.png + #begin Tiled/Map.tmx /importer:TiledMapImporter /processor:TiledMapProcessor diff --git a/Sandbox/Content/Textures/Furniture.atlas b/Sandbox/Content/Textures/Furniture.atlas new file mode 100644 index 0000000..9bc74c8 --- /dev/null +++ b/Sandbox/Content/Textures/Furniture.atlas @@ -0,0 +1,16 @@ +SimpleDeskUp +loc 0 0 48 32 +piv 16 16 +SimpleDeskRight +loc 48 0 48 32 +piv 80 16 + +Plant +loc 96 0 16 32 + +LongTableUp +loc 0 32 64 48 +piv 16 48 +LongTableRight +loc 64 32 64 48 +piv 112 48 \ No newline at end of file diff --git a/Sandbox/Content/Textures/Furniture.png b/Sandbox/Content/Textures/Furniture.png new file mode 100644 index 0000000..2aae963 Binary files /dev/null and b/Sandbox/Content/Textures/Furniture.png differ diff --git a/Sandbox/GameImpl.cs b/Sandbox/GameImpl.cs index c811dc1..bb9e9a1 100644 --- a/Sandbox/GameImpl.cs +++ b/Sandbox/GameImpl.cs @@ -143,6 +143,11 @@ namespace Sandbox { var region = new TextureRegion(round) {Pivot = new Vector2(0.5F)}; var region2 = new TextureRegion(round); + var atlas = this.Content.LoadTextureAtlas("Textures/Furniture"); + foreach (var r in atlas.Regions) { + Console.WriteLine(r.Name + ": " + r.U + " " + r.V + " " + r.Width + " " + r.Height + " " + r.PivotPixels); + } + this.OnDraw += (g, time) => { this.SpriteBatch.Begin(samplerState: SamplerState.PointClamp); //this.SpriteBatch.Draw(square, new Rectangle(10, 10, 400, 400), Color.White); diff --git a/Sandbox/Sandbox.csproj b/Sandbox/Sandbox.csproj index 45565c1..5ef7fce 100644 --- a/Sandbox/Sandbox.csproj +++ b/Sandbox/Sandbox.csproj @@ -25,6 +25,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest +