From 773237f53efeb85ddd4812e07fa2bbd6936d32d3 Mon Sep 17 00:00:00 2001 From: Waffle Date: Sat, 13 Dec 2025 05:44:44 +0900 Subject: [PATCH 1/3] Add layer split feature --- .../Processors/TextureAtlasProcessor.cs | 41 +++++++++++++++++-- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/source/AsepriteDotNet/Processors/TextureAtlasProcessor.cs b/source/AsepriteDotNet/Processors/TextureAtlasProcessor.cs index 3450c28..de1c7db 100644 --- a/source/AsepriteDotNet/Processors/TextureAtlasProcessor.cs +++ b/source/AsepriteDotNet/Processors/TextureAtlasProcessor.cs @@ -81,12 +81,14 @@ public static TextureAtlas Process(AsepriteFile file, /// The amount of transparent pixels to add to the edge of the generated texture. /// The amount of transparent pixels to add between each texture region in the generated texture. /// The amount of transparent pixels to add around the edge of each texture region in the generated texture. + /// Indicates whether each layer should be processed separately instead of being flattened together. /// /// The created by this method. If is empty or contains zero /// elements, then is returned. /// /// Thrown when is . - public static TextureAtlas Process(AsepriteFile file, ICollection layers, bool mergeDuplicateFrames = true, int borderPadding = 0, int spacing = 0, int innerPadding = 0) + public static TextureAtlas Process(AsepriteFile file, ICollection layers, bool mergeDuplicateFrames = true, int borderPadding = 0, int spacing = 0, int innerPadding = 0, bool splitLayers = false) + { ArgumentNullException.ThrowIfNull(file); @@ -99,11 +101,42 @@ public static TextureAtlas Process(AsepriteFile file, ICollection layers int frameHeight = file.CanvasHeight; int frameCount = file.Frames.Length; - Rgba32[][] flattenedFrames = new Rgba32[frameCount][]; + Rgba32[][] flattenedFrames; - for (int i = 0; i < frameCount; i++) + if (splitLayers) { - flattenedFrames[i] = file.Frames[i].FlattenFrame(layers); + flattenedFrames = new Rgba32[layers.Count * frameCount][]; + + HashSet layerNames = new HashSet(layers); + + for (int i = 0; i < frameCount; i++) + { + for (int celNum = 0; celNum < Math.Min(layers.Count, file.Frames[i].Cels.Length); celNum++) + { + AsepriteCel cel = file.Frames[i].Cels[celNum]; + + if (!layerNames.Contains(cel.Layer.Name)) continue; + + if (cel is AsepriteLinkedCel linkedCel) + { + cel = linkedCel.Cel; + } + + if (cel is AsepriteImageCel imageCel) + { + flattenedFrames[i * layers.Count + celNum] = imageCel.Pixels.ToArray(); + } + } + } + } + else + { + flattenedFrames = new Rgba32[frameCount][]; + + for (int i = 0; i < frameCount; i++) + { + flattenedFrames[i] = file.Frames[i].FlattenFrame(layers); + } } Dictionary duplicateMap = new Dictionary(); From 945d6083e96305bf8a870771c4c3fad088898cd5 Mon Sep 17 00:00:00 2001 From: Waffle Date: Sat, 4 Apr 2026 06:45:56 +0900 Subject: [PATCH 2/3] Add splitLayers parameter to TextureAtlasProcessor.Process method --- source/AsepriteDotNet/Processors/TextureAtlasProcessor.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/AsepriteDotNet/Processors/TextureAtlasProcessor.cs b/source/AsepriteDotNet/Processors/TextureAtlasProcessor.cs index de1c7db..e8e8a24 100644 --- a/source/AsepriteDotNet/Processors/TextureAtlasProcessor.cs +++ b/source/AsepriteDotNet/Processors/TextureAtlasProcessor.cs @@ -43,6 +43,7 @@ public static TextureAtlas Process(AsepriteFile file, ProcessorOptions? options /// The amount of transparent pixels to add to the edge of the generated texture. /// The amount of transparent pixels to add between each texture region in the generated texture. /// The amount of transparent pixels to add around the edge of each texture region in the generated texture. + /// Indicates whether each layer should be processed separately. /// The . /// Thrown when is . public static TextureAtlas Process(AsepriteFile file, @@ -52,7 +53,8 @@ public static TextureAtlas Process(AsepriteFile file, bool mergeDuplicateFrames = true, int borderPadding = 0, int spacing = 0, - int innerPadding = 0) + int innerPadding = 0, + bool splitLayers = false) { ArgumentNullException.ThrowIfNull(file); @@ -66,7 +68,7 @@ public static TextureAtlas Process(AsepriteFile file, layers.Add(layer.Name); } - return Process(file, layers, mergeDuplicateFrames, borderPadding, spacing, innerPadding); + return Process(file, layers, mergeDuplicateFrames, borderPadding, spacing, innerPadding, splitLayers); } /// From 140c5d6e0a3d4be98af8a2b1e3d28cd87a6a0f7c Mon Sep 17 00:00:00 2001 From: Waffle Date: Sat, 4 Apr 2026 06:46:39 +0900 Subject: [PATCH 3/3] Fix layer processing to maintain correct order when splitting layers --- .../Processors/TextureAtlasProcessor.cs | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/source/AsepriteDotNet/Processors/TextureAtlasProcessor.cs b/source/AsepriteDotNet/Processors/TextureAtlasProcessor.cs index e8e8a24..067b403 100644 --- a/source/AsepriteDotNet/Processors/TextureAtlasProcessor.cs +++ b/source/AsepriteDotNet/Processors/TextureAtlasProcessor.cs @@ -109,15 +109,25 @@ public static TextureAtlas Process(AsepriteFile file, ICollection layers { flattenedFrames = new Rgba32[layers.Count * frameCount][]; - HashSet layerNames = new HashSet(layers); + List layerList = new List(layers); for (int i = 0; i < frameCount; i++) { - for (int celNum = 0; celNum < Math.Min(layers.Count, file.Frames[i].Cels.Length); celNum++) + for (int layerIndex = 0; layerIndex < layerList.Count; layerIndex++) { - AsepriteCel cel = file.Frames[i].Cels[celNum]; + string layerName = layerList[layerIndex]; + AsepriteCel? cel = null; - if (!layerNames.Contains(cel.Layer.Name)) continue; + foreach (AsepriteCel frameCel in file.Frames[i].Cels) + { + if (frameCel.Layer.Name == layerName) + { + cel = frameCel; + break; + } + } + + if (cel is null) continue; if (cel is AsepriteLinkedCel linkedCel) { @@ -126,7 +136,7 @@ public static TextureAtlas Process(AsepriteFile file, ICollection layers if (cel is AsepriteImageCel imageCel) { - flattenedFrames[i * layers.Count + celNum] = imageCel.Pixels.ToArray(); + flattenedFrames[i * layers.Count + layerIndex] = imageCel.Pixels.ToArray(); } } } @@ -141,6 +151,8 @@ public static TextureAtlas Process(AsepriteFile file, ICollection layers } } + frameCount = flattenedFrames.Length; + Dictionary duplicateMap = new Dictionary(); Dictionary originalToDuplicateLookup = new Dictionary(); @@ -176,7 +188,7 @@ public static TextureAtlas Process(AsepriteFile file, ICollection layers + (innerPadding * 2 * rows); Rgba32[] imagePixels = new Rgba32[imageWidth * imageHeight]; - TextureRegion[] regions = new TextureRegion[file.Frames.Length]; + TextureRegion[] regions = new TextureRegion[flattenedFrames.Length]; int offset = 0;