diff --git a/spine-unity/Assets/spine-unity/Modules/AttachmentTools/AttachmentTools.cs b/spine-unity/Assets/spine-unity/Modules/AttachmentTools/AttachmentTools.cs
index ab5d73d0b..cc92143e1 100644
--- a/spine-unity/Assets/spine-unity/Modules/AttachmentTools/AttachmentTools.cs
+++ b/spine-unity/Assets/spine-unity/Modules/AttachmentTools/AttachmentTools.cs
@@ -129,7 +129,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
///
/// Creates a Spine.AtlasRegion that uses a premultiplied alpha duplicate texture of the Sprite's texture data. Returns a RegionAttachment that uses it. Use this if you plan to use a premultiply alpha shader such as "Spine/Skeleton"
- public static RegionAttachment ToRegionAttachmentPMAClone (this Sprite sprite, Shader shader, TextureFormat textureFormat = SpriteAtlasRegionExtensions.SpineTextureFormat, bool mipmaps = SpriteAtlasRegionExtensions.UseMipMaps, Material materialPropertySource = null) {
+ public static RegionAttachment ToRegionAttachmentPMAClone (this Sprite sprite, Shader shader, TextureFormat textureFormat = AtlasUtilities.SpineTextureFormat, bool mipmaps = AtlasUtilities.UseMipMaps, Material materialPropertySource = null) {
if (sprite == null) throw new System.ArgumentNullException("sprite");
if (shader == null) throw new System.ArgumentNullException("shader");
var region = sprite.ToAtlasRegionPMAClone(shader, textureFormat, mipmaps, materialPropertySource);
@@ -137,7 +137,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
return region.ToRegionAttachment(sprite.name, unitsPerPixel);
}
- public static RegionAttachment ToRegionAttachmentPMAClone (this Sprite sprite, Material materialPropertySource, TextureFormat textureFormat = SpriteAtlasRegionExtensions.SpineTextureFormat, bool mipmaps = SpriteAtlasRegionExtensions.UseMipMaps) {
+ public static RegionAttachment ToRegionAttachmentPMAClone (this Sprite sprite, Material materialPropertySource, TextureFormat textureFormat = AtlasUtilities.SpineTextureFormat, bool mipmaps = AtlasUtilities.UseMipMaps) {
return sprite.ToRegionAttachmentPMAClone(materialPropertySource.shader, textureFormat, mipmaps, materialPropertySource);
}
@@ -210,7 +210,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
#endregion
}
- public static class SpriteAtlasRegionExtensions {
+ public static class AtlasUtilities {
internal const TextureFormat SpineTextureFormat = TextureFormat.RGBA32;
internal const float DefaultMipmapBias = -0.5f;
internal const bool UseMipMaps = false;
@@ -395,16 +395,98 @@ namespace Spine.Unity.Modules.AttachmentTools {
#region Runtime Repacking
///
- /// Creates and populates a duplicate skin with cloned attachments that are backed by a new packed texture atlas comprised of all the regions from the original skin.
- /// No Spine.Atlas object is created so there is no way to find AtlasRegions except through the Attachments using them.
- public static Skin GetRepackedSkin (this Skin o, string newName, Material materialPropertySource, out Material m, out Texture2D t, int maxAtlasSize = 1024, int padding = 2, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps) {
- return GetRepackedSkin(o, newName, materialPropertySource.shader, out m, out t, maxAtlasSize, padding, textureFormat, mipmaps, materialPropertySource);
+ /// Fills the outputAttachments list with new attachment objects based on the attachments in sourceAttachments, but mapped to a new single texture using the same material.
+ /// The list of attachments to be repacked.
+ /// The List(Attachment) to populate with the newly created Attachment objects.
+ ///
+ /// May be null. If no Material property source is provided, no special
+ public static void GetRepackedAttachments (List sourceAttachments, List outputAttachments, Material materialPropertySource, out Material outputMaterial, out Texture2D outputTexture, int maxAtlasSize = 1024, int padding = 2, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps, string newAssetName = "Repacked Attachments") {
+ if (sourceAttachments == null) throw new System.ArgumentNullException("sourceAttachments");
+ if (outputAttachments == null) throw new System.ArgumentNullException("outputAttachments");
+
+ // Use these to detect and use shared regions.
+ var existingRegions = new Dictionary();
+ var regionIndexes = new List();
+ var texturesToPack = new List();
+ var originalRegions = new List();
+
+ outputAttachments.Clear();
+ outputAttachments.AddRange(sourceAttachments);
+
+ int newRegionIndex = 0;
+ for (int i = 0, n = sourceAttachments.Count; i < n; i++) {
+ var originalAttachment = sourceAttachments[i];
+ var newAttachment = originalAttachment.GetClone(true);
+ if (IsRenderable(newAttachment)) {
+
+ var region = newAttachment.GetAtlasRegion();
+ int existingIndex;
+ if (existingRegions.TryGetValue(region, out existingIndex)) {
+ regionIndexes.Add(existingIndex); // Store the region index for the eventual new attachment.
+ } else {
+ originalRegions.Add(region);
+ texturesToPack.Add(region.ToTexture()); // Add the texture to the PackTextures argument
+ existingRegions.Add(region, newRegionIndex); // Add the region to the dictionary of known regions
+ regionIndexes.Add(newRegionIndex); // Store the region index for the eventual new attachment.
+ newRegionIndex++;
+ }
+
+ outputAttachments[i] = newAttachment;
+ }
+ }
+
+ // Fill a new texture with the collected attachment textures.
+ var newTexture = new Texture2D(maxAtlasSize, maxAtlasSize, textureFormat, mipmaps);
+ newTexture.mipMapBias = AtlasUtilities.DefaultMipmapBias;
+ newTexture.anisoLevel = texturesToPack[0].anisoLevel;
+ newTexture.name = newAssetName;
+ var rects = newTexture.PackTextures(texturesToPack.ToArray(), padding, maxAtlasSize);
+
+ // Rehydrate the repacked textures as a Material, Spine atlas and Spine.AtlasAttachments
+ Shader shader = materialPropertySource == null ? Shader.Find("Spine/Skeleton") : materialPropertySource.shader;
+ var newMaterial = new Material(shader);
+ if (materialPropertySource != null) {
+ newMaterial.CopyPropertiesFromMaterial(materialPropertySource);
+ newMaterial.shaderKeywords = materialPropertySource.shaderKeywords;
+ }
+
+ newMaterial.name = newAssetName;
+ newMaterial.mainTexture = newTexture;
+ var page = newMaterial.ToSpineAtlasPage();
+ page.name = newAssetName;
+
+ var repackedRegions = new List();
+ for (int i = 0, n = originalRegions.Count; i < n; i++) {
+ var oldRegion = originalRegions[i];
+ var newRegion = UVRectToAtlasRegion(rects[i], oldRegion.name, page, oldRegion.offsetX, oldRegion.offsetY, oldRegion.rotate);
+ repackedRegions.Add(newRegion);
+ }
+
+ // Map the cloned attachments to the repacked atlas.
+ for (int i = 0, n = outputAttachments.Count; i < n; i++) {
+ var a = outputAttachments[i];
+ a.SetRegion(repackedRegions[regionIndexes[i]]);
+ }
+
+ // Clean up.
+ foreach (var ttp in texturesToPack)
+ UnityEngine.Object.Destroy(ttp);
+
+ outputTexture = newTexture;
+ outputMaterial = newMaterial;
}
///
/// Creates and populates a duplicate skin with cloned attachments that are backed by a new packed texture atlas comprised of all the regions from the original skin.
/// No Spine.Atlas object is created so there is no way to find AtlasRegions except through the Attachments using them.
- public static Skin GetRepackedSkin (this Skin o, string newName, Shader shader, out Material m, out Texture2D t, int maxAtlasSize = 1024, int padding = 2, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps, Material materialPropertySource = null) {
+ public static Skin GetRepackedSkin (this Skin o, string newName, Material materialPropertySource, out Material outputMaterial, out Texture2D outputTexture, int maxAtlasSize = 1024, int padding = 2, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps) {
+ return GetRepackedSkin(o, newName, materialPropertySource.shader, out outputMaterial, out outputTexture, maxAtlasSize, padding, textureFormat, mipmaps, materialPropertySource);
+ }
+
+ ///
+ /// Creates and populates a duplicate skin with cloned attachments that are backed by a new packed texture atlas comprised of all the regions from the original skin.
+ /// No Spine.Atlas object is created so there is no way to find AtlasRegions except through the Attachments using them.
+ public static Skin GetRepackedSkin (this Skin o, string newName, Shader shader, out Material outputMaterial, out Texture2D outputTexture, int maxAtlasSize = 1024, int padding = 2, TextureFormat textureFormat = SpineTextureFormat, bool mipmaps = UseMipMaps, Material materialPropertySource = null) {
var skinAttachments = o.Attachments;
var newSkin = new Skin(newName);
@@ -441,7 +523,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
// Fill a new texture with the collected attachment textures.
var newTexture = new Texture2D(maxAtlasSize, maxAtlasSize, textureFormat, mipmaps);
- newTexture.mipMapBias = SpriteAtlasRegionExtensions.DefaultMipmapBias;
+ newTexture.mipMapBias = AtlasUtilities.DefaultMipmapBias;
newTexture.anisoLevel = texturesToPack[0].anisoLevel;
newTexture.name = newName;
var rects = newTexture.PackTextures(texturesToPack.ToArray(), padding, maxAtlasSize);
@@ -471,12 +553,12 @@ namespace Spine.Unity.Modules.AttachmentTools {
a.SetRegion(repackedRegions[regionIndexes[i]]);
}
-// // Clean up
-// foreach (var ttp in texturesToPack)
-// UnityEngine.Object.Destroy(ttp);
+ // Clean up.
+ foreach (var ttp in texturesToPack)
+ UnityEngine.Object.Destroy(ttp);
- t = newTexture;
- m = newMaterial;
+ outputTexture = newTexture;
+ outputMaterial = newMaterial;
return newSkin;
}
@@ -679,7 +761,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
}
}
- public static class SkinExtensions {
+ public static class SkinUtilities {
#region Skeleton Skin Extensions
///