diff --git a/spine-csharp/src/Animation.cs b/spine-csharp/src/Animation.cs index a0589396f..d10be09dd 100644 --- a/spine-csharp/src/Animation.cs +++ b/spine-csharp/src/Animation.cs @@ -1034,7 +1034,7 @@ namespace Spine { MixDirection direction) { Slot slot = skeleton.slots.Items[slotIndex]; VertexAttachment vertexAttachment = slot.attachment as VertexAttachment; - if (vertexAttachment == null || !vertexAttachment.ApplyDeform(attachment)) return; + if (vertexAttachment == null || vertexAttachment.DeformAttachment != attachment) return; var deformArray = slot.Deform; if (deformArray.Count == 0) blend = MixBlend.Setup; diff --git a/spine-csharp/src/Attachments/MeshAttachment.cs b/spine-csharp/src/Attachments/MeshAttachment.cs index 5eb19247e..0e74083f2 100644 --- a/spine-csharp/src/Attachments/MeshAttachment.cs +++ b/spine-csharp/src/Attachments/MeshAttachment.cs @@ -38,8 +38,7 @@ namespace Spine { internal int[] triangles; internal float r = 1, g = 1, b = 1, a = 1; internal int hulllength; - internal bool inheritDeform; - + public int HullLength { get { return hulllength; } set { hulllength = value; } } public float[] RegionUVs { get { return regionUVs; } set { regionUVs = value; } } /// The UV pair for each vertex, normalized within the entire texture. @@ -66,8 +65,6 @@ namespace Spine { public float RegionOriginalWidth { get { return regionOriginalWidth; } set { regionOriginalWidth = value; } } public float RegionOriginalHeight { get { return regionOriginalHeight; } set { regionOriginalHeight = value; } } // Unrotated, unstripped size. - public bool InheritDeform { get { return inheritDeform; } set { inheritDeform = value; } } - public MeshAttachment ParentMesh { get { return parentMesh; } set { @@ -152,11 +149,9 @@ namespace Spine { } } - override public bool ApplyDeform (VertexAttachment sourceAttachment) { - return this == sourceAttachment || (inheritDeform && parentMesh == sourceAttachment); - } - public override Attachment Copy () { + if (parentMesh != null) return NewLinkedMesh(); + MeshAttachment copy = new MeshAttachment(this.Name); copy.regionOffsetX = regionOffsetX; copy.regionOffsetY = regionOffsetY; @@ -164,33 +159,51 @@ namespace Spine { copy.regionHeight = regionHeight; copy.regionOriginalWidth = regionOriginalWidth; copy.regionOriginalHeight = regionOriginalHeight; - copy.Path = Path; + copy.r = r; + copy.g = g; + copy.b = b; + copy.a = a; + copy.deformAttachment = deformAttachment; + + CopyTo(copy); + copy.regionUVs = new float[regionUVs.Length]; + Array.Copy(regionUVs, 0, copy.regionUVs, 0, regionUVs.Length); + copy.uvs = new float[uvs.Length]; + Array.Copy(uvs, 0, copy.uvs, 0, uvs.Length); + copy.triangles = new int[triangles.Length]; + Array.Copy(triangles, 0, copy.triangles, 0, triangles.Length); + copy.HullLength = HullLength; - if (parentMesh == null) { - CopyTo(copy); - copy.regionUVs = new float[regionUVs.Length]; - Array.Copy(regionUVs, 0, copy.regionUVs, 0, regionUVs.Length); - copy.uvs = new float[uvs.Length]; - Array.Copy(uvs, 0, copy.uvs, 0, uvs.Length); - copy.triangles = new int[triangles.Length]; - Array.Copy(triangles, 0, copy.triangles, 0, triangles.Length); - copy.HullLength = HullLength; - - copy.inheritDeform = inheritDeform; - - // Nonessential. - if (Edges != null) { - copy.Edges = new int[Edges.Length]; - Array.Copy(Edges, 0, copy.Edges, 0, Edges.Length); - } - copy.Width = Width; - copy.Height = Height; + // Nonessential. + if (Edges != null) { + copy.Edges = new int[Edges.Length]; + Array.Copy(Edges, 0, copy.Edges, 0, Edges.Length); } - else - copy.ParentMesh = parentMesh; - + copy.Width = Width; + copy.Height = Height; return copy; } + + ///Returns a new mesh with this mesh set as the . + public MeshAttachment NewLinkedMesh () { + MeshAttachment mesh = new MeshAttachment(Name); + mesh.regionOffsetX = regionOffsetX; + mesh.regionOffsetY = regionOffsetY; + mesh.regionWidth = regionWidth; + mesh.regionHeight = regionHeight; + mesh.regionOriginalWidth = regionOriginalWidth; + mesh.regionOriginalHeight = regionOriginalHeight; + + mesh.Path = Path; + mesh.r = r; + mesh.g = g; + mesh.b = b; + mesh.a = a; + mesh.deformAttachment = deformAttachment; + mesh.ParentMesh = parentMesh != null ? parentMesh : this; + mesh.UpdateUVs(); + return mesh; + } } } diff --git a/spine-csharp/src/Attachments/VertexAttachment.cs b/spine-csharp/src/Attachments/VertexAttachment.cs index 71bb42ea0..d5ffb183f 100644 --- a/spine-csharp/src/Attachments/VertexAttachment.cs +++ b/spine-csharp/src/Attachments/VertexAttachment.cs @@ -40,16 +40,21 @@ namespace Spine { internal int[] bones; internal float[] vertices; internal int worldVerticesLength; + internal VertexAttachment deformAttachment; /// Gets a unique ID for this attachment. public int Id { get { return id; } } public int[] Bones { get { return bones; } set { bones = value; } } public float[] Vertices { get { return vertices; } set { vertices = value; } } public int WorldVerticesLength { get { return worldVerticesLength; } set { worldVerticesLength = value; } } + ///Deform keys for the deform attachment are also applied to this attachment. + /// May be null if no deform keys should be applied. + public VertexAttachment DeformAttachment { get { return deformAttachment; } set { deformAttachment = value; } } public VertexAttachment (string name) : base(name) { + deformAttachment = this; lock (VertexAttachment.nextIdLock) { id = (VertexAttachment.nextID++ & 65535) << 11; } @@ -128,11 +133,6 @@ namespace Spine { } } - /// Returns true if a deform originally applied to the specified attachment should be applied to this attachment. - virtual public bool ApplyDeform (VertexAttachment sourceAttachment) { - return this == sourceAttachment; - } - ///Does not copy id (generated) or name (set on construction). internal void CopyTo (VertexAttachment attachment) { if (bones != null) { diff --git a/spine-csharp/src/Skeleton.cs b/spine-csharp/src/Skeleton.cs index af8ddc642..20a879201 100644 --- a/spine-csharp/src/Skeleton.cs +++ b/spine-csharp/src/Skeleton.cs @@ -507,7 +507,7 @@ namespace Spine { } /// A convenience method to set an attachment by finding the slot with FindSlot, finding the attachment with GetAttachment, then setting the slot's slot.Attachment. - /// May be null. + /// May be null to clear the slot's attachment. public void SetAttachment (string slotName, string attachmentName) { if (slotName == null) throw new ArgumentNullException("slotName", "slotName cannot be null."); ExposedList slots = this.slots; diff --git a/spine-csharp/src/SkeletonBinary.cs b/spine-csharp/src/SkeletonBinary.cs index a660ddda4..08bb6d5ff 100644 --- a/spine-csharp/src/SkeletonBinary.cs +++ b/spine-csharp/src/SkeletonBinary.cs @@ -281,6 +281,7 @@ namespace Spine { if (skin == null) throw new Exception("Skin not found: " + linkedMesh.skin); Attachment parent = skin.GetAttachment(linkedMesh.slotIndex, linkedMesh.parent); if (parent == null) throw new Exception("Parent mesh not found: " + linkedMesh.parent); + linkedMesh.mesh.DeformAttachment = linkedMesh.inheritDeform ? (VertexAttachment)parent : linkedMesh.mesh; linkedMesh.mesh.ParentMesh = (MeshAttachment)parent; linkedMesh.mesh.UpdateUVs(); } @@ -446,12 +447,11 @@ namespace Spine { mesh.g = ((color & 0x00ff0000) >> 16) / 255f; mesh.b = ((color & 0x0000ff00) >> 8) / 255f; mesh.a = ((color & 0x000000ff)) / 255f; - mesh.inheritDeform = inheritDeform; if (nonessential) { mesh.Width = width * scale; mesh.Height = height * scale; } - linkedMeshes.Add(new SkeletonJson.LinkedMesh(mesh, skinName, slotIndex, parent)); + linkedMeshes.Add(new SkeletonJson.LinkedMesh(mesh, skinName, slotIndex, parent, inheritDeform)); return mesh; } case AttachmentType.Path: { diff --git a/spine-csharp/src/SkeletonJson.cs b/spine-csharp/src/SkeletonJson.cs index b42d35276..f213467bf 100644 --- a/spine-csharp/src/SkeletonJson.cs +++ b/spine-csharp/src/SkeletonJson.cs @@ -427,8 +427,7 @@ namespace Spine { string parent = GetString(map, "parent", null); if (parent != null) { - mesh.InheritDeform = GetBoolean(map, "deform", true); - linkedMeshes.Add(new LinkedMesh(mesh, GetString(map, "skin", null), slotIndex, parent)); + linkedMeshes.Add(new LinkedMesh(mesh, GetString(map, "skin", null), slotIndex, parent, GetBoolean(map, "deform", true))); return mesh; } @@ -864,12 +863,14 @@ namespace Spine { internal string parent, skin; internal int slotIndex; internal MeshAttachment mesh; + internal bool inheritDeform; - public LinkedMesh (MeshAttachment mesh, string skin, int slotIndex, string parent) { + public LinkedMesh (MeshAttachment mesh, string skin, int slotIndex, string parent, bool inheritDeform) { this.mesh = mesh; this.skin = skin; this.slotIndex = slotIndex; this.parent = parent; + this.inheritDeform = inheritDeform; } } diff --git a/spine-csharp/src/Skin.cs b/spine-csharp/src/Skin.cs index e57b3d33d..e7c7f099d 100644 --- a/spine-csharp/src/Skin.cs +++ b/spine-csharp/src/Skin.cs @@ -82,10 +82,10 @@ namespace Spine { if (!constraints.Contains(data)) constraints.Add(data); foreach (SkinEntry entry in skin.attachments.Keys) { - Attachment attachment = entry.Attachment.Copy(); - if (attachment is MeshAttachment) { - } - SetAttachment(entry.SlotIndex, entry.Name, attachment); + if (entry.Attachment is MeshAttachment) + SetAttachment(entry.SlotIndex, entry.Name, ((MeshAttachment)entry.Attachment).NewLinkedMesh()); + else + SetAttachment(entry.SlotIndex, entry.Name, entry.Attachment.Copy()); } } diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools/AttachmentTools.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools/AttachmentTools.cs index 231a60817..cba045633 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools/AttachmentTools.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Modules/AttachmentTools/AttachmentTools.cs @@ -415,7 +415,7 @@ namespace Spine.Unity.Modules.AttachmentTools { var originalAttachment = sourceAttachments[i]; if (IsRenderable(originalAttachment)) { - var newAttachment = originalAttachment.GetClone(true); + var newAttachment = originalAttachment.GetCopy(true); var region = newAttachment.GetRegion(); int existingIndex; if (existingRegions.TryGetValue(region, out existingIndex)) { @@ -430,7 +430,7 @@ namespace Spine.Unity.Modules.AttachmentTools { outputAttachments[i] = newAttachment; } else { - outputAttachments[i] = useOriginalNonrenderables ? originalAttachment : originalAttachment.GetClone(true); + outputAttachments[i] = useOriginalNonrenderables ? originalAttachment : originalAttachment.GetCopy(true); regionIndexes.Add(NonrenderingRegion); // Output attachments pairs with regionIndexes list 1:1. Pad with a sentinel if the attachment doesn't have a region. } } @@ -511,7 +511,7 @@ namespace Spine.Unity.Modules.AttachmentTools { Attachment newAttachment; if (IsRenderable(originalAttachment)) { - newAttachment = originalAttachment.GetClone(true); + newAttachment = originalAttachment.GetCopy(true); var region = newAttachment.GetRegion(); int existingIndex; if (existingRegions.TryGetValue(region, out existingIndex)) { @@ -527,7 +527,7 @@ namespace Spine.Unity.Modules.AttachmentTools { repackedAttachments.Add(newAttachment); newSkin.SetAttachment(originalKey.SlotIndex, originalKey.Name, newAttachment); } else { - newSkin.SetAttachment(originalKey.SlotIndex, originalKey.Name, useOriginalNonrenderables ? originalAttachment : originalAttachment.GetClone(true)); + newSkin.SetAttachment(originalKey.SlotIndex, originalKey.Name, useOriginalNonrenderables ? originalAttachment : originalAttachment.GetCopy(true)); } } @@ -851,11 +851,11 @@ namespace Spine.Unity.Modules.AttachmentTools { if (cloneAttachments) { if (overwrite) { foreach (DictionaryEntry e in sourceAttachments) - destinationAttachments[e.Key] = ((Attachment)e.Value).GetClone(cloneMeshesAsLinked); + destinationAttachments[e.Key] = ((Attachment)e.Value).GetCopy(cloneMeshesAsLinked); } else { foreach (DictionaryEntry e in sourceAttachments) { if (destinationAttachments.Contains(e.Key)) continue; - destinationAttachments.Add(e.Key, ((Attachment)e.Value).GetClone(cloneMeshesAsLinked)); + destinationAttachments.Add(e.Key, ((Attachment)e.Value).GetCopy(cloneMeshesAsLinked)); } } } else { @@ -877,213 +877,40 @@ namespace Spine.Unity.Modules.AttachmentTools { public static class AttachmentCloneExtensions { /// /// Clones the attachment. - public static Attachment GetClone (this Attachment o, bool cloneMeshesAsLinked) { - var regionAttachment = o as RegionAttachment; - if (regionAttachment != null) - return regionAttachment.GetClone(); - + public static Attachment GetCopy (this Attachment o, bool cloneMeshesAsLinked) { var meshAttachment = o as MeshAttachment; - if (meshAttachment != null) - return cloneMeshesAsLinked ? meshAttachment.GetLinkedClone() : meshAttachment.GetClone(); - - var boundingBoxAttachment = o as BoundingBoxAttachment; - if (boundingBoxAttachment != null) - return boundingBoxAttachment.GetClone(); - - var pathAttachment = o as PathAttachment; - if (pathAttachment != null) - return pathAttachment.GetClone(); - - var pointAttachment = o as PointAttachment; - if (pointAttachment != null) - return pointAttachment.GetClone(); - - var clippingAttachment = o as ClippingAttachment; - if (clippingAttachment != null) - return clippingAttachment.GetClone(); - - return null; + if (meshAttachment != null && cloneMeshesAsLinked) + return meshAttachment.NewLinkedMesh(); + return o.Copy(); } - public static RegionAttachment GetClone (this RegionAttachment o) { - return new RegionAttachment(o.Name) { - x = o.x, - y = o.y, - rotation = o.rotation, - scaleX = o.scaleX, - scaleY = o.scaleY, - width = o.width, - height = o.height, - - r = o.r, - g = o.g, - b = o.b, - a = o.a, - - Path = o.Path, - RendererObject = o.RendererObject, - regionOffsetX = o.regionOffsetX, - regionOffsetY = o.regionOffsetY, - regionWidth = o.regionWidth, - regionHeight = o.regionHeight, - regionOriginalWidth = o.regionOriginalWidth, - regionOriginalHeight = o.regionOriginalHeight, - uvs = o.uvs.Clone() as float[], - offset = o.offset.Clone() as float[] - }; - } - - public static ClippingAttachment GetClone (this ClippingAttachment o) { - var ca = new ClippingAttachment(o.Name) { - endSlot = o.endSlot - }; - CloneVertexAttachment(o, ca); - return ca; - } - - public static PointAttachment GetClone (this PointAttachment o) { - var pa = new PointAttachment(o.Name) { - rotation = o.rotation, - x = o.x, - y = o.y - }; - return pa; - } - - public static BoundingBoxAttachment GetClone (this BoundingBoxAttachment o) { - var ba = new BoundingBoxAttachment(o.Name); - CloneVertexAttachment(o, ba); - return ba; - } - - public static MeshAttachment GetLinkedClone (this MeshAttachment o, bool inheritDeform = true) { - return o.GetLinkedMesh(o.Name, o.RendererObject as AtlasRegion, inheritDeform, copyOriginalProperties: true); - } - - /// - /// Returns a clone of the MeshAttachment. This will cause Deform animations to stop working unless you explicity set the .parentMesh to the original. - public static MeshAttachment GetClone (this MeshAttachment o) { - var ma = new MeshAttachment(o.Name) { - r = o.r, - g = o.g, - b = o.b, - a = o.a, - - inheritDeform = o.inheritDeform, - - Path = o.Path, - RendererObject = o.RendererObject, - - regionOffsetX = o.regionOffsetX, - regionOffsetY = o.regionOffsetY, - regionWidth = o.regionWidth, - regionHeight = o.regionHeight, - regionOriginalWidth = o.regionOriginalWidth, - regionOriginalHeight = o.regionOriginalHeight, - RegionU = o.RegionU, - RegionV = o.RegionV, - RegionU2 = o.RegionU2, - RegionV2 = o.RegionV2, - RegionRotate = o.RegionRotate, - uvs = o.uvs.Clone() as float[] - }; - - // Linked mesh - if (o.ParentMesh != null) { - // bones, vertices, worldVerticesLength, regionUVs, triangles, HullLength, Edges, Width, Height - ma.ParentMesh = o.ParentMesh; - } else { - CloneVertexAttachment(o, ma); // bones, vertices, worldVerticesLength - ma.regionUVs = o.regionUVs.Clone() as float[]; - ma.triangles = o.triangles.Clone() as int[]; - ma.hulllength = o.hulllength; - - // Nonessential. - ma.Edges = (o.Edges == null) ? null : o.Edges.Clone() as int[]; // Allow absence of Edges array when nonessential data is not exported. - ma.Width = o.Width; - ma.Height = o.Height; - } - - return ma; - } - - public static PathAttachment GetClone (this PathAttachment o) { - var newPathAttachment = new PathAttachment(o.Name) { - lengths = o.lengths.Clone() as float[], - closed = o.closed, - constantSpeed = o.constantSpeed - }; - CloneVertexAttachment(o, newPathAttachment); - - return newPathAttachment; - } - - static void CloneVertexAttachment (VertexAttachment src, VertexAttachment dest) { - dest.worldVerticesLength = src.worldVerticesLength; - if (src.bones != null) - dest.bones = src.bones.Clone() as int[]; - - if (src.vertices != null) - dest.vertices = src.vertices.Clone() as float[]; - } - - #region Runtime Linked MeshAttachments /// /// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to the AtlasRegion provided. - public static MeshAttachment GetLinkedMesh (this MeshAttachment o, string newLinkedMeshName, AtlasRegion region, bool inheritDeform = true, bool copyOriginalProperties = false) { - //if (string.IsNullOrEmpty(attachmentName)) throw new System.ArgumentException("attachmentName cannot be null or empty", "attachmentName"); + public static MeshAttachment GetLinkedMesh (this MeshAttachment o, string newLinkedMeshName, AtlasRegion region) { if (region == null) throw new System.ArgumentNullException("region"); - - // If parentMesh is a linked mesh, create a link to its parent. Preserves Deform animations. - if (o.ParentMesh != null) - o = o.ParentMesh; - - // 1. NewMeshAttachment (AtlasAttachmentLoader.cs) - var mesh = new MeshAttachment(newLinkedMeshName); + MeshAttachment mesh = o.NewLinkedMesh(); mesh.SetRegion(region, false); - - // 2. (SkeletonJson.cs::ReadAttachment. case: LinkedMesh) - mesh.Path = newLinkedMeshName; - if (copyOriginalProperties) { - mesh.r = o.r; - mesh.g = o.g; - mesh.b = o.b; - mesh.a = o.a; - } else { - mesh.r = 1f; - mesh.g = 1f; - mesh.b = 1f; - mesh.a = 1f; - } - - //mesh.ParentMesh property call below sets mesh.Width and mesh.Height - - // 3. Link mesh with parent. (SkeletonJson.cs) - mesh.inheritDeform = inheritDeform; - mesh.ParentMesh = o; - mesh.UpdateUVs(); - return mesh; } /// /// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to an AtlasRegion generated from a Sprite. The AtlasRegion will be mapped to a new Material based on the shader. /// For better caching and batching, use GetLinkedMesh(string, AtlasRegion, bool) - public static MeshAttachment GetLinkedMesh (this MeshAttachment o, Sprite sprite, Shader shader, bool inheritDeform = true, Material materialPropertySource = null) { + public static MeshAttachment GetLinkedMesh (this MeshAttachment o, Sprite sprite, Shader shader, Material materialPropertySource = null) { var m = new Material(shader); if (materialPropertySource != null) { m.CopyPropertiesFromMaterial(materialPropertySource); m.shaderKeywords = materialPropertySource.shaderKeywords; } - return o.GetLinkedMesh(sprite.name, sprite.ToAtlasRegion(), inheritDeform); + return o.GetLinkedMesh(sprite.name, sprite.ToAtlasRegion()); } /// /// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to an AtlasRegion generated from a Sprite. The AtlasRegion will be mapped to a new Material based on the shader. /// For better caching and batching, use GetLinkedMesh(string, AtlasRegion, bool) - public static MeshAttachment GetLinkedMesh (this MeshAttachment o, Sprite sprite, Material materialPropertySource, bool inheritDeform = true) { - return o.GetLinkedMesh(sprite, materialPropertySource.shader, inheritDeform, materialPropertySource); + public static MeshAttachment GetLinkedMesh (this MeshAttachment o, Sprite sprite, Material materialPropertySource) { + return o.GetLinkedMesh(sprite, materialPropertySource.shader, materialPropertySource); } #endregion @@ -1113,7 +940,7 @@ namespace Spine.Unity.Modules.AttachmentTools { public static Attachment GetRemappedClone (this Attachment o, AtlasRegion atlasRegion, bool cloneMeshAsLinked = true, bool useOriginalRegionSize = false, float scale = 0.01f) { var regionAttachment = o as RegionAttachment; if (regionAttachment != null) { - RegionAttachment newAttachment = regionAttachment.GetClone(); + RegionAttachment newAttachment = (RegionAttachment)regionAttachment.Copy(); newAttachment.SetRegion(atlasRegion, false); if (!useOriginalRegionSize) { newAttachment.width = atlasRegion.width * scale; @@ -1124,13 +951,13 @@ namespace Spine.Unity.Modules.AttachmentTools { } else { var meshAttachment = o as MeshAttachment; if (meshAttachment != null) { - MeshAttachment newAttachment = cloneMeshAsLinked ? meshAttachment.GetLinkedClone(cloneMeshAsLinked) : meshAttachment.GetClone(); + MeshAttachment newAttachment = cloneMeshAsLinked ? meshAttachment.NewLinkedMesh() : (MeshAttachment)meshAttachment.Copy(); newAttachment.SetRegion(atlasRegion); return newAttachment; } } - return o.GetClone(true); // Non-renderable Attachments will return as normal cloned attachments. + return o.GetCopy(true); // Non-renderable Attachments will return as normal cloned attachments. } #endregion }