using System; using System.Collections.Generic; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using UnityEngine; using UnityEngine.Assertions; namespace UnityEditor.U2D.Aseprite { internal static class ImportMergedLayers { public static void Import(string assetName, ref List layers, out List> cellBuffers, out List cellWidth, out List cellHeight) { var cellsPerFrame = GetAllCellsPerFrame(in layers); var mergedCells = MergeCells(in cellsPerFrame, assetName); cellBuffers = new List>(); cellWidth = new List(); cellHeight = new List(); for (var i = 0; i < mergedCells.Count; ++i) { var width = mergedCells[i].cellRect.width; var height = mergedCells[i].cellRect.height; if (width == 0 || height == 0) continue; cellBuffers.Add(mergedCells[i].image); cellWidth.Add(width); cellHeight.Add(height); } UpdateLayerList(mergedCells, assetName, ref layers); } static Dictionary> GetAllCellsPerFrame(in List layers) { var cellsPerFrame = new Dictionary>(); for (var i = 0; i < layers.Count; ++i) { var cells = layers[i].cells; for (var m = 0; m < cells.Count; ++m) { var cell = cells[m]; var width = cell.cellRect.width; var height = cell.cellRect.height; if (width == 0 || height == 0) continue; if (cellsPerFrame.ContainsKey(cell.frameIndex)) cellsPerFrame[cell.frameIndex].Add(cell); else cellsPerFrame.Add(cell.frameIndex, new List() { cell }); } var linkedCells = layers[i].linkedCells; for (var m = 0; m < linkedCells.Count; ++m) { var frameIndex = linkedCells[m].frameIndex; var linkedToFrame = linkedCells[m].linkedToFrame; var cellIndex = cells.FindIndex(x => x.frameIndex == linkedToFrame); Assert.AreNotEqual(-1, cellIndex, $"Linked Cell: {frameIndex} is linked to cell: {linkedToFrame}, which cannot be found."); var cell = cells[cellIndex]; var width = cell.cellRect.width; var height = cell.cellRect.height; if (width == 0 || height == 0) continue; if (cellsPerFrame.ContainsKey(frameIndex)) cellsPerFrame[frameIndex].Add(cell); else cellsPerFrame.Add(frameIndex, new List() { cell }); } } return cellsPerFrame; } static List MergeCells(in Dictionary> cellsPerFrame, string assetName) { var mergedCells = new List(cellsPerFrame.Count); foreach (var (frameIndex, cells) in cellsPerFrame) { unsafe { var count = cells.Count; var textures = new NativeArray(count, Allocator.Persistent); var cellRects = new NativeArray(count, Allocator.Persistent); var cellBlendModes = new NativeArray(count, Allocator.Persistent); for (var i = 0; i < cells.Count; ++i) { textures[i] = (IntPtr)cells[i].image.GetUnsafePtr(); cellRects[i] = cells[i].cellRect; cellBlendModes[i] = cells[i].blendMode; } TextureTasks.MergeTextures(in textures, in cellRects, in cellBlendModes, out var output); var mergedCell = new Cell() { cellRect = output.rect, image = output.image, frameIndex = frameIndex, name = ImportUtilities.GetCellName(assetName, frameIndex, cellsPerFrame.Count), spriteId = GUID.Generate() }; mergedCells.Add(mergedCell); textures.Dispose(); cellRects.Dispose(); cellBlendModes.Dispose(); } } return mergedCells; } static void UpdateLayerList(in List cells, string assetName, ref List layers) { layers.Clear(); var flattenLayer = new Layer() { cells = cells, index = 0, name = assetName }; flattenLayer.guid = Layer.GenerateGuid(flattenLayer); layers.Add(flattenLayer); } } }