[csharp] Ported more skin API changes of commits eae88a0 and b87ff73 (Added Mesh#newLinkedMesh(), replaced VertexAttachment#applyDeform with VertexAttachment#deformAttachment), see #841.

This commit is contained in:
Harald Csaszar 2019-05-31 21:25:46 +02:00
parent 47c3704acd
commit 4a684f63bf
8 changed files with 80 additions and 239 deletions

View File

@ -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;

View File

@ -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; } }
/// <summary>The UV pair for each vertex, normalized within the entire texture. <seealso cref="MeshAttachment.UpdateUVs"/></summary>
@ -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;
}
///<summary>Returns a new mesh with this mesh set as the <see cref="ParentMesh"/>.
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;
}
}
}

View File

@ -40,16 +40,21 @@ namespace Spine {
internal int[] bones;
internal float[] vertices;
internal int worldVerticesLength;
internal VertexAttachment deformAttachment;
/// <summary>Gets a unique ID for this attachment.</summary>
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; } }
///<summary>Deform keys for the deform attachment are also applied to this attachment.
/// May be null if no deform keys should be applied.</summary>
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 {
}
}
/// <summary>Returns true if a deform originally applied to the specified attachment should be applied to this attachment.</summary>
virtual public bool ApplyDeform (VertexAttachment sourceAttachment) {
return this == sourceAttachment;
}
///<summary>Does not copy id (generated) or name (set on construction).</summary>
internal void CopyTo (VertexAttachment attachment) {
if (bones != null) {

View File

@ -507,7 +507,7 @@ namespace Spine {
}
/// <summary>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.</summary>
/// <param name="attachmentName">May be null.</param>
/// <param name="attachmentName">May be null to clear the slot's attachment.</param>
public void SetAttachment (string slotName, string attachmentName) {
if (slotName == null) throw new ArgumentNullException("slotName", "slotName cannot be null.");
ExposedList<Slot> slots = this.slots;

View File

@ -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: {

View File

@ -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;
}
}

View File

@ -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());
}
}

View File

@ -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 {
/// <summary>
/// Clones the attachment.</summary>
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);
}
/// <summary>
/// Returns a clone of the MeshAttachment. This will cause Deform animations to stop working unless you explicity set the .parentMesh to the original.</summary>
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
/// <summary>
/// Returns a new linked mesh linked to this MeshAttachment. It will be mapped to the AtlasRegion provided.</summary>
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;
}
/// <summary>
/// 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)</summary>
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());
}
/// <summary>
/// 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)</summary>
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
}