You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
5.1 KiB

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<Layer> layers, out List<NativeArray<Color32>> cellBuffers, out List<int> cellWidth, out List<int> cellHeight)
{
var cellsPerFrame = GetAllCellsPerFrame(in layers);
var mergedCells = MergeCells(in cellsPerFrame, assetName);
cellBuffers = new List<NativeArray<Color32>>();
cellWidth = new List<int>();
cellHeight = new List<int>();
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<int, List<Cell>> GetAllCellsPerFrame(in List<Layer> layers)
{
var cellsPerFrame = new Dictionary<int, List<Cell>>();
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>() { 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>() { cell });
}
}
return cellsPerFrame;
}
static List<Cell> MergeCells(in Dictionary<int, List<Cell>> cellsPerFrame, string assetName)
{
var mergedCells = new List<Cell>(cellsPerFrame.Count);
foreach (var (frameIndex, cells) in cellsPerFrame)
{
unsafe
{
var count = cells.Count;
var textures = new NativeArray<IntPtr>(count, Allocator.Persistent);
var cellRects = new NativeArray<RectInt>(count, Allocator.Persistent);
var cellBlendModes = new NativeArray<BlendModes>(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<Cell> cells, string assetName, ref List<Layer> layers)
{
layers.Clear();
var flattenLayer = new Layer()
{
cells = cells,
index = 0,
name = assetName
};
flattenLayer.guid = Layer.GenerateGuid(flattenLayer);
layers.Add(flattenLayer);
}
}
}