From 1d5189db8154a47fe1044b7e090ca118dbd08394 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Mon, 2 Dec 2019 16:23:06 +0100 Subject: [PATCH] [unity] Cleanup: merged common code of `GetRepackedAttachments` and `GetRepackedSkin`. See commit e3245ed. --- .../spine-unity/Utility/AtlasUtilities.cs | 126 +++++------------- 1 file changed, 30 insertions(+), 96 deletions(-) diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs index ee76c5921..807ba5c62 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AtlasUtilities.cs @@ -219,6 +219,19 @@ namespace Spine.Unity.AttachmentTools { } #region Runtime Repacking + /// + /// 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 equal to sourceAttachments for in-place operation. + /// May be null. If no Material property source is provided, a material with + /// default parameters using the provided shader will be created. + /// Optional additional textures (such as normal maps) to copy while repacking. + /// To copy e.g. the main texture and normal maps, pass 'new int[] { Shader.PropertyToID("_BumpMap") }' at this parameter. + /// When additionalTexturePropertyIDsToCopy is non-null, + /// this array will be filled with the resulting repacked texture for every property, + /// just as the main repacked texture is assigned to outputTexture. 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, @@ -236,9 +249,10 @@ namespace Spine.Unity.AttachmentTools { /// 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 + /// The List(Attachment) to populate with the newly created Attachment objects. + /// May be equal to sourceAttachments for in-place operation. + /// May be null. If no Material property source is provided, a material with + /// default parameters using the provided shader will be created. /// Optional additional textures (such as normal maps) to copy while repacking. /// To copy e.g. the main texture and normal maps, pass 'new int[] { Shader.PropertyToID("_BumpMap") }' at this parameter. /// When additionalTexturePropertyIDsToCopy is non-null, @@ -268,8 +282,10 @@ namespace Spine.Unity.AttachmentTools { } var originalRegions = new List(); + if (!object.ReferenceEquals(sourceAttachments, outputAttachments)) { outputAttachments.Clear(); outputAttachments.AddRange(sourceAttachments); + } int newRegionIndex = 0; for (int attachmentIndex = 0, n = sourceAttachments.Count; attachmentIndex < n; attachmentIndex++) { @@ -398,102 +414,20 @@ namespace Spine.Unity.AttachmentTools { newSkin.bones.AddRange(o.bones); newSkin.constraints.AddRange(o.constraints); - // Use these to detect and use shared regions. - var existingRegions = new Dictionary(); - var regionIndexes = new List(); - - // Collect all textures from the attachments of the original skin. - var repackedAttachments = new List(); - int numTextureParamsToRepack = 1 + (additionalTexturePropertyIDsToCopy == null ? 0 : additionalTexturePropertyIDsToCopy.Length); - additionalOutputTextures = (additionalTexturePropertyIDsToCopy == null ? null : new Texture2D[additionalTexturePropertyIDsToCopy.Length]); - List[] texturesToPackAtParam = new List[numTextureParamsToRepack]; - for (int i = 0; i < numTextureParamsToRepack; ++i) { - texturesToPackAtParam[i] = new List(); + var originalAttachments = o.Attachments; + int attachmentCount = originalAttachments.Count; + List inoutAttachments = new List(attachmentCount); + foreach (var entry in o.Attachments) { + inoutAttachments.Add(entry.attachment); } - var originalRegions = new List(); - int newRegionIndex = 0; - - foreach (var originalSkinEntry in skinAttachments) { - var originalAttachment = originalSkinEntry.Attachment; - - if (originalAttachment is IHasRendererObject) { - var originalMeshAttachment = originalAttachment as MeshAttachment; - Attachment newAttachment = (originalMeshAttachment != null) ? originalMeshAttachment.NewLinkedMesh() : originalAttachment.Copy(); - var region = ((IHasRendererObject)newAttachment).RendererObject as AtlasRegion; - int existingIndex; - if (existingRegions.TryGetValue(region, out existingIndex)) { - regionIndexes.Add(existingIndex); // Store the region index for the eventual new attachment. - } else { - originalRegions.Add(region); - for (int i = 0; i < numTextureParamsToRepack; ++i) { - Texture2D regionTexture = (i == 0 ? region.ToTexture() : region.ToTexture(texturePropertyId : additionalTexturePropertyIDsToCopy[i - 1])); - texturesToPackAtParam[i].Add(regionTexture); // 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++; - } - - repackedAttachments.Add(newAttachment); + GetRepackedAttachments(inoutAttachments, inoutAttachments, materialPropertySource, out outputMaterial, out outputTexture, + maxAtlasSize, padding, textureFormat, mipmaps, newName, clearCache, useOriginalNonrenderables, + additionalTexturePropertyIDsToCopy, additionalOutputTextures); + int i = 0; + foreach (var originalSkinEntry in o.Attachments) { + var newAttachment = inoutAttachments[i++]; newSkin.SetAttachment(originalSkinEntry.SlotIndex, originalSkinEntry.Name, newAttachment); - } else { - newSkin.SetAttachment(originalSkinEntry.SlotIndex, originalSkinEntry.Name, useOriginalNonrenderables ? originalAttachment : originalAttachment.Copy()); - } } - - // Rehydrate the repacked textures as a Material, Spine atlas and Spine.AtlasAttachments - var newMaterial = new Material(shader); - if (materialPropertySource != null) { - newMaterial.CopyPropertiesFromMaterial(materialPropertySource); - newMaterial.shaderKeywords = materialPropertySource.shaderKeywords; - } - newMaterial.name = newName; - - Rect[] rects = null; - for (int i = 0; i < numTextureParamsToRepack; ++i) { - // Fill a new texture with the collected attachment textures. - var newTexture = new Texture2D(maxAtlasSize, maxAtlasSize, textureFormat, mipmaps); - newTexture.mipMapBias = AtlasUtilities.DefaultMipmapBias; - var texturesToPack = texturesToPackAtParam[i]; - if (texturesToPack.Count > 0) { - var sourceTexture = texturesToPack[0]; - newTexture.CopyTextureAttributesFrom(sourceTexture); - } - newTexture.name = newName; - var rectsForTexParam = newTexture.PackTextures(texturesToPack.ToArray(), padding, maxAtlasSize); - if (i == 0) { - rects = rectsForTexParam; - newMaterial.mainTexture = newTexture; - outputTexture = newTexture; - } - else { - newMaterial.SetTexture(additionalTexturePropertyIDsToCopy[i - 1], newTexture); - additionalOutputTextures[i - 1] = newTexture; - } - } - - var page = newMaterial.ToSpineAtlasPage(); - page.name = newName; - - var repackedRegions = new List(); - for (int i = 0, n = originalRegions.Count; i < n; i++) { - var oldRegion = originalRegions[i]; - var newRegion = UVRectToAtlasRegion(rects[i], oldRegion, page); - repackedRegions.Add(newRegion); - } - - // Map the cloned attachments to the repacked atlas. - for (int i = 0, n = repackedAttachments.Count; i < n; i++) { - var a = repackedAttachments[i]; - if (a is IHasRendererObject) - a.SetRegion(repackedRegions[regionIndexes[i]]); - } - - // Clean up. - if (clearCache) - AtlasUtilities.ClearCache(); - - outputMaterial = newMaterial; return newSkin; }