[unity] Better nonrenderables repack handling.

This commit is contained in:
pharan 2018-07-02 16:16:27 +08:00 committed by GitHub
parent 046c9b871a
commit b82b27ebca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -211,6 +211,8 @@ namespace Spine.Unity.Modules.AttachmentTools {
internal const bool UseMipMaps = false; internal const bool UseMipMaps = false;
internal const float DefaultScale = 0.01f; internal const float DefaultScale = 0.01f;
const int NonrenderingRegion = -1;
public static AtlasRegion ToAtlasRegion (this Texture2D t, Material materialPropertySource, float scale = DefaultScale) { public static AtlasRegion ToAtlasRegion (this Texture2D t, Material materialPropertySource, float scale = DefaultScale) {
return t.ToAtlasRegion(materialPropertySource.shader, scale, materialPropertySource); return t.ToAtlasRegion(materialPropertySource.shader, scale, materialPropertySource);
} }
@ -395,7 +397,7 @@ namespace Spine.Unity.Modules.AttachmentTools {
/// <param name = "outputAttachments">The List(Attachment) to populate with the newly created Attachment objects.</param> /// <param name = "outputAttachments">The List(Attachment) to populate with the newly created Attachment objects.</param>
/// ///
/// <param name="materialPropertySource">May be null. If no Material property source is provided, no special </param> /// <param name="materialPropertySource">May be null. If no Material property source is provided, no special </param>
public static void GetRepackedAttachments (List<Attachment> sourceAttachments, List<Attachment> 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", bool clearCache = false) { public static void GetRepackedAttachments (List<Attachment> sourceAttachments, List<Attachment> 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", bool clearCache = false, bool useOriginalNonrenderables = true) {
if (sourceAttachments == null) throw new System.ArgumentNullException("sourceAttachments"); if (sourceAttachments == null) throw new System.ArgumentNullException("sourceAttachments");
if (outputAttachments == null) throw new System.ArgumentNullException("outputAttachments"); if (outputAttachments == null) throw new System.ArgumentNullException("outputAttachments");
@ -411,9 +413,9 @@ namespace Spine.Unity.Modules.AttachmentTools {
int newRegionIndex = 0; int newRegionIndex = 0;
for (int i = 0, n = sourceAttachments.Count; i < n; i++) { for (int i = 0, n = sourceAttachments.Count; i < n; i++) {
var originalAttachment = sourceAttachments[i]; var originalAttachment = sourceAttachments[i];
var newAttachment = originalAttachment.GetClone(true);
if (IsRenderable(newAttachment)) {
if (IsRenderable(originalAttachment)) {
var newAttachment = originalAttachment.GetClone(true);
var region = newAttachment.GetRegion(); var region = newAttachment.GetRegion();
int existingIndex; int existingIndex;
if (existingRegions.TryGetValue(region, out existingIndex)) { if (existingRegions.TryGetValue(region, out existingIndex)) {
@ -427,6 +429,9 @@ namespace Spine.Unity.Modules.AttachmentTools {
} }
outputAttachments[i] = newAttachment; outputAttachments[i] = newAttachment;
} else {
outputAttachments[i] = useOriginalNonrenderables ? originalAttachment : originalAttachment.GetClone(true);
regionIndexes.Add(NonrenderingRegion); // Output attachments pairs with regionIndexes list 1:1. Pad with a sentinel if the attachment doesn't have a region.
} }
} }
@ -460,7 +465,8 @@ namespace Spine.Unity.Modules.AttachmentTools {
// Map the cloned attachments to the repacked atlas. // Map the cloned attachments to the repacked atlas.
for (int i = 0, n = outputAttachments.Count; i < n; i++) { for (int i = 0, n = outputAttachments.Count; i < n; i++) {
var a = outputAttachments[i]; var a = outputAttachments[i];
a.SetRegion(repackedRegions[regionIndexes[i]]); if (IsRenderable(a))
a.SetRegion(repackedRegions[regionIndexes[i]]);
} }
// Clean up. // Clean up.
@ -474,14 +480,14 @@ namespace Spine.Unity.Modules.AttachmentTools {
/// <summary> /// <summary>
/// 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.</summary> /// 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.</summary>
/// <remarks>No Spine.Atlas object is created so there is no way to find AtlasRegions except through the Attachments using them.</remarks> /// <remarks>No Spine.Atlas object is created so there is no way to find AtlasRegions except through the Attachments using them.</remarks>
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) { 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, bool useOriginalNonrenderables = true) {
return GetRepackedSkin(o, newName, materialPropertySource.shader, out outputMaterial, out outputTexture, maxAtlasSize, padding, textureFormat, mipmaps, materialPropertySource); return GetRepackedSkin(o, newName, materialPropertySource.shader, out outputMaterial, out outputTexture, maxAtlasSize, padding, textureFormat, mipmaps, materialPropertySource, useOriginalNonrenderables);
} }
/// <summary> /// <summary>
/// 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.</summary> /// 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.</summary>
/// <remarks>No Spine.Atlas object is created so there is no way to find AtlasRegions except through the Attachments using them.</remarks> /// <remarks>No Spine.Atlas object is created so there is no way to find AtlasRegions except through the Attachments using them.</remarks>
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, bool clearCache = false) { 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, bool clearCache = false, bool useOriginalNonrenderables = true) {
if (o == null) throw new System.NullReferenceException("Skin was null"); if (o == null) throw new System.NullReferenceException("Skin was null");
var skinAttachments = o.Attachments; var skinAttachments = o.Attachments;
var newSkin = new Skin(newName); var newSkin = new Skin(newName);
@ -495,10 +501,13 @@ namespace Spine.Unity.Modules.AttachmentTools {
var texturesToPack = new List<Texture2D>(); var texturesToPack = new List<Texture2D>();
var originalRegions = new List<AtlasRegion>(); var originalRegions = new List<AtlasRegion>();
int newRegionIndex = 0; int newRegionIndex = 0;
foreach (var kvp in skinAttachments) { foreach (var skinEntry in skinAttachments) {
var newAttachment = kvp.Value.GetClone(true); var originalKey = skinEntry.Key;
if (IsRenderable(newAttachment)) { var originalAttachment = skinEntry.Value;
Attachment newAttachment;
if (IsRenderable(originalAttachment)) {
newAttachment = originalAttachment.GetClone(true);
var region = newAttachment.GetRegion(); var region = newAttachment.GetRegion();
int existingIndex; int existingIndex;
if (existingRegions.TryGetValue(region, out existingIndex)) { if (existingRegions.TryGetValue(region, out existingIndex)) {
@ -512,9 +521,10 @@ namespace Spine.Unity.Modules.AttachmentTools {
} }
repackedAttachments.Add(newAttachment); repackedAttachments.Add(newAttachment);
newSkin.AddAttachment(originalKey.slotIndex, originalKey.name, newAttachment);
} else {
newSkin.AddAttachment(originalKey.slotIndex, originalKey.name, useOriginalNonrenderables ? originalAttachment : originalAttachment.GetClone(true));
} }
var key = kvp.Key;
newSkin.AddAttachment(key.slotIndex, key.name, newAttachment);
} }
// Fill a new texture with the collected attachment textures. // Fill a new texture with the collected attachment textures.
@ -546,7 +556,8 @@ namespace Spine.Unity.Modules.AttachmentTools {
// Map the cloned attachments to the repacked atlas. // Map the cloned attachments to the repacked atlas.
for (int i = 0, n = repackedAttachments.Count; i < n; i++) { for (int i = 0, n = repackedAttachments.Count; i < n; i++) {
var a = repackedAttachments[i]; var a = repackedAttachments[i];
a.SetRegion(repackedRegions[regionIndexes[i]]); if (IsRenderable(a))
a.SetRegion(repackedRegions[regionIndexes[i]]);
} }
// Clean up. // Clean up.