[csharp] Ported AnimationState and Animation changes of commit bd306d4. See #1303.

This commit is contained in:
Harald Csaszar 2019-03-19 17:16:57 +01:00
parent 37b759fc17
commit 9deb3be61c
3 changed files with 50 additions and 42 deletions

View File

@ -987,7 +987,7 @@ namespace Spine {
} }
} }
/// <summary>Changes a slot's <see cref="Slot.AttachmentVertices"/> to deform a <see cref="VertexAttachment"/>.</summary> /// <summary>Changes a slot's <see cref="Slot.Deform"/> to deform a <see cref="VertexAttachment"/>.</summary>
public class DeformTimeline : CurveTimeline, ISlotTimeline { public class DeformTimeline : CurveTimeline, ISlotTimeline {
internal int slotIndex; internal int slotIndex;
internal VertexAttachment attachment; internal VertexAttachment attachment;
@ -1037,41 +1037,41 @@ namespace Spine {
VertexAttachment vertexAttachment = slot.attachment as VertexAttachment; VertexAttachment vertexAttachment = slot.attachment as VertexAttachment;
if (vertexAttachment == null || !vertexAttachment.ApplyDeform(attachment)) return; if (vertexAttachment == null || !vertexAttachment.ApplyDeform(attachment)) return;
var verticesArray = slot.attachmentVertices; var deformArray = slot.Deform;
if (verticesArray.Count == 0) blend = MixBlend.Setup; if (deformArray.Count == 0) blend = MixBlend.Setup;
float[][] frameVertices = this.frameVertices; float[][] frameVertices = this.frameVertices;
int vertexCount = frameVertices[0].Length; int vertexCount = frameVertices[0].Length;
float[] frames = this.frames; float[] frames = this.frames;
float[] vertices; float[] deform;
if (time < frames[0]) { // Time is before first frame. if (time < frames[0]) { // Time is before first frame.
switch (blend) { switch (blend) {
case MixBlend.Setup: case MixBlend.Setup:
verticesArray.Clear(); deformArray.Clear();
return; return;
case MixBlend.Replace: case MixBlend.Replace:
if (alpha == 1) { if (alpha == 1) {
verticesArray.Clear(); deformArray.Clear();
return; return;
} }
// verticesArray.SetSize(vertexCount) // Ensure size and preemptively set count. // deformArray.SetSize(vertexCount) // Ensure size and preemptively set count.
if (verticesArray.Capacity < vertexCount) verticesArray.Capacity = vertexCount; if (deformArray.Capacity < vertexCount) deformArray.Capacity = vertexCount;
verticesArray.Count = vertexCount; deformArray.Count = vertexCount;
vertices = verticesArray.Items; deform = deformArray.Items;
if (vertexAttachment.bones == null) { if (vertexAttachment.bones == null) {
// Unweighted vertex positions. // Unweighted vertex positions.
float[] setupVertices = vertexAttachment.vertices; float[] setupVertices = vertexAttachment.vertices;
for (int i = 0; i < vertexCount; i++) for (int i = 0; i < vertexCount; i++)
vertices[i] += (setupVertices[i] - vertices[i]) * alpha; deform[i] += (setupVertices[i] - deform[i]) * alpha;
} else { } else {
// Weighted deform offsets. // Weighted deform offsets.
alpha = 1 - alpha; alpha = 1 - alpha;
for (int i = 0; i < vertexCount; i++) for (int i = 0; i < vertexCount; i++)
vertices[i] *= alpha; deform[i] *= alpha;
} }
return; return;
default: default:
@ -1080,10 +1080,10 @@ namespace Spine {
} }
// verticesArray.SetSize(vertexCount) // Ensure size and preemptively set count. // deformArray.SetSize(vertexCount) // Ensure size and preemptively set count.
if (verticesArray.Capacity < vertexCount) verticesArray.Capacity = vertexCount; if (deformArray.Capacity < vertexCount) deformArray.Capacity = vertexCount;
verticesArray.Count = vertexCount; deformArray.Count = vertexCount;
vertices = verticesArray.Items; deform = deformArray.Items;
if (time >= frames[frames.Length - 1]) { // Time is after last frame. if (time >= frames[frames.Length - 1]) { // Time is after last frame.
@ -1094,15 +1094,15 @@ namespace Spine {
// Unweighted vertex positions, no alpha. // Unweighted vertex positions, no alpha.
float[] setupVertices = vertexAttachment.vertices; float[] setupVertices = vertexAttachment.vertices;
for (int i = 0; i < vertexCount; i++) for (int i = 0; i < vertexCount; i++)
vertices[i] += lastVertices[i] - setupVertices[i]; deform[i] += lastVertices[i] - setupVertices[i];
} else { } else {
// Weighted deform offsets, no alpha. // Weighted deform offsets, no alpha.
for (int i = 0; i < vertexCount; i++) for (int i = 0; i < vertexCount; i++)
vertices[i] += lastVertices[i]; deform[i] += lastVertices[i];
} }
} else { } else {
// Vertex positions or deform offsets, no alpha. // Vertex positions or deform offsets, no alpha.
Array.Copy(lastVertices, 0, vertices, 0, vertexCount); Array.Copy(lastVertices, 0, deform, 0, vertexCount);
} }
} else { } else {
switch (blend) { switch (blend) {
@ -1112,12 +1112,12 @@ namespace Spine {
float[] setupVertices = vertexAttachment.vertices; float[] setupVertices = vertexAttachment.vertices;
for (int i = 0; i < vertexCount; i++) { for (int i = 0; i < vertexCount; i++) {
float setup = setupVertices[i]; float setup = setupVertices[i];
vertices[i] = setup + (lastVertices[i] - setup) * alpha; deform[i] = setup + (lastVertices[i] - setup) * alpha;
} }
} else { } else {
// Weighted deform offsets, with alpha. // Weighted deform offsets, with alpha.
for (int i = 0; i < vertexCount; i++) for (int i = 0; i < vertexCount; i++)
vertices[i] = lastVertices[i] * alpha; deform[i] = lastVertices[i] * alpha;
} }
break; break;
} }
@ -1125,18 +1125,18 @@ namespace Spine {
case MixBlend.Replace: case MixBlend.Replace:
// Vertex positions or deform offsets, with alpha. // Vertex positions or deform offsets, with alpha.
for (int i = 0; i < vertexCount; i++) for (int i = 0; i < vertexCount; i++)
vertices[i] += (lastVertices[i] - vertices[i]) * alpha; deform[i] += (lastVertices[i] - deform[i]) * alpha;
break; break;
case MixBlend.Add: case MixBlend.Add:
if (vertexAttachment.bones == null) { if (vertexAttachment.bones == null) {
// Unweighted vertex positions, no alpha. // Unweighted vertex positions, no alpha.
float[] setupVertices = vertexAttachment.vertices; float[] setupVertices = vertexAttachment.vertices;
for (int i = 0; i < vertexCount; i++) for (int i = 0; i < vertexCount; i++)
vertices[i] += (lastVertices[i] - setupVertices[i]) * alpha; deform[i] += (lastVertices[i] - setupVertices[i]) * alpha;
} else { } else {
// Weighted deform offsets, alpha. // Weighted deform offsets, alpha.
for (int i = 0; i < vertexCount; i++) for (int i = 0; i < vertexCount; i++)
vertices[i] += lastVertices[i] * alpha; deform[i] += lastVertices[i] * alpha;
} }
break; break;
} }
@ -1158,20 +1158,20 @@ namespace Spine {
float[] setupVertices = vertexAttachment.vertices; float[] setupVertices = vertexAttachment.vertices;
for (int i = 0; i < vertexCount; i++) { for (int i = 0; i < vertexCount; i++) {
float prev = prevVertices[i]; float prev = prevVertices[i];
vertices[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i]; deform[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i];
} }
} else { } else {
// Weighted deform offsets, no alpha. // Weighted deform offsets, no alpha.
for (int i = 0; i < vertexCount; i++) { for (int i = 0; i < vertexCount; i++) {
float prev = prevVertices[i]; float prev = prevVertices[i];
vertices[i] += prev + (nextVertices[i] - prev) * percent; deform[i] += prev + (nextVertices[i] - prev) * percent;
} }
} }
} else { } else {
// Vertex positions or deform offsets, no alpha. // Vertex positions or deform offsets, no alpha.
for (int i = 0; i < vertexCount; i++) { for (int i = 0; i < vertexCount; i++) {
float prev = prevVertices[i]; float prev = prevVertices[i];
vertices[i] = prev + (nextVertices[i] - prev) * percent; deform[i] = prev + (nextVertices[i] - prev) * percent;
} }
} }
} else { } else {
@ -1182,13 +1182,13 @@ namespace Spine {
float[] setupVertices = vertexAttachment.vertices; float[] setupVertices = vertexAttachment.vertices;
for (int i = 0; i < vertexCount; i++) { for (int i = 0; i < vertexCount; i++) {
float prev = prevVertices[i], setup = setupVertices[i]; float prev = prevVertices[i], setup = setupVertices[i];
vertices[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha; deform[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha;
} }
} else { } else {
// Weighted deform offsets, with alpha. // Weighted deform offsets, with alpha.
for (int i = 0; i < vertexCount; i++) { for (int i = 0; i < vertexCount; i++) {
float prev = prevVertices[i]; float prev = prevVertices[i];
vertices[i] = (prev + (nextVertices[i] - prev) * percent) * alpha; deform[i] = (prev + (nextVertices[i] - prev) * percent) * alpha;
} }
} }
break; break;
@ -1198,7 +1198,7 @@ namespace Spine {
// Vertex positions or deform offsets, with alpha. // Vertex positions or deform offsets, with alpha.
for (int i = 0; i < vertexCount; i++) { for (int i = 0; i < vertexCount; i++) {
float prev = prevVertices[i]; float prev = prevVertices[i];
vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha; deform[i] += (prev + (nextVertices[i] - prev) * percent - deform[i]) * alpha;
} }
break; break;
} }
@ -1208,13 +1208,13 @@ namespace Spine {
float[] setupVertices = vertexAttachment.vertices; float[] setupVertices = vertexAttachment.vertices;
for (int i = 0; i < vertexCount; i++) { for (int i = 0; i < vertexCount; i++) {
float prev = prevVertices[i]; float prev = prevVertices[i];
vertices[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha; deform[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha;
} }
} else { } else {
// Weighted deform offsets, with alpha. // Weighted deform offsets, with alpha.
for (int i = 0; i < vertexCount; i++) { for (int i = 0; i < vertexCount; i++) {
float prev = prevVertices[i]; float prev = prevVertices[i];
vertices[i] += (prev + (nextVertices[i] - prev) * percent) * alpha; deform[i] += (prev + (nextVertices[i] - prev) * percent) * alpha;
} }
} }
break; break;

View File

@ -31,7 +31,8 @@
using System; using System;
namespace Spine { namespace Spine {
/// <summary>>An attachment with vertices that are transformed by one or more bones and can be deformed by a slot's vertices.</summary> /// <summary>>An attachment with vertices that are transformed by one or more bones and can be deformed by a slot's
/// <see cref="Slot.Deform"/>.</summary>
public class VertexAttachment : Attachment { public class VertexAttachment : Attachment {
static int nextID = 0; static int nextID = 0;
static readonly Object nextIdLock = new Object(); static readonly Object nextIdLock = new Object();
@ -59,7 +60,13 @@ namespace Spine {
ComputeWorldVertices(slot, 0, worldVerticesLength, worldVertices, 0); ComputeWorldVertices(slot, 0, worldVerticesLength, worldVertices, 0);
} }
/// <summary>Transforms local vertices to world coordinates.</summary> /// <summary>
/// Transforms the attachment's local <see cref="Vertices"/> to world coordinates. If the slot has <see cref="Slot.Deform"/>,
/// they are used to deform the vertices.
/// <para />
/// See <a href="http://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
/// Runtimes Guide.
/// </summary>
/// <param name="start">The index of the first <see cref="Vertices"/> value to transform. Each vertex has 2 values, x and y.</param> /// <param name="start">The index of the first <see cref="Vertices"/> value to transform. Each vertex has 2 values, x and y.</param>
/// <param name="count">The number of world vertex values to output. Must be less than or equal to <see cref="WorldVerticesLength"/> - start.</param> /// <param name="count">The number of world vertex values to output. Must be less than or equal to <see cref="WorldVerticesLength"/> - start.</param>
/// <param name="worldVertices">The output world vertices. Must have a length greater than or equal to <paramref name="offset"/> + <paramref name="count"/>.</param> /// <param name="worldVertices">The output world vertices. Must have a length greater than or equal to <paramref name="offset"/> + <paramref name="count"/>.</param>
@ -68,7 +75,7 @@ namespace Spine {
public void ComputeWorldVertices (Slot slot, int start, int count, float[] worldVertices, int offset, int stride = 2) { public void ComputeWorldVertices (Slot slot, int start, int count, float[] worldVertices, int offset, int stride = 2) {
count = offset + (count >> 1) * stride; count = offset + (count >> 1) * stride;
Skeleton skeleton = slot.bone.skeleton; Skeleton skeleton = slot.bone.skeleton;
var deformArray = slot.attachmentVertices; var deformArray = slot.deform;
float[] vertices = this.vertices; float[] vertices = this.vertices;
int[] bones = this.bones; int[] bones = this.bones;
if (bones == null) { if (bones == null) {

View File

@ -45,7 +45,7 @@ namespace Spine {
internal bool hasSecondColor; internal bool hasSecondColor;
internal Attachment attachment; internal Attachment attachment;
internal float attachmentTime; internal float attachmentTime;
internal ExposedList<float> attachmentVertices = new ExposedList<float>(); internal ExposedList<float> deform = new ExposedList<float>();
public Slot (SlotData data, Bone bone) { public Slot (SlotData data, Bone bone) {
if (data == null) throw new ArgumentNullException("data", "data cannot be null."); if (data == null) throw new ArgumentNullException("data", "data cannot be null.");
@ -84,6 +84,7 @@ namespace Spine {
attachment = slot.attachment; attachment = slot.attachment;
attachmentTime = slot.attachmentTime; attachmentTime = slot.attachmentTime;
deform.AddRange(slot.deform);
} }
/// <summary>The slot's setup pose data.</summary> /// <summary>The slot's setup pose data.</summary>
@ -128,7 +129,7 @@ namespace Spine {
if (attachment == value) return; if (attachment == value) return;
attachment = value; attachment = value;
attachmentTime = bone.skeleton.time; attachmentTime = bone.skeleton.time;
attachmentVertices .Clear(false); deform.Clear(false);
} }
} }
@ -139,17 +140,17 @@ namespace Spine {
set { attachmentTime = bone.skeleton.time - value; } set { attachmentTime = bone.skeleton.time - value; }
} }
/// <summary> Vertices to deform the slot's attachment. For an unweighted mesh, the entries are local positions for each vertex. For a /// <summary> Values to deform the slot's attachment. For an unweighted mesh, the entries are local positions for each vertex. For a
/// weighted mesh, the entries are an offset for each vertex which will be added to the mesh's local vertex positions. /// weighted mesh, the entries are an offset for each vertex which will be added to the mesh's local vertex positions.
/// <para /> /// <para />
/// See <see cref="VertexAttachment.ComputeWorldVertices(Slot, int, int, float[], int, int)"/> and <see cref="DeformTimeline"/>.</summary> /// See <see cref="VertexAttachment.ComputeWorldVertices(Slot, int, int, float[], int, int)"/> and <see cref="DeformTimeline"/>.</summary>
public ExposedList<float> AttachmentVertices { public ExposedList<float> Deform {
get { get {
return attachmentVertices ; return deform;
} }
set { set {
if (attachmentVertices == null) throw new ArgumentNullException("attachmentVertices", "attachmentVertices cannot be null."); if (deform == null) throw new ArgumentNullException("deform", "deform cannot be null.");
attachmentVertices = value; deform = value;
} }
} }