diff --git a/MLEM.Data/RuntimeTexturePacker.cs b/MLEM.Data/RuntimeTexturePacker.cs index 2b848f6..ee11290 100644 --- a/MLEM.Data/RuntimeTexturePacker.cs +++ b/MLEM.Data/RuntimeTexturePacker.cs @@ -68,17 +68,30 @@ namespace MLEM.Data { /// The result callback which will receive the resulting texture regions. /// The padding that the texture should have around itself. This can be useful if texture bleeding issues occur due to texture coordinate rounding. /// Whether the texture's padding should be filled with a copy of the texture's border, rather than transparent pixels. This value only has an effect if is greater than 0. + /// Whether completely transparent texture regions in the should be ignored. If this is true, they will not be part of the collection either. /// Thrown when trying to add data to a packer that has already been packed, or when trying to add a texture width a width greater than the defined max width. - public void Add(UniformTextureAtlas atlas, Action> result, int padding = 0, bool padWithPixels = false) { + public void Add(UniformTextureAtlas atlas, Action> result, int padding = 0, bool padWithPixels = false, bool ignoreTransparent = false) { + TextureData data = null; + var addedRegions = new List(); var resultRegions = new Dictionary(); for (var x = 0; x < atlas.RegionAmountX; x++) { for (var y = 0; y < atlas.RegionAmountY; y++) { var pos = new Point(x, y); - this.Add(atlas[pos], r => { + var region = atlas[pos]; + + if (ignoreTransparent) { + if (data == null) + data = atlas.Texture.GetTextureData(); + if (IsTransparent(region, data)) + continue; + } + + this.Add(region, r => { resultRegions.Add(pos, r); - if (resultRegions.Count >= atlas.RegionAmountX * atlas.RegionAmountY) + if (resultRegions.Count >= addedRegions.Count) result.Invoke(resultRegions); }, padding, padWithPixels); + addedRegions.Add(region); } } } @@ -273,6 +286,16 @@ namespace MLEM.Data { return ret; } + private static bool IsTransparent(TextureRegion region, TextureData data) { + for (var rX = 0; rX < region.Width; rX++) { + for (var rY = 0; rY < region.Height; rY++) { + if (data[region.U + rX, region.V + rY] != Color.Transparent) + return false; + } + } + return true; + } + private class Request { public readonly TextureRegion Texture; diff --git a/Sandbox/GameImpl.cs b/Sandbox/GameImpl.cs index 01af04a..bc14fb6 100644 --- a/Sandbox/GameImpl.cs +++ b/Sandbox/GameImpl.cs @@ -323,7 +323,7 @@ namespace Sandbox { packer.Add(new UniformTextureAtlas(tex, 16, 16), r => { regions.AddRange(r.Values); Console.WriteLine($"Returned {r.Count} regions: {string.Join(", ", r.Select(kv => kv.Key + ": " + kv.Value.Area))}"); - }, 1, true); + }, 1, true, true); packer.Add(this.Content.LoadTextureAtlas("Textures/Furniture"), r => { regions.AddRange(r.Values); Console.WriteLine($"Returned {r.Count} regions: {string.Join(", ", r.Select(kv => kv.Key + ": " + kv.Value.Area))}"); @@ -342,7 +342,7 @@ namespace Sandbox { x += r.Width * sc + 1; if (x >= 1000) { x = 0; - y += 50; + y += 250; } } this.SpriteBatch.End();