public void PackWithNoBufferMosiacTests(RectInt[] rects, int padding, Vector2Int expectedSize) { RectInt[] packedRect; int packedWidth, packedHeight; ImagePacker.Pack(rects, padding, out packedRect, out packedWidth, out packedHeight); Assert.AreEqual(expectedSize.x, packedWidth); Assert.AreEqual(expectedSize.y, packedHeight); Assert.AreEqual(rects.Length, packedRect.Length); // Ensure all rects exists for (int i = 0; i < packedRect.Length; ++i) { // Ensure rect doesn't overlap with other rects RectInt testRect = packedRect[i]; for (int k = i + 1; k < packedRect.Length; ++k) { RectInt other = packedRect[k]; var contains = !((other.xMax + padding <= testRect.xMin || other.yMax + padding <= testRect.yMin) || (other.xMin >= testRect.xMax + padding || other.yMin >= testRect.yMax + padding)); Assert.IsFalse(contains); } // Ensure rects has the correct padding Assert.AreEqual(rects[i].width, testRect.width); Assert.AreEqual(rects[i].height, testRect.height); } }
public void PackWithBufferMosiacTests(RectInt[] rects, int padding, Vector2Int expectedSize) { RectInt[] packedRect; int packedWidth, packedHeight; // Find the largest buffer int maxWidth = -1, maxHeight = -1; for (int i = 0; i < rects.Length; ++i) { if (rects[i].width > maxWidth) { maxWidth = rects[i].width; } if (rects[i].height > maxHeight) { maxHeight = rects[i].height; } } // Setup color buffers NativeArray <Color32>[] buffers = new NativeArray <Color32> [rects.Length]; for (int i = 0; i < rects.Length; ++i) { buffers[i] = new NativeArray <Color32>(maxWidth * maxHeight, Allocator.Temp); for (int j = 0; j < maxHeight; ++j) { for (int k = 0; k < maxWidth; ++k) { int bufferIndex = (j * maxWidth + k); if (k >= rects[i].width || j >= rects[i].height) { buffers[i][bufferIndex] = new Color32(0, 0, 0, 0); } else { buffers[i][bufferIndex] = new Color32((byte)i, (byte)i, (byte)i, 255); } } } } NativeArray <Color32> packedBuffer; Vector2Int[] uvTransform; ImagePacker.Pack(buffers, maxWidth, maxHeight, padding, out packedBuffer, out packedWidth, out packedHeight, out packedRect, out uvTransform); Assert.AreEqual(expectedSize.x, packedWidth); Assert.AreEqual(expectedSize.y, packedHeight); Assert.AreEqual(rects.Length, packedRect.Length); // Ensure all rects exists int bytesPerRow = packedWidth; for (int i = 0; i < packedRect.Length; ++i) { // Ensure rect doesn't overlap with other rects RectInt testRect = packedRect[i]; for (int k = i + 1; k < packedRect.Length; ++k) { RectInt other = packedRect[k]; var contains = !((other.xMax + padding <= testRect.xMin || other.yMax + padding <= testRect.yMin) || (other.xMin >= testRect.xMax + padding || other.yMin >= testRect.yMax + padding)); Assert.IsFalse(contains); } // Ensure rects has the correct padding Assert.AreEqual(rects[i].width, testRect.width); Assert.AreEqual(rects[i].height, testRect.height); // Ensure buffers are blitted to the correct place. We will just sample min, max and center point if (testRect.width > 0 && testRect.height > 0) { Assert.IsTrue(PixelColorEqual(packedBuffer, packedWidth, bytesPerRow, testRect.xMin + padding, testRect.yMin, new Color32((byte)i, (byte)i, (byte)i, 255))); Assert.IsTrue(PixelColorEqual(packedBuffer, packedWidth, bytesPerRow, testRect.xMax - 1, testRect.yMax - 1, new Color32((byte)i, (byte)i, (byte)i, 255))); Assert.IsTrue(PixelColorEqual(packedBuffer, packedWidth, bytesPerRow, (int)testRect.center.x - 1, (int)testRect.center.y - 1, new Color32((byte)i, (byte)i, (byte)i, 255))); } } packedBuffer.Dispose(); for (int i = 0; i < buffers.Length; ++i) { buffers[i].Dispose(); } }
public void PostCheck() { CheckUsage(); ImagePacker.Pack(PublishTarget.Current); }
void ImportFromLayers(AssetImportContext ctx, Document doc) { NativeArray <Color32> output = default(NativeArray <Color32>); List <int> layerIndex = new List <int>(); List <int> spriteNameHash = new List <int>(); var oldPsdLayers = GetPSDLayers(); try { var psdLayers = new List <PSDLayer>(); ExtractLayerTask.Execute(psdLayers, doc.Layers, m_ImportHiddenLayers); var removedLayersSprite = oldPsdLayers.Where(x => psdLayers.FirstOrDefault(y => y.layerID == x.layerID) == null).Select(z => z.spriteID).ToArray(); for (int i = 0; i < psdLayers.Count; ++i) { int j = 0; var psdLayer = psdLayers[i]; for (; j < oldPsdLayers.Count; ++j) { if (psdLayer.layerID == oldPsdLayers[j].layerID) { psdLayer.spriteID = oldPsdLayers[j].spriteID; psdLayer.spriteName = oldPsdLayers[j].spriteName; psdLayer.mosaicPosition = oldPsdLayers[j].mosaicPosition; break; } } } int expectedBufferLength = doc.width * doc.height; var layerBuffers = new List <NativeArray <Color32> >(); for (int i = 0; i < psdLayers.Count; ++i) { var l = psdLayers[i]; if (l.texture.IsCreated && l.texture.Length == expectedBufferLength) { layerBuffers.Add(l.texture); layerIndex.Add(i); } } RectInt[] spritedata; int width, height; int padding = 4; Vector2Int[] uvTransform; ImagePacker.Pack(layerBuffers.ToArray(), doc.width, doc.height, padding, out output, out width, out height, out spritedata, out uvTransform); var spriteImportData = GetSpriteImportData(); if (spriteImportData.Count <= 0 || shouldResliceFromLayer) { var newSpriteMeta = new List <SpriteMetaData>(); for (int i = 0; i < spritedata.Length && i < layerIndex.Count; ++i) { var spriteSheet = spriteImportData.FirstOrDefault(x => x.spriteID == psdLayers[layerIndex[i]].spriteID); if (spriteSheet == null) { spriteSheet = new SpriteMetaData(); spriteSheet.border = Vector4.zero; spriteSheet.alignment = (SpriteAlignment)m_TextureImporterSettings.spriteAlignment; spriteSheet.pivot = m_TextureImporterSettings.spritePivot; } psdLayers[layerIndex[i]].spriteName = GetUniqueName(psdLayers[layerIndex[i]].name, spriteNameHash); spriteSheet.name = psdLayers[layerIndex[i]].spriteName; spriteSheet.rect = new Rect(spritedata[i].x, spritedata[i].y, spritedata[i].width, spritedata[i].height); spriteSheet.uvTransform = uvTransform[i]; psdLayers[layerIndex[i]].spriteID = spriteSheet.spriteID; psdLayers[layerIndex[i]].mosaicPosition = spritedata[i].position; newSpriteMeta.Add(spriteSheet); } spriteImportData.Clear(); spriteImportData.AddRange(newSpriteMeta); } else { spriteImportData.RemoveAll(x => removedLayersSprite.Contains(x.spriteID)); foreach (var spriteData in spriteImportData) { var psdLayer = psdLayers.FirstOrDefault(x => x.spriteID == spriteData.spriteID); if (psdLayer == null) { spriteData.uvTransform = new Vector2Int((int)spriteData.rect.position.x, (int)spriteData.rect.position.y); } // If it is user created rect or the name has been changed before // add it into the spriteNameHash and we don't copy it over from the layer if (psdLayer == null || psdLayer.spriteName != spriteData.name) { spriteNameHash.Add(spriteData.name.GetHashCode()); } // If the sprite name has not been changed, we ensure the new // layer name is still unique and use it as the sprite name if (psdLayer != null && psdLayer.spriteName == spriteData.name) { psdLayer.spriteName = GetUniqueName(psdLayer.name, spriteNameHash); spriteData.name = psdLayer.spriteName; } } //Update names for those user has not changed and add new sprite rect based on PSD file. for (int k = 0; k < layerIndex.Count; ++k) { int i = layerIndex[k]; var spriteSheet = spriteImportData.FirstOrDefault(x => x.spriteID == psdLayers[i].spriteID); var inOldLayer = oldPsdLayers.FindIndex(x => x.layerID == psdLayers[i].layerID) != -1; if (spriteSheet == null && !inOldLayer) { spriteSheet = new SpriteMetaData(); spriteImportData.Add(spriteSheet); spriteSheet.rect = new Rect(spritedata[k].x, spritedata[k].y, spritedata[k].width, spritedata[k].height); spriteSheet.border = Vector4.zero; spriteSheet.alignment = (SpriteAlignment)m_TextureImporterSettings.spriteAlignment; spriteSheet.pivot = m_TextureImporterSettings.spritePivot; psdLayers[i].spriteName = GetUniqueName(psdLayers[i].name, spriteNameHash); spriteSheet.name = psdLayers[i].spriteName; } else if (spriteSheet != null) { var r = spriteSheet.rect; r.position = spriteSheet.rect.position - psdLayers[i].mosaicPosition + spritedata[k].position; spriteSheet.rect = r; } if (spriteSheet != null) { spriteSheet.uvTransform = uvTransform[k]; psdLayers[i].spriteID = spriteSheet.spriteID; psdLayers[i].mosaicPosition = spritedata[k].position; } } } oldPsdLayers.Clear(); oldPsdLayers.AddRange(psdLayers); m_ResliceFromLayer = false; m_ImportedTextureHeight = textureActualHeight = height; m_ImportedTextureWidth = textureActualWidth = width; var generatedTexture = ImportTexture(ctx, output, width, height, 0, spriteImportData.Count); m_ImportedTextureHeight = generatedTexture.texture.height; m_ImportedTextureWidth = generatedTexture.texture.width; RegisterAssets(ctx, generatedTexture); } finally { if (output.IsCreated) { output.Dispose(); } foreach (var l in oldPsdLayers) { l.Dispose(); } } }