[csharp] Code style update.

* `else` on same line as `if` brace.
* `var` only when the type is shown.
* Removed unnecessarily locals, eg `var events = this.events; var eventsItems = events.Items;`.
* Don't indent `case`.
* ExposedList for EventQueue just so iteration can use array indexing.
* EventQueue, inner members (struct/enum) after methods.
* No braces for single line `if/else/for`.
* Removed comments noting ref impl code, eg `// abc.setSize(xyz);`.
* Removed comments that didn't add to what the code shows, eg `// Pooling`.
* Removed comments not in ref impl about implementation details, eg `// nextTrackLast == -1 ...`.
* Removed commented code we are not using.
* Use local with list.Items when iterating.
This commit is contained in:
Nathan Sweet 2021-05-31 01:21:03 -04:00
parent 551f33b2d1
commit 963da7561e
18 changed files with 1001 additions and 1066 deletions

1
.gitignore vendored
View File

@ -48,6 +48,7 @@ xcshareddata/
spine-cocos2d-objc/cocos2d/* spine-cocos2d-objc/cocos2d/*
spine-cocos2d-objc/spine-cocos2d-iphone-objc.xcodeproj/project.xcworkspace/xcshareddata/ spine-cocos2d-objc/spine-cocos2d-iphone-objc.xcodeproj/project.xcworkspace/xcshareddata/
spine-csharp/.vs/
spine-csharp/bin spine-csharp/bin
spine-csharp/obj spine-csharp/obj
spine-csharp/src/*.meta spine-csharp/src/*.meta

View File

@ -60,18 +60,16 @@ namespace Spine {
// once (EnsureCapacity() is only available in newer .Net versions). // once (EnsureCapacity() is only available in newer .Net versions).
int idCount = 0; int idCount = 0;
int timelinesCount = timelines.Count; int timelinesCount = timelines.Count;
var timelinesItems = timelines.Items; Timeline[] timelinesItems = timelines.Items;
for (int t = 0; t < timelinesCount; ++t) { for (int t = 0; t < timelinesCount; ++t)
idCount += timelinesItems[t].PropertyIds.Length; idCount += timelinesItems[t].PropertyIds.Length;
}
string[] propertyIds = new string[idCount]; string[] propertyIds = new string[idCount];
int currentId = 0; int currentId = 0;
for (int t = 0; t < timelinesCount; ++t) { for (int t = 0; t < timelinesCount; ++t) {
var ids = timelinesItems[t].PropertyIds; var ids = timelinesItems[t].PropertyIds;
for (int i = 0, idsLength = ids.Length; i < idsLength; ++i) { for (int i = 0, idsLength = ids.Length; i < idsLength; ++i)
propertyIds[currentId++] = ids[i]; propertyIds[currentId++] = ids[i];
} }
}
this.timelineIds = new HashSet<string>(propertyIds); this.timelineIds = new HashSet<string>(propertyIds);
} }
@ -125,26 +123,6 @@ namespace Spine {
override public string ToString () { override public string ToString () {
return name; return name;
} }
/// <summary>Search using a stride of 1.</summary>
/// <param name="time">Must be >= the first value in <code>frames</code>.</param>
/// <returns>The index of the first value <= <code>time</code>.</returns>
internal static int Search (float[] frames, float time) {
int n = frames.Length;
for (int i = 1; i < n; i++)
if (frames[i] > time) return i - 1;
return n - 1;
}
/// <summary>Search using the specified stride.</summary>
/// <param name="time">Must be >= the first value in <code>frames</code>.</param>
/// <returns>The index of the first value <= <code>time</code>.</returns>
internal static int Search (float[] frames, float time, int step) {
int n = frames.Length;
for (int i = step; i < n; i += step)
if (frames[i] > time) return i - step;
return n - step;
}
} }
/// <summary> /// <summary>
@ -152,7 +130,6 @@ namespace Spine {
/// <code>alpha</code> < 1.</summary> /// <code>alpha</code> < 1.</summary>
/// <seealso cref="Timeline.Apply(Skeleton, float, float, ExposedList, float, MixBlend, MixDirection)"/> /// <seealso cref="Timeline.Apply(Skeleton, float, float, ExposedList, float, MixBlend, MixDirection)"/>
public enum MixBlend { public enum MixBlend {
/// <summary> Transitions from the setup value to the timeline value (the current value is not used). Before the first frame, the /// <summary> Transitions from the setup value to the timeline value (the current value is not used). Before the first frame, the
/// setup value is set.</summary> /// setup value is set.</summary>
Setup, Setup,
@ -267,6 +244,26 @@ namespace Spine {
/// such as <see cref="DrawOrderTimeline"/> or <see cref="AttachmentTimeline"/>, and other such as <see cref="ScaleTimeline"/>.</param> /// such as <see cref="DrawOrderTimeline"/> or <see cref="AttachmentTimeline"/>, and other such as <see cref="ScaleTimeline"/>.</param>
public abstract void Apply (Skeleton skeleton, float lastTime, float time, ExposedList<Event> events, float alpha, public abstract void Apply (Skeleton skeleton, float lastTime, float time, ExposedList<Event> events, float alpha,
MixBlend blend, MixDirection direction); MixBlend blend, MixDirection direction);
/// <summary>Search using a stride of 1.</summary>
/// <param name="time">Must be >= the first value in <code>frames</code>.</param>
/// <returns>The index of the first value <= <code>time</code>.</returns>
internal static int Search (float[] frames, float time) {
int n = frames.Length;
for (int i = 1; i < n; i++)
if (frames[i] > time) return i - 1;
return n - 1;
}
/// <summary>Search using the specified stride.</summary>
/// <param name="time">Must be >= the first value in <code>frames</code>.</param>
/// <returns>The index of the first value <= <code>time</code>.</returns>
internal static int Search (float[] frames, float time, int step) {
int n = frames.Length;
for (int i = step; i < n; i += step)
if (frames[i] > time) return i - step;
return n - step;
}
} }
/// <summary>An interface for timelines which change the property of a bone.</summary> /// <summary>An interface for timelines which change the property of a bone.</summary>
@ -550,7 +547,7 @@ namespace Spine {
} }
float x, y; float x, y;
int i = Animation.Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES]; int i = Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR:
float before = frames[i]; float before = frames[i];
@ -616,7 +613,7 @@ namespace Spine {
return; return;
case MixBlend.First: case MixBlend.First:
bone.x += (bone.data.x - bone.x) * alpha; bone.x += (bone.data.x - bone.x) * alpha;
break; return;
} }
return; return;
} }
@ -665,7 +662,7 @@ namespace Spine {
return; return;
case MixBlend.First: case MixBlend.First:
bone.y += (bone.data.y - bone.y) * alpha; bone.y += (bone.data.y - bone.y) * alpha;
break; return;
} }
return; return;
} }
@ -724,7 +721,7 @@ namespace Spine {
} }
float x, y; float x, y;
int i = Animation.Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES]; int i = Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR:
float before = frames[i]; float before = frames[i];
@ -834,7 +831,7 @@ namespace Spine {
return; return;
case MixBlend.First: case MixBlend.First:
bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha; bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha;
break; return;
} }
return; return;
} }
@ -913,7 +910,7 @@ namespace Spine {
return; return;
case MixBlend.First: case MixBlend.First:
bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha; bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha;
break; return;
} }
return; return;
} }
@ -1002,7 +999,7 @@ namespace Spine {
} }
float x, y; float x, y;
int i = Animation.Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES]; int i = Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR:
float before = frames[i]; float before = frames[i];
@ -1022,7 +1019,6 @@ namespace Spine {
break; break;
} }
switch (blend) { switch (blend) {
case MixBlend.Setup: case MixBlend.Setup:
bone.shearX = bone.data.shearX + x * alpha; bone.shearX = bone.data.shearX + x * alpha;
@ -1069,7 +1065,7 @@ namespace Spine {
return; return;
case MixBlend.First: case MixBlend.First:
bone.shearX += (bone.data.shearX - bone.shearX) * alpha; bone.shearX += (bone.data.shearX - bone.shearX) * alpha;
break; return;
} }
return; return;
} }
@ -1118,7 +1114,7 @@ namespace Spine {
return; return;
case MixBlend.First: case MixBlend.First:
bone.shearY += (bone.data.shearY - bone.shearY) * alpha; bone.shearY += (bone.data.shearY - bone.shearY) * alpha;
break; return;
} }
return; return;
} }
@ -1201,7 +1197,7 @@ namespace Spine {
} }
float r, g, b, a; float r, g, b, a;
int i = Animation.Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES]; int i = Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR:
float before = frames[i]; float before = frames[i];
@ -1269,6 +1265,7 @@ namespace Spine {
(int)Property.RGB + "|" + slotIndex) { (int)Property.RGB + "|" + slotIndex) {
this.slotIndex = slotIndex; this.slotIndex = slotIndex;
} }
public override int FrameEntries { public override int FrameEntries {
get { return ENTRIES; } get { return ENTRIES; }
} }
@ -1315,7 +1312,7 @@ namespace Spine {
} }
float r, g, b; float r, g, b;
int i = Animation.Search(frames, time, ENTRIES), curveType = (int)curves[i >> 2]; int i = Search(frames, time, ENTRIES), curveType = (int)curves[i >> 2];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR:
float before = frames[i]; float before = frames[i];
@ -1344,16 +1341,14 @@ namespace Spine {
slot.g = g; slot.g = g;
slot.b = b; slot.b = b;
slot.ClampColor(); slot.ClampColor();
} } else {
else {
float br, bg, bb; float br, bg, bb;
if (blend == MixBlend.Setup) { if (blend == MixBlend.Setup) {
var setup = slot.data; var setup = slot.data;
br = setup.r; br = setup.r;
bg = setup.g; bg = setup.g;
bb = setup.b; bb = setup.b;
} } else {
else {
br = slot.r; br = slot.r;
bg = slot.g; bg = slot.g;
bb = slot.b; bb = slot.b;
@ -1402,15 +1397,13 @@ namespace Spine {
} }
float a = GetCurveValue(time); float a = GetCurveValue(time);
if (alpha == 1) { if (alpha == 1)
slot.a = a; slot.a = a;
slot.ClampColor();
}
else { else {
if (blend == MixBlend.Setup) slot.a = slot.data.a; if (blend == MixBlend.Setup) slot.a = slot.data.a;
slot.a += (a - slot.a) * alpha; slot.a += (a - slot.a) * alpha;
slot.ClampColor();
} }
slot.ClampColor();
} }
} }
@ -1469,8 +1462,6 @@ namespace Spine {
var slotData = slot.data; var slotData = slot.data;
switch (blend) { switch (blend) {
case MixBlend.Setup: case MixBlend.Setup:
// slot.color.set(slot.data.color);
// slot.darkColor.set(slot.data.darkColor);
slot.r = slotData.r; slot.r = slotData.r;
slot.g = slotData.g; slot.g = slotData.g;
slot.b = slotData.b; slot.b = slotData.b;
@ -1497,7 +1488,7 @@ namespace Spine {
} }
float r, g, b, a, r2, g2, b2; float r, g, b, a, r2, g2, b2;
int i = Animation.Search(frames, time, ENTRIES), curveType = (int)curves[i >> 3]; int i = Search(frames, time, ENTRIES), curveType = (int)curves[i >> 3];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR:
float before = frames[i]; float before = frames[i];
@ -1658,7 +1649,7 @@ namespace Spine {
} }
float r, g, b, r2, g2, b2; float r, g, b, r2, g2, b2;
int i = Animation.Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES]; int i = Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR:
float before = frames[i]; float before = frames[i];
@ -1703,8 +1694,7 @@ namespace Spine {
slot.g2 = g2; slot.g2 = g2;
slot.b2 = b2; slot.b2 = b2;
slot.ClampSecondColor(); slot.ClampSecondColor();
} } else {
else {
float br, bg, bb, br2, bg2, bb2; float br, bg, bb, br2, bg2, bb2;
if (blend == MixBlend.Setup) { if (blend == MixBlend.Setup) {
br = slot.data.r; br = slot.data.r;
@ -1713,8 +1703,7 @@ namespace Spine {
br2 = slot.data.r2; br2 = slot.data.r2;
bg2 = slot.data.g2; bg2 = slot.data.g2;
bb2 = slot.data.b2; bb2 = slot.data.b2;
} } else {
else {
br = slot.r; br = slot.r;
bg = slot.g; bg = slot.g;
bb = slot.b; bb = slot.b;
@ -1782,7 +1771,7 @@ namespace Spine {
return; return;
} }
SetAttachment(skeleton, slot, attachmentNames[Animation.Search(frames, time)]); SetAttachment(skeleton, slot, attachmentNames[Search(frames, time)]);
} }
private void SetAttachment (Skeleton skeleton, Slot slot, string attachmentName) { private void SetAttachment (Skeleton skeleton, Slot slot, string attachmentName) {
@ -1888,9 +1877,10 @@ namespace Spine {
override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList<Event> firedEvents, float alpha, MixBlend blend, override public void Apply (Skeleton skeleton, float lastTime, float time, ExposedList<Event> firedEvents, float alpha, MixBlend blend,
MixDirection direction) { MixDirection direction) {
Slot slot = skeleton.slots.Items[slotIndex]; Slot slot = skeleton.slots.Items[slotIndex];
if (!slot.bone.active) return; if (!slot.bone.active) return;
VertexAttachment vertexAttachment = slot.attachment as VertexAttachment; var vertexAttachment = slot.attachment as VertexAttachment;
if (vertexAttachment == null || vertexAttachment.DeformAttachment != attachment) return; if (vertexAttachment == null || vertexAttachment.DeformAttachment != attachment) return;
var deformArray = slot.Deform; var deformArray = slot.Deform;
@ -1898,11 +1888,11 @@ namespace Spine {
float[][] vertices = this.vertices; float[][] vertices = this.vertices;
int vertexCount = vertices[0].Length; int vertexCount = vertices[0].Length;
float[] frames = this.frames;
float[] deform; float[] deform;
float[] frames = this.frames;
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:
deformArray.Clear(); deformArray.Clear();
@ -1913,7 +1903,7 @@ namespace Spine {
return; return;
} }
// deformArray.SetSize(vertexCount) // Ensure size and preemptively set count. // Ensure size and preemptively set count.
if (deformArray.Capacity < vertexCount) deformArray.Capacity = vertexCount; if (deformArray.Capacity < vertexCount) deformArray.Capacity = vertexCount;
deformArray.Count = vertexCount; deformArray.Count = vertexCount;
deform = deformArray.Items; deform = deformArray.Items;
@ -1930,19 +1920,16 @@ namespace Spine {
deform[i] *= alpha; deform[i] *= alpha;
} }
return; return;
default: }
return; return;
} }
} // Ensure size and preemptively set count.
// deformArray.SetSize(vertexCount) // Ensure size and preemptively set count.
if (deformArray.Capacity < vertexCount) deformArray.Capacity = vertexCount; if (deformArray.Capacity < vertexCount) deformArray.Capacity = vertexCount;
deformArray.Count = vertexCount; deformArray.Count = vertexCount;
deform = deformArray.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.
float[] lastVertices = vertices[frames.Length - 1]; float[] lastVertices = vertices[frames.Length - 1];
if (alpha == 1) { if (alpha == 1) {
if (blend == MixBlend.Add) { if (blend == MixBlend.Add) {
@ -2000,7 +1987,7 @@ namespace Spine {
return; return;
} }
int frame = Animation.Search(frames, time); int frame = Search(frames, time);
float percent = GetCurvePercent(time, frame); float percent = GetCurvePercent(time, frame);
float[] prevVertices = vertices[frame]; float[] prevVertices = vertices[frame];
float[] nextVertices = vertices[frame + 1]; float[] nextVertices = vertices[frame + 1];
@ -2056,7 +2043,7 @@ namespace Spine {
} }
break; break;
} }
case MixBlend.Add: { case MixBlend.Add:
if (vertexAttachment.bones == null) { if (vertexAttachment.bones == null) {
// Unweighted vertex positions, with alpha. // Unweighted vertex positions, with alpha.
float[] setupVertices = vertexAttachment.vertices; float[] setupVertices = vertexAttachment.vertices;
@ -2076,7 +2063,6 @@ namespace Spine {
} }
} }
} }
}
/// <summary>Fires an <see cref="Event"/> when specific animation times are reached.</summary> /// <summary>Fires an <see cref="Event"/> when specific animation times are reached.</summary>
public class EventTimeline : Timeline { public class EventTimeline : Timeline {
@ -2122,7 +2108,7 @@ namespace Spine {
if (lastTime < frames[0]) if (lastTime < frames[0])
i = 0; i = 0;
else { else {
i = Animation.Search(frames, lastTime) + 1; i = Search(frames, lastTime) + 1;
float frameTime = frames[i]; float frameTime = frames[i];
while (i > 0) { // Fire multiple events with the same frame. while (i > 0) { // Fire multiple events with the same frame.
if (frames[i - 1] != frameTime) break; if (frames[i - 1] != frameTime) break;
@ -2166,23 +2152,23 @@ namespace Spine {
public override void Apply (Skeleton skeleton, float lastTime, float time, ExposedList<Event> firedEvents, float alpha, MixBlend blend, public override void Apply (Skeleton skeleton, float lastTime, float time, ExposedList<Event> firedEvents, float alpha, MixBlend blend,
MixDirection direction) { MixDirection direction) {
var drawOrder = skeleton.drawOrder.Items;
if (direction == MixDirection.Out) { if (direction == MixDirection.Out) {
if (blend == MixBlend.Setup) Array.Copy(skeleton.slots.Items, 0, drawOrder, 0, skeleton.slots.Count); if (blend == MixBlend.Setup) Array.Copy(skeleton.slots.Items, 0, skeleton.drawOrder.Items, 0, skeleton.slots.Count);
return; return;
} }
float[] frames = this.frames; float[] frames = this.frames;
if (time < frames[0]) { // Time is before first frame. if (time < frames[0]) { // Time is before first frame.
if (blend == MixBlend.Setup || blend == MixBlend.First) Array.Copy(skeleton.slots.Items, 0, drawOrder, 0, skeleton.slots.Count); if (blend == MixBlend.Setup || blend == MixBlend.First) Array.Copy(skeleton.slots.Items, 0, skeleton.drawOrder.Items, 0, skeleton.slots.Count);
return; return;
} }
int[] drawOrderToSetupIndex = drawOrders[Animation.Search(frames, time)]; int[] drawOrderToSetupIndex = drawOrders[Search(frames, time)];
if (drawOrderToSetupIndex == null) if (drawOrderToSetupIndex == null)
Array.Copy(skeleton.slots.Items, 0, drawOrder, 0, skeleton.slots.Count); Array.Copy(skeleton.slots.Items, 0, skeleton.drawOrder.Items, 0, skeleton.slots.Count);
else { else {
var slots = skeleton.slots.Items; Slot[] slots = skeleton.slots.Items;
Slot[] drawOrder = skeleton.drawOrder.Items;
for (int i = 0, n = drawOrderToSetupIndex.Length; i < n; i++) for (int i = 0, n = drawOrderToSetupIndex.Length; i < n; i++)
drawOrder[i] = slots[drawOrderToSetupIndex[i]]; drawOrder[i] = slots[drawOrderToSetupIndex[i]];
} }
@ -2258,7 +2244,7 @@ namespace Spine {
} }
float mix, softness; float mix, softness;
int i = Animation.Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES]; int i = Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR:
float before = frames[i]; float before = frames[i];
@ -2285,14 +2271,12 @@ namespace Spine {
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.compress = constraint.data.compress; constraint.compress = constraint.data.compress;
constraint.stretch = constraint.data.stretch; constraint.stretch = constraint.data.stretch;
} } else {
else {
constraint.bendDirection = (int)frames[i + BEND_DIRECTION]; constraint.bendDirection = (int)frames[i + BEND_DIRECTION];
constraint.compress = frames[i + COMPRESS] != 0; constraint.compress = frames[i + COMPRESS] != 0;
constraint.stretch = frames[i + STRETCH] != 0; constraint.stretch = frames[i + STRETCH] != 0;
} }
} } else {
else {
constraint.mix += (mix - constraint.mix) * alpha; constraint.mix += (mix - constraint.mix) * alpha;
constraint.softness += (softness - constraint.softness) * alpha; constraint.softness += (softness - constraint.softness) * alpha;
if (direction == MixDirection.In) { if (direction == MixDirection.In) {
@ -2375,7 +2359,7 @@ namespace Spine {
} }
float rotate, x, y, scaleX, scaleY, shearY; float rotate, x, y, scaleX, scaleY, shearY;
int i = Animation.Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES]; int i = Search(frames, time, ENTRIES), curveType = (int)curves[i / ENTRIES];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR:
float before = frames[i]; float before = frames[i];
@ -2575,7 +2559,7 @@ namespace Spine {
} }
float rotate, x, y; float rotate, x, y;
int i = Animation.Search(frames, time, ENTRIES), curveType = (int)curves[i >> 2]; int i = Search(frames, time, ENTRIES), curveType = (int)curves[i >> 2];
switch (curveType) { switch (curveType) {
case LINEAR: case LINEAR:
float before = frames[i]; float before = frames[i];

View File

@ -134,7 +134,7 @@ namespace Spine {
/// <param name="delta">delta time</param> /// <param name="delta">delta time</param>
public void Update (float delta) { public void Update (float delta) {
delta *= timeScale; delta *= timeScale;
var tracksItems = tracks.Items; TrackEntry[] tracksItems = tracks.Items;
for (int i = 0, n = tracks.Count; i < n; i++) { for (int i = 0, n = tracks.Count; i < n; i++) {
TrackEntry current = tracksItems[i]; TrackEntry current = tracksItems[i];
if (current == null) continue; if (current == null) continue;
@ -225,9 +225,9 @@ namespace Spine {
if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null."); if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null.");
if (animationsChanged) AnimationsChanged(); if (animationsChanged) AnimationsChanged();
var events = this.events; ExposedList<Event> events = this.events;
bool applied = false; bool applied = false;
var tracksItems = tracks.Items; TrackEntry[] tracksItems = tracks.Items;
for (int i = 0, n = tracks.Count; i < n; i++) { for (int i = 0, n = tracks.Count; i < n; i++) {
TrackEntry current = tracksItems[i]; TrackEntry current = tracksItems[i];
if (current == null || current.delay > 0) continue; if (current == null || current.delay > 0) continue;
@ -252,25 +252,24 @@ namespace Spine {
} }
int timelineCount = current.animation.timelines.Count; int timelineCount = current.animation.timelines.Count;
var timelines = current.animation.timelines; Timeline[] timelines = current.animation.timelines.Items;
var timelinesItems = timelines.Items;
if ((i == 0 && mix == 1) || blend == MixBlend.Add) { if ((i == 0 && mix == 1) || blend == MixBlend.Add) {
for (int ii = 0; ii < timelineCount; ii++) { for (int ii = 0; ii < timelineCount; ii++) {
var timeline = timelinesItems[ii]; Timeline timeline = timelines[ii];
if (timeline is AttachmentTimeline) if (timeline is AttachmentTimeline)
ApplyAttachmentTimeline((AttachmentTimeline)timeline, skeleton, applyTime, blend, true); ApplyAttachmentTimeline((AttachmentTimeline)timeline, skeleton, applyTime, blend, true);
else else
timeline.Apply(skeleton, animationLast, applyTime, applyEvents, mix, blend, MixDirection.In); timeline.Apply(skeleton, animationLast, applyTime, applyEvents, mix, blend, MixDirection.In);
} }
} else { } else {
var timelineMode = current.timelineMode.Items; int[] timelineMode = current.timelineMode.Items;
bool firstFrame = current.timelinesRotation.Count != timelineCount << 1; bool firstFrame = current.timelinesRotation.Count != timelineCount << 1;
if (firstFrame) current.timelinesRotation.Resize(timelines.Count << 1); if (firstFrame) current.timelinesRotation.Resize(timelineCount << 1);
var timelinesRotation = current.timelinesRotation.Items; float[] timelinesRotation = current.timelinesRotation.Items;
for (int ii = 0; ii < timelineCount; ii++) { for (int ii = 0; ii < timelineCount; ii++) {
Timeline timeline = timelinesItems[ii]; Timeline timeline = timelines[ii];
MixBlend timelineBlend = timelineMode[ii] == AnimationState.Subsequent ? blend : MixBlend.Setup; MixBlend timelineBlend = timelineMode[ii] == AnimationState.Subsequent ? blend : MixBlend.Setup;
var rotateTimeline = timeline as RotateTimeline; var rotateTimeline = timeline as RotateTimeline;
if (rotateTimeline != null) if (rotateTimeline != null)
@ -292,9 +291,9 @@ namespace Spine {
// subsequent timelines see any deform, but the subsequent timelines don't set an attachment (eg they are also mixing out or // subsequent timelines see any deform, but the subsequent timelines don't set an attachment (eg they are also mixing out or
// the time is before the first key). // the time is before the first key).
int setupState = unkeyedState + Setup; int setupState = unkeyedState + Setup;
var slots = skeleton.slots.Items; Slot[] slots = skeleton.slots.Items;
for (int i = 0, n = skeleton.slots.Count; i < n; i++) { for (int i = 0, n = skeleton.slots.Count; i < n; i++) {
Slot slot = (Slot)slots[i]; Slot slot = slots[i];
if (slot.attachmentState == setupState) { if (slot.attachmentState == setupState) {
string attachmentName = slot.data.attachmentName; string attachmentName = slot.data.attachmentName;
slot.Attachment = (attachmentName == null ? null : skeleton.GetAttachment(slot.data.index, attachmentName)); slot.Attachment = (attachmentName == null ? null : skeleton.GetAttachment(slot.data.index, attachmentName));
@ -311,25 +310,23 @@ namespace Spine {
public bool ApplyEventTimelinesOnly (Skeleton skeleton) { public bool ApplyEventTimelinesOnly (Skeleton skeleton) {
if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null."); if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null.");
var events = this.events; ExposedList<Event> events = this.events;
bool applied = false; bool applied = false;
var tracksItems = tracks.Items; TrackEntry[] tracksItems = tracks.Items;
for (int i = 0, n = tracks.Count; i < n; i++) { for (int i = 0, n = tracks.Count; i < n; i++) {
TrackEntry current = tracksItems[i]; TrackEntry current = tracksItems[i];
if (current == null || current.delay > 0) continue; if (current == null || current.delay > 0) continue;
applied = true; applied = true;
// Apply mixing from entries first. // Apply mixing from entries first.
if (current.mixingFrom != null) if (current.mixingFrom != null) ApplyMixingFromEventTimelinesOnly(current, skeleton);
ApplyMixingFromEventTimelinesOnly(current, skeleton);
// Apply current entry. // Apply current entry.
float animationLast = current.animationLast, animationTime = current.AnimationTime; float animationLast = current.animationLast, animationTime = current.AnimationTime;
int timelineCount = current.animation.timelines.Count; int timelineCount = current.animation.timelines.Count;
var timelines = current.animation.timelines; Timeline[] timelines = current.animation.timelines.Items;
var timelinesItems = timelines.Items;
for (int ii = 0; ii < timelineCount; ii++) { for (int ii = 0; ii < timelineCount; ii++) {
Timeline timeline = timelinesItems[ii]; Timeline timeline = timelines[ii];
if (timeline is EventTimeline) if (timeline is EventTimeline)
timeline.Apply(skeleton, animationLast, animationTime, events, 1.0f, MixBlend.Setup, MixDirection.In); timeline.Apply(skeleton, animationLast, animationTime, events, 1.0f, MixBlend.Setup, MixDirection.In);
} }
@ -358,9 +355,8 @@ namespace Spine {
} }
bool attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold; bool attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold;
var timelines = from.animation.timelines; int timelineCount = from.animation.timelines.Count;
int timelineCount = timelines.Count; Timeline[] timelines = from.animation.timelines.Items;
var timelinesItems = timelines.Items;
float alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix); float alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix);
float animationLast = from.animationLast, animationTime = from.AnimationTime, applyTime = animationTime; float animationLast = from.animationLast, animationTime = from.AnimationTime, applyTime = animationTime;
ExposedList<Event> events = null; ExposedList<Event> events = null;
@ -373,18 +369,18 @@ namespace Spine {
if (blend == MixBlend.Add) { if (blend == MixBlend.Add) {
for (int i = 0; i < timelineCount; i++) for (int i = 0; i < timelineCount; i++)
timelinesItems[i].Apply(skeleton, animationLast, applyTime, events, alphaMix, blend, MixDirection.Out); timelines[i].Apply(skeleton, animationLast, applyTime, events, alphaMix, blend, MixDirection.Out);
} else { } else {
var timelineMode = from.timelineMode.Items; int[] timelineMode = from.timelineMode.Items;
var timelineHoldMix = from.timelineHoldMix.Items; TrackEntry[] timelineHoldMix = from.timelineHoldMix.Items;
bool firstFrame = from.timelinesRotation.Count != timelineCount << 1; bool firstFrame = from.timelinesRotation.Count != timelineCount << 1;
if (firstFrame) from.timelinesRotation.Resize(timelines.Count << 1); // from.timelinesRotation.setSize if (firstFrame) from.timelinesRotation.Resize(timelineCount << 1);
var timelinesRotation = from.timelinesRotation.Items; float[] timelinesRotation = from.timelinesRotation.Items;
from.totalAlpha = 0; from.totalAlpha = 0;
for (int i = 0; i < timelineCount; i++) { for (int i = 0; i < timelineCount; i++) {
Timeline timeline = timelinesItems[i]; Timeline timeline = timelines[i];
MixDirection direction = MixDirection.Out; MixDirection direction = MixDirection.Out;
MixBlend timelineBlend; MixBlend timelineBlend;
float alpha; float alpha;
@ -444,22 +440,19 @@ namespace Spine {
float mix; float mix;
if (to.mixDuration == 0) { // Single frame mix to undo mixingFrom changes. if (to.mixDuration == 0) { // Single frame mix to undo mixingFrom changes.
mix = 1; mix = 1;
} } else {
else {
mix = to.mixTime / to.mixDuration; mix = to.mixTime / to.mixDuration;
if (mix > 1) mix = 1; if (mix > 1) mix = 1;
} }
var eventBuffer = mix < from.eventThreshold ? this.events : null; ExposedList<Event> eventBuffer = mix < from.eventThreshold ? this.events : null;
if (eventBuffer == null) if (eventBuffer == null) return mix;
return mix;
float animationLast = from.animationLast, animationTime = from.AnimationTime; float animationLast = from.animationLast, animationTime = from.AnimationTime;
var timelines = from.animation.timelines; int timelineCount = from.animation.timelines.Count;
int timelineCount = timelines.Count; Timeline[] timelines = from.animation.timelines.Items;
var timelinesItems = timelines.Items;
for (int i = 0; i < timelineCount; i++) { for (int i = 0; i < timelineCount; i++) {
var timeline = timelinesItems[i]; Timeline timeline = timelines[i];
if (timeline is EventTimeline) if (timeline is EventTimeline)
timeline.Apply(skeleton, animationLast, animationTime, eventBuffer, 0, MixBlend.Setup, MixDirection.Out); timeline.Apply(skeleton, animationLast, animationTime, eventBuffer, 0, MixBlend.Setup, MixDirection.Out);
} }
@ -486,10 +479,8 @@ namespace Spine {
if (time < frames[0]) { // Time is before first frame. if (time < frames[0]) { // Time is before first frame.
if (blend == MixBlend.Setup || blend == MixBlend.First) if (blend == MixBlend.Setup || blend == MixBlend.First)
SetAttachment(skeleton, slot, slot.data.attachmentName, attachments); SetAttachment(skeleton, slot, slot.data.attachmentName, attachments);
} } else
else { SetAttachment(skeleton, slot, timeline.AttachmentNames[Timeline.Search(frames, time)], attachments);
SetAttachment(skeleton, slot, timeline.AttachmentNames[Animation.Search(frames, time)], attachments);
}
// If an attachment wasn't set (ie before the first frame or attachments is false), set the setup attachment later. // If an attachment wasn't set (ie before the first frame or attachments is false), set the setup attachment later.
if (slot.attachmentState <= unkeyedState) slot.attachmentState = unkeyedState + Setup; if (slot.attachmentState <= unkeyedState) slot.attachmentState = unkeyedState + Setup;
@ -570,8 +561,7 @@ namespace Spine {
float trackLastWrapped = entry.trackLast % duration; float trackLastWrapped = entry.trackLast % duration;
// Queue events before complete. // Queue events before complete.
var events = this.events; Event[] eventsItems = this.events.Items;
var eventsItems = events.Items;
int i = 0, n = events.Count; int i = 0, n = events.Count;
for (; i < n; i++) { for (; i < n; i++) {
Event e = eventsItems[i]; Event e = eventsItems[i];
@ -698,10 +688,9 @@ namespace Spine {
DisposeNext(current); DisposeNext(current);
current = current.mixingFrom; current = current.mixingFrom;
interrupt = false; // mixingFrom is current again, but don't interrupt it twice. interrupt = false; // mixingFrom is current again, but don't interrupt it twice.
} else { } else
DisposeNext(current); DisposeNext(current);
} }
}
TrackEntry entry = NewTrackEntry(trackIndex, animation, loop, current); TrackEntry entry = NewTrackEntry(trackIndex, animation, loop, current);
SetCurrent(trackIndex, entry, interrupt); SetCurrent(trackIndex, entry, interrupt);
queue.Drain(); queue.Drain();
@ -801,7 +790,7 @@ namespace Spine {
public void SetEmptyAnimations (float mixDuration) { public void SetEmptyAnimations (float mixDuration) {
bool oldDrainDisabled = queue.drainDisabled; bool oldDrainDisabled = queue.drainDisabled;
queue.drainDisabled = true; queue.drainDisabled = true;
var tracksItems = tracks.Items; TrackEntry[] tracksItems = tracks.Items;
for (int i = 0, n = tracks.Count; i < n; i++) { for (int i = 0, n = tracks.Count; i < n; i++) {
TrackEntry current = tracksItems[i]; TrackEntry current = tracksItems[i];
if (current != null) SetEmptyAnimation(current.trackIndex, mixDuration); if (current != null) SetEmptyAnimation(current.trackIndex, mixDuration);
@ -819,7 +808,7 @@ namespace Spine {
/// <summary>Object-pooling version of new TrackEntry. Obtain an unused TrackEntry from the pool and clear/initialize its values.</summary> /// <summary>Object-pooling version of new TrackEntry. Obtain an unused TrackEntry from the pool and clear/initialize its values.</summary>
/// <param name="last">May be null.</param> /// <param name="last">May be null.</param>
private TrackEntry NewTrackEntry (int trackIndex, Animation animation, bool loop, TrackEntry last) { private TrackEntry NewTrackEntry (int trackIndex, Animation animation, bool loop, TrackEntry last) {
TrackEntry entry = trackEntryPool.Obtain(); // Pooling TrackEntry entry = trackEntryPool.Obtain();
entry.trackIndex = trackIndex; entry.trackIndex = trackIndex;
entry.animation = animation; entry.animation = animation;
entry.loop = loop; entry.loop = loop;
@ -837,14 +826,14 @@ namespace Spine {
entry.delay = 0; entry.delay = 0;
entry.trackTime = 0; entry.trackTime = 0;
entry.trackLast = -1; entry.trackLast = -1;
entry.nextTrackLast = -1; // nextTrackLast == -1 signifies a TrackEntry that wasn't applied yet. entry.nextTrackLast = -1;
entry.trackEnd = float.MaxValue; // loop ? float.MaxValue : animation.Duration; entry.trackEnd = float.MaxValue;
entry.timeScale = 1; entry.timeScale = 1;
entry.alpha = 1; entry.alpha = 1;
entry.interruptAlpha = 1; entry.interruptAlpha = 1;
entry.mixTime = 0; entry.mixTime = 0;
entry.mixDuration = (last == null) ? 0 : data.GetMix(last.animation, animation); entry.mixDuration = last == null ? 0 : data.GetMix(last.animation, animation);
return entry; return entry;
} }
@ -864,7 +853,7 @@ namespace Spine {
// Process in the order that animations are applied. // Process in the order that animations are applied.
propertyIds.Clear(); propertyIds.Clear();
int n = tracks.Count; int n = tracks.Count;
var tracksItems = tracks.Items; TrackEntry[] tracksItems = tracks.Items;
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
TrackEntry entry = tracksItems[i]; TrackEntry entry = tracksItems[i];
if (entry == null) continue; if (entry == null) continue;
@ -882,12 +871,12 @@ namespace Spine {
private void ComputeHold (TrackEntry entry) { private void ComputeHold (TrackEntry entry) {
TrackEntry to = entry.mixingTo; TrackEntry to = entry.mixingTo;
var timelines = entry.animation.timelines.Items; Timeline[] timelines = entry.animation.timelines.Items;
int timelinesCount = entry.animation.timelines.Count; int timelinesCount = entry.animation.timelines.Count;
var timelineMode = entry.timelineMode.Resize(timelinesCount).Items; //timelineMode.setSize(timelinesCount); int[] timelineMode = entry.timelineMode.Resize(timelinesCount).Items;
entry.timelineHoldMix.Clear(); entry.timelineHoldMix.Clear();
var timelineHoldMix = entry.timelineHoldMix.Resize(timelinesCount).Items; //timelineHoldMix.setSize(timelinesCount); TrackEntry[] timelineHoldMix = entry.timelineHoldMix.Resize(timelinesCount).Items;
var propertyIds = this.propertyIds; HashSet<string> propertyIds = this.propertyIds;
if (to != null && to.holdPrevious) { if (to != null && to.holdPrevious) {
for (int i = 0; i < timelinesCount; i++) for (int i = 0; i < timelinesCount; i++)
@ -958,7 +947,7 @@ namespace Spine {
override public string ToString () { override public string ToString () {
var buffer = new System.Text.StringBuilder(); var buffer = new System.Text.StringBuilder();
var tracksItems = tracks.Items; TrackEntry[] tracksItems = tracks.Items;
for (int i = 0, n = tracks.Count; i < n; i++) { for (int i = 0, n = tracks.Count; i < n; i++) {
TrackEntry entry = tracksItems[i]; TrackEntry entry = tracksItems[i];
if (entry == null) continue; if (entry == null) continue;
@ -1273,7 +1262,7 @@ namespace Spine {
} }
class EventQueue { class EventQueue {
private readonly List<EventQueueEntry> eventQueueEntries = new List<EventQueueEntry>(); private readonly ExposedList<EventQueueEntry> eventQueueEntries = new ExposedList<EventQueueEntry>();
internal bool drainDisabled; internal bool drainDisabled;
private readonly AnimationState state; private readonly AnimationState state;
@ -1286,22 +1275,6 @@ namespace Spine {
this.trackEntryPool = trackEntryPool; this.trackEntryPool = trackEntryPool;
} }
struct EventQueueEntry {
public EventType type;
public TrackEntry entry;
public Event e;
public EventQueueEntry (EventType eventType, TrackEntry trackEntry, Event e = null) {
this.type = eventType;
this.entry = trackEntry;
this.e = e;
}
}
enum EventType {
Start, Interrupt, End, Dispose, Complete, Event
}
internal void Start (TrackEntry entry) { internal void Start (TrackEntry entry) {
eventQueueEntries.Add(new EventQueueEntry(EventType.Start, entry)); eventQueueEntries.Add(new EventQueueEntry(EventType.Start, entry));
if (AnimationsChanged != null) AnimationsChanged(); if (AnimationsChanged != null) AnimationsChanged();
@ -1333,12 +1306,12 @@ namespace Spine {
if (drainDisabled) return; if (drainDisabled) return;
drainDisabled = true; drainDisabled = true;
var entries = this.eventQueueEntries; EventQueueEntry[] entries = eventQueueEntries.Items;
AnimationState state = this.state; AnimationState state = this.state;
// Don't cache entries.Count so callbacks can queue their own events (eg, call SetAnimation in AnimationState_Complete). // Don't cache eventQueueEntries.Count so callbacks can queue their own events (eg, call SetAnimation in AnimationState_Complete).
for (int i = 0; i < entries.Count; i++) { for (int i = 0; i < eventQueueEntries.Count; i++) {
var queueEntry = entries[i]; EventQueueEntry queueEntry = entries[i];
TrackEntry trackEntry = queueEntry.entry; TrackEntry trackEntry = queueEntry.entry;
switch (queueEntry.type) { switch (queueEntry.type) {
@ -1357,7 +1330,7 @@ namespace Spine {
case EventType.Dispose: case EventType.Dispose:
trackEntry.OnDispose(); trackEntry.OnDispose();
state.OnDispose(trackEntry); state.OnDispose(trackEntry);
trackEntryPool.Free(trackEntry); // Pooling trackEntryPool.Free(trackEntry);
break; break;
case EventType.Complete: case EventType.Complete:
trackEntry.OnComplete(); trackEntry.OnComplete();
@ -1377,9 +1350,25 @@ namespace Spine {
internal void Clear () { internal void Clear () {
eventQueueEntries.Clear(); eventQueueEntries.Clear();
} }
struct EventQueueEntry {
public EventType type;
public TrackEntry entry;
public Event e;
public EventQueueEntry (EventType eventType, TrackEntry trackEntry, Event e = null) {
this.type = eventType;
this.entry = trackEntry;
this.e = e;
}
} }
public class Pool<T> where T : class, new() { enum EventType {
Start, Interrupt, End, Dispose, Complete, Event
}
}
class Pool<T> where T : class, new() {
public readonly int max; public readonly int max;
readonly Stack<T> freeObjects; readonly Stack<T> freeObjects;
@ -1404,19 +1393,6 @@ namespace Spine {
Reset(obj); Reset(obj);
} }
// protected void FreeAll (List<T> objects) {
// if (objects == null) throw new ArgumentNullException("objects", "objects cannot be null.");
// var freeObjects = this.freeObjects;
// int max = this.max;
// for (int i = 0; i < objects.Count; i++) {
// T obj = objects[i];
// if (obj == null) continue;
// if (freeObjects.Count < max) freeObjects.Push(obj);
// Reset(obj);
// }
// Peak = Math.Max(Peak, freeObjects.Count);
// }
public void Clear () { public void Clear () {
freeObjects.Clear(); freeObjects.Clear();
} }
@ -1435,7 +1411,7 @@ namespace Spine {
public static bool AddAll<T> (this HashSet<T> set, T[] addSet) { public static bool AddAll<T> (this HashSet<T> set, T[] addSet) {
bool anyItemAdded = false; bool anyItemAdded = false;
for (int i = 0, n = addSet.Length; i < n; ++i) { for (int i = 0, n = addSet.Length; i < n; ++i) {
var item = addSet[i]; T item = addSet[i];
anyItemAdded |= set.Add(item); anyItemAdded |= set.Add(item);
} }
return anyItemAdded; return anyItemAdded;

View File

@ -78,8 +78,7 @@ namespace Spine {
/// <param name="stride">The number of <paramref name="worldVertices"/> entries between the value pairs written.</param> /// <param name="stride">The number of <paramref name="worldVertices"/> entries between the value pairs written.</param>
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; ExposedList<float> deformArray = slot.deform;
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) {
@ -100,7 +99,7 @@ namespace Spine {
v += n + 1; v += n + 1;
skip += n; skip += n;
} }
var skeletonBones = skeleton.bones.Items; Bone[] skeletonBones = slot.bone.skeleton.bones.Items;
if (deformArray.Count == 0) { if (deformArray.Count == 0) {
for (int w = offset, b = skip * 3; w < count; w += stride) { for (int w = offset, b = skip * 3; w < count; w += stride) {
float wx = 0, wy = 0; float wx = 0, wy = 0;
@ -138,15 +137,13 @@ namespace Spine {
if (bones != null) { if (bones != null) {
attachment.bones = new int[bones.Length]; attachment.bones = new int[bones.Length];
Array.Copy(bones, 0, attachment.bones, 0, bones.Length); Array.Copy(bones, 0, attachment.bones, 0, bones.Length);
} } else
else
attachment.bones = null; attachment.bones = null;
if (vertices != null) { if (vertices != null) {
attachment.vertices = new float[vertices.Length]; attachment.vertices = new float[vertices.Length];
Array.Copy(vertices, 0, attachment.vertices, 0, vertices.Length); Array.Copy(vertices, 0, attachment.vertices, 0, vertices.Length);
} } else
else
attachment.vertices = null; attachment.vertices = null;
attachment.worldVerticesLength = worldVerticesLength; attachment.worldVerticesLength = worldVerticesLength;

View File

@ -198,10 +198,11 @@ namespace Spine {
if (converter == null) if (converter == null)
throw new ArgumentNullException("converter"); throw new ArgumentNullException("converter");
ExposedList<TOutput> u = new ExposedList<TOutput>(Count); ExposedList<TOutput> u = new ExposedList<TOutput>(Count);
for (int i = 0; i < Count; i++)
u.Items[i] = converter(Items[i]);
u.Count = Count; u.Count = Count;
T[] items = Items;
TOutput[] uItems = u.Items;
for (int i = 0; i < Count; i++)
uItems[i] = converter(items[i]);
return u; return u;
} }

View File

@ -293,8 +293,7 @@ namespace Spine {
sx *= a; sx *= a;
if (uniform) sy *= a; if (uniform) sy *= a;
} }
} } else
else
a2 = (float)Math.Acos(cos) * bendDir; a2 = (float)Math.Acos(cos) * bendDir;
a = l1 + l2 * cos; a = l1 + l2 * cos;
b = l2 * (float)Math.Sin(a2); b = l2 * (float)Math.Sin(a2);

View File

@ -150,8 +150,7 @@ namespace Spine {
if (setupLength < PathConstraint.Epsilon) { if (setupLength < PathConstraint.Epsilon) {
if (scale) lengths[i] = 0; if (scale) lengths[i] = 0;
spaces[++i] = spacing; spaces[++i] = spacing;
} } else {
else {
float x = setupLength * bone.a, y = setupLength * bone.c; float x = setupLength * bone.a, y = setupLength * bone.c;
float length = (float)Math.Sqrt(x * x + y * y); float length = (float)Math.Sqrt(x * x + y * y);
if (scale) lengths[i] = length; if (scale) lengths[i] = length;
@ -221,14 +220,13 @@ namespace Spine {
} }
float[] ComputeWorldPositions (PathAttachment path, int spacesCount, bool tangents) { float[] ComputeWorldPositions (PathAttachment path, int spacesCount, bool tangents) {
Slot target = this.target; Slot target = this.target;
float position = this.position; float position = this.position;
float[] spaces = this.spaces.Items, output = this.positions.Resize(spacesCount * 3 + 2).Items, world; float[] spaces = this.spaces.Items, output = this.positions.Resize(spacesCount * 3 + 2).Items, world;
bool closed = path.Closed; bool closed = path.Closed;
int verticesLength = path.WorldVerticesLength, curveCount = verticesLength / 6, prevCurve = NONE; int verticesLength = path.WorldVerticesLength, curveCount = verticesLength / 6, prevCurve = NONE;
float pathLength;
float multiplier; float pathLength, multiplier;
if (!path.ConstantSpeed) { if (!path.ConstantSpeed) {
float[] lengths = path.Lengths; float[] lengths = path.Lengths;
curveCount -= closed ? 1 : 2; curveCount -= closed ? 1 : 2;
@ -236,7 +234,6 @@ namespace Spine {
if (data.positionMode == PositionMode.Percent) position *= pathLength; if (data.positionMode == PositionMode.Percent) position *= pathLength;
//float multiplier;
switch (data.spacingMode) { switch (data.spacingMode) {
case SpacingMode.Percent: case SpacingMode.Percent:
multiplier = pathLength; multiplier = pathLength;
@ -355,7 +352,6 @@ namespace Spine {
if (data.positionMode == PositionMode.Percent) position *= pathLength; if (data.positionMode == PositionMode.Percent) position *= pathLength;
//float multiplier;
switch (data.spacingMode) { switch (data.spacingMode) {
case SpacingMode.Percent: case SpacingMode.Percent:
multiplier = pathLength; multiplier = pathLength;

View File

@ -87,7 +87,7 @@ namespace Spine {
this.data = data; this.data = data;
bones = new ExposedList<Bone>(data.bones.Count); bones = new ExposedList<Bone>(data.bones.Count);
var bonesItems = this.bones.Items; Bone[] bonesItems = this.bones.Items;
foreach (BoneData boneData in data.bones) { foreach (BoneData boneData in data.bones) {
Bone bone; Bone bone;
if (boneData.parent == null) { if (boneData.parent == null) {
@ -131,17 +131,17 @@ namespace Spine {
var updateCache = this.updateCache; var updateCache = this.updateCache;
updateCache.Clear(); updateCache.Clear();
int boneCount = this.bones.Items.Length; int boneCount = this.bones.Count;
var bones = this.bones; Bone[] bones = this.bones.Items;
for (int i = 0; i < boneCount; i++) { for (int i = 0; i < boneCount; i++) {
Bone bone = bones.Items[i]; Bone bone = bones[i];
bone.sorted = bone.data.skinRequired; bone.sorted = bone.data.skinRequired;
bone.active = !bone.sorted; bone.active = !bone.sorted;
} }
if (skin != null) { if (skin != null) {
Object[] skinBones = skin.bones.Items; BoneData[] skinBones = skin.bones.Items;
for (int i = 0, n = skin.bones.Count; i < n; i++) { for (int i = 0, n = skin.bones.Count; i < n; i++) {
Bone bone = (Bone)bones.Items[((BoneData)skinBones[i]).index]; var bone = bones[skinBones[i].index];
do { do {
bone.sorted = false; bone.sorted = false;
bone.active = true; bone.active = true;
@ -151,38 +151,37 @@ namespace Spine {
} }
int ikCount = this.ikConstraints.Count, transformCount = this.transformConstraints.Count, pathCount = this.pathConstraints.Count; int ikCount = this.ikConstraints.Count, transformCount = this.transformConstraints.Count, pathCount = this.pathConstraints.Count;
var ikConstraints = this.ikConstraints; IkConstraint[] ikConstraints = this.ikConstraints.Items;
var transformConstraints = this.transformConstraints; TransformConstraint[] transformConstraints = this.transformConstraints.Items;
var pathConstraints = this.pathConstraints; PathConstraint[] pathConstraints = this.pathConstraints.Items;
int constraintCount = ikCount + transformCount + pathCount; int constraintCount = ikCount + transformCount + pathCount;
//outer:
for (int i = 0; i < constraintCount; i++) { for (int i = 0; i < constraintCount; i++) {
for (int ii = 0; ii < ikCount; ii++) { for (int ii = 0; ii < ikCount; ii++) {
IkConstraint constraint = ikConstraints.Items[ii]; IkConstraint constraint = ikConstraints[ii];
if (constraint.data.order == i) { if (constraint.data.order == i) {
SortIkConstraint(constraint); SortIkConstraint(constraint);
goto continue_outer; //continue outer; goto continue_outer;
} }
} }
for (int ii = 0; ii < transformCount; ii++) { for (int ii = 0; ii < transformCount; ii++) {
TransformConstraint constraint = transformConstraints.Items[ii]; TransformConstraint constraint = transformConstraints[ii];
if (constraint.data.order == i) { if (constraint.data.order == i) {
SortTransformConstraint(constraint); SortTransformConstraint(constraint);
goto continue_outer; //continue outer; goto continue_outer;
} }
} }
for (int ii = 0; ii < pathCount; ii++) { for (int ii = 0; ii < pathCount; ii++) {
PathConstraint constraint = pathConstraints.Items[ii]; PathConstraint constraint = pathConstraints[ii];
if (constraint.data.order == i) { if (constraint.data.order == i) {
SortPathConstraint(constraint); SortPathConstraint(constraint);
goto continue_outer; //continue outer; goto continue_outer;
} }
} }
continue_outer: {} continue_outer: {}
} }
for (int i = 0; i < boneCount; i++) for (int i = 0; i < boneCount; i++)
SortBone(bones.Items[i]); SortBone(bones[i]);
} }
private void SortIkConstraint (IkConstraint constraint) { private void SortIkConstraint (IkConstraint constraint) {
@ -200,8 +199,7 @@ namespace Spine {
if (constrained.Count == 1) { if (constrained.Count == 1) {
updateCache.Add(constraint); updateCache.Add(constraint);
SortReset(parent.children); SortReset(parent.children);
} } else {
else {
Bone child = constrained.Items[constrained.Count - 1]; Bone child = constrained.Items[constrained.Count - 1];
SortBone(child); SortBone(child);
@ -269,10 +267,9 @@ namespace Spine {
} }
private void SortPathConstraintAttachment (Skin skin, int slotIndex, Bone slotBone) { private void SortPathConstraintAttachment (Skin skin, int slotIndex, Bone slotBone) {
foreach (var entry in skin.Attachments) { foreach (var entry in skin.Attachments)
if (entry.SlotIndex == slotIndex) SortPathConstraintAttachment(entry.Attachment, slotBone); if (entry.SlotIndex == slotIndex) SortPathConstraintAttachment(entry.Attachment, slotBone);
} }
}
private void SortPathConstraintAttachment (Attachment attachment, Bone slotBone) { private void SortPathConstraintAttachment (Attachment attachment, Bone slotBone) {
if (!(attachment is PathAttachment)) return; if (!(attachment is PathAttachment)) return;
@ -299,7 +296,7 @@ namespace Spine {
} }
private static void SortReset (ExposedList<Bone> bones) { private static void SortReset (ExposedList<Bone> bones) {
var bonesItems = bones.Items; Bone[] bonesItems = bones.Items;
for (int i = 0, n = bones.Count; i < n; i++) { for (int i = 0, n = bones.Count; i < n; i++) {
Bone bone = bonesItems[i]; Bone bone = bonesItems[i];
if (!bone.active) continue; if (!bone.active) continue;
@ -308,7 +305,6 @@ namespace Spine {
} }
} }
/// <summary> /// <summary>
/// Updates the world transform for each bone and applies all constraints. /// Updates the world transform for each bone and applies all constraints.
/// <para> /// <para>
@ -316,9 +312,9 @@ namespace Spine {
/// Runtimes Guide.</para> /// Runtimes Guide.</para>
/// </summary> /// </summary>
public void UpdateWorldTransform () { public void UpdateWorldTransform () {
Object[] bones = this.bones.Items; Bone[] bones = this.bones.Items;
for (int i = 0, n = this.bones.Count; i < n; i++) { for (int i = 0, n = this.bones.Count; i < n; i++) {
Bone bone = (Bone)bones[i]; Bone bone = bones[i];
bone.ax = bone.x; bone.ax = bone.x;
bone.ay = bone.y; bone.ay = bone.y;
bone.arotation = bone.rotation; bone.arotation = bone.rotation;
@ -360,8 +356,7 @@ namespace Spine {
var updateCache = this.updateCache.Items; var updateCache = this.updateCache.Items;
for (int i = 0, n = this.updateCache.Count; i < n; i++) { for (int i = 0, n = this.updateCache.Count; i < n; i++) {
var updatable = updateCache[i]; var updatable = updateCache[i];
if (updatable != rootBone) if (updatable != rootBone) updatable.Update();
updatable.Update();
} }
} }
@ -380,34 +375,35 @@ namespace Spine {
var ikConstraints = this.ikConstraints.Items; var ikConstraints = this.ikConstraints.Items;
for (int i = 0, n = this.ikConstraints.Count; i < n; i++) { for (int i = 0, n = this.ikConstraints.Count; i < n; i++) {
IkConstraint constraint = ikConstraints[i]; IkConstraint constraint = ikConstraints[i];
constraint.mix = constraint.data.mix; IkConstraintData data = constraint.data;
constraint.softness = constraint.data.softness; constraint.mix = data.mix;
constraint.bendDirection = constraint.data.bendDirection; constraint.softness = data.softness;
constraint.compress = constraint.data.compress; constraint.bendDirection = data.bendDirection;
constraint.stretch = constraint.data.stretch; constraint.compress = data.compress;
constraint.stretch = data.stretch;
} }
var transformConstraints = this.transformConstraints.Items; var transformConstraints = this.transformConstraints.Items;
for (int i = 0, n = this.transformConstraints.Count; i < n; i++) { for (int i = 0, n = this.transformConstraints.Count; i < n; i++) {
TransformConstraint constraint = transformConstraints[i]; TransformConstraint constraint = transformConstraints[i];
TransformConstraintData constraintData = constraint.data; TransformConstraintData data = constraint.data;
constraint.mixRotate = constraintData.mixRotate; constraint.mixRotate = data.mixRotate;
constraint.mixX = constraintData.mixX; constraint.mixX = data.mixX;
constraint.mixY = constraintData.mixY; constraint.mixY = data.mixY;
constraint.mixScaleX = constraintData.mixScaleX; constraint.mixScaleX = data.mixScaleX;
constraint.mixScaleY = constraintData.mixScaleY; constraint.mixScaleY = data.mixScaleY;
constraint.mixShearY = constraintData.mixShearY; constraint.mixShearY = data.mixShearY;
} }
var pathConstraints = this.pathConstraints.Items; var pathConstraints = this.pathConstraints.Items;
for (int i = 0, n = this.pathConstraints.Count; i < n; i++) { for (int i = 0, n = this.pathConstraints.Count; i < n; i++) {
PathConstraint constraint = pathConstraints[i]; PathConstraint constraint = pathConstraints[i];
PathConstraintData constraintData = constraint.data; PathConstraintData data = constraint.data;
constraint.position = constraintData.position; constraint.position = data.position;
constraint.spacing = constraintData.spacing; constraint.spacing = data.spacing;
constraint.mixRotate = constraintData.mixRotate; constraint.mixRotate = data.mixRotate;
constraint.mixX = constraintData.mixX; constraint.mixX = data.mixX;
constraint.mixY = constraintData.mixY; constraint.mixY = data.mixY;
} }
} }
@ -491,9 +487,9 @@ namespace Spine {
if (skin != null) if (skin != null)
newSkin.AttachAll(this, skin); newSkin.AttachAll(this, skin);
else { else {
ExposedList<Slot> slots = this.slots; Slot[] slots = this.slots.Items;
for (int i = 0, n = slots.Count; i < n; i++) { for (int i = 0, n = this.slots.Count; i < n; i++) {
Slot slot = slots.Items[i]; Slot slot = slots[i];
string name = slot.data.attachmentName; string name = slot.data.attachmentName;
if (name != null) { if (name != null) {
Attachment attachment = newSkin.GetAttachment(i, name); Attachment attachment = newSkin.GetAttachment(i, name);
@ -527,9 +523,9 @@ namespace Spine {
/// <param name="attachmentName">May be null to clear the slot's attachment.</param> /// <param name="attachmentName">May be null to clear the slot's attachment.</param>
public void SetAttachment (string slotName, string attachmentName) { public void SetAttachment (string slotName, string attachmentName) {
if (slotName == null) throw new ArgumentNullException("slotName", "slotName cannot be null."); if (slotName == null) throw new ArgumentNullException("slotName", "slotName cannot be null.");
ExposedList<Slot> slots = this.slots; Slot[] slots = this.slots.Items;
for (int i = 0, n = slots.Count; i < n; i++) { for (int i = 0, n = this.slots.Count; i < n; i++) {
Slot slot = slots.Items[i]; Slot slot = slots[i];
if (slot.data.name == slotName) { if (slot.data.name == slotName) {
Attachment attachment = null; Attachment attachment = null;
if (attachmentName != null) { if (attachmentName != null) {

View File

@ -934,8 +934,7 @@ namespace Spine {
if (scale == 1) { if (scale == 1) {
for (int v = start; v < end; v++) for (int v = start; v < end; v++)
deform[v] = input.ReadFloat(); deform[v] = input.ReadFloat();
} } else {
else {
for (int v = start; v < end; v++) for (int v = start; v < end; v++)
deform[v] = input.ReadFloat() * scale; deform[v] = input.ReadFloat() * scale;
} }

View File

@ -64,8 +64,8 @@ namespace Spine {
public void Update (Skeleton skeleton, bool updateAabb) { public void Update (Skeleton skeleton, bool updateAabb) {
ExposedList<BoundingBoxAttachment> boundingBoxes = BoundingBoxes; ExposedList<BoundingBoxAttachment> boundingBoxes = BoundingBoxes;
ExposedList<Polygon> polygons = Polygons; ExposedList<Polygon> polygons = Polygons;
ExposedList<Slot> slots = skeleton.slots; Slot[] slots = skeleton.slots.Items;
int slotCount = slots.Count; int slotCount = skeleton.slots.Count;
boundingBoxes.Clear(); boundingBoxes.Clear();
for (int i = 0, n = polygons.Count; i < n; i++) for (int i = 0, n = polygons.Count; i < n; i++)
@ -73,7 +73,7 @@ namespace Spine {
polygons.Clear(); polygons.Clear();
for (int i = 0; i < slotCount; i++) { for (int i = 0; i < slotCount; i++) {
Slot slot = slots.Items[i]; Slot slot = slots[i];
if (!slot.bone.active) continue; if (!slot.bone.active) continue;
BoundingBoxAttachment boundingBox = slot.attachment as BoundingBoxAttachment; BoundingBoxAttachment boundingBox = slot.attachment as BoundingBoxAttachment;
if (boundingBox == null) continue; if (boundingBox == null) continue;
@ -106,9 +106,9 @@ namespace Spine {
private void AabbCompute () { private void AabbCompute () {
float minX = int.MaxValue, minY = int.MaxValue, maxX = int.MinValue, maxY = int.MinValue; float minX = int.MaxValue, minY = int.MaxValue, maxX = int.MinValue, maxY = int.MinValue;
ExposedList<Polygon> polygons = Polygons; Polygon[] polygons = Polygons.Items;
for (int i = 0, n = polygons.Count; i < n; i++) { for (int i = 0, n = Polygons.Count; i < n; i++) {
Polygon polygon = polygons.Items[i]; Polygon polygon = polygons[i];
float[] vertices = polygon.Vertices; float[] vertices = polygon.Vertices;
for (int ii = 0, nn = polygon.Count; ii < nn; ii += 2) { for (int ii = 0, nn = polygon.Count; ii < nn; ii += 2) {
float x = vertices[ii]; float x = vertices[ii];
@ -178,18 +178,18 @@ namespace Spine {
/// <summary>Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more /// <summary>Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more
/// efficient to only call this method if <see cref="AabbContainsPoint(float, float)"/> returns true.</summary> /// efficient to only call this method if <see cref="AabbContainsPoint(float, float)"/> returns true.</summary>
public BoundingBoxAttachment ContainsPoint (float x, float y) { public BoundingBoxAttachment ContainsPoint (float x, float y) {
ExposedList<Polygon> polygons = Polygons; Polygon[] polygons = Polygons.Items;
for (int i = 0, n = polygons.Count; i < n; i++) for (int i = 0, n = Polygons.Count; i < n; i++)
if (ContainsPoint(polygons.Items[i], x, y)) return BoundingBoxes.Items[i]; if (ContainsPoint(polygons[i], x, y)) return BoundingBoxes.Items[i];
return null; return null;
} }
/// <summary>Returns the first bounding box attachment that contains the line segment, or null. When doing many checks, it is usually /// <summary>Returns the first bounding box attachment that contains the line segment, or null. When doing many checks, it is usually
/// more efficient to only call this method if <see cref="aabbIntersectsSegment(float, float, float, float)"/> returns true.</summary> /// more efficient to only call this method if <see cref="aabbIntersectsSegment(float, float, float, float)"/> returns true.</summary>
public BoundingBoxAttachment IntersectsSegment (float x1, float y1, float x2, float y2) { public BoundingBoxAttachment IntersectsSegment (float x1, float y1, float x2, float y2) {
ExposedList<Polygon> polygons = Polygons; Polygon[] polygons = Polygons.Items;
for (int i = 0, n = polygons.Count; i < n; i++) for (int i = 0, n = Polygons.Count; i < n; i++)
if (IntersectsSegment(polygons.Items[i], x1, y1, x2, y2)) return BoundingBoxes.Items[i]; if (IntersectsSegment(polygons[i], x1, y1, x2, y2)) return BoundingBoxes.Items[i];
return null; return null;
} }

View File

@ -137,8 +137,7 @@ namespace Spine {
s += 3; s += 3;
} }
index += clipOutputCount + 1; index += clipOutputCount + 1;
} } else {
else {
float[] clippedVerticesItems = clippedVertices.Resize(s + 3 * 2).Items; float[] clippedVerticesItems = clippedVertices.Resize(s + 3 * 2).Items;
float[] clippedUVsItems = clippedUVs.Resize(s + 3 * 2).Items; float[] clippedUVsItems = clippedUVs.Resize(s + 3 * 2).Items;
clippedVerticesItems[s] = x1; clippedVerticesItems[s] = x1;
@ -224,8 +223,7 @@ namespace Spine {
output.Add(edgeX); output.Add(edgeX);
output.Add(edgeY); output.Add(edgeY);
} }
} } else if (side2) { // v1 outside, v2 inside
else if (side2) { // v1 outside, v2 inside
float c0 = inputY2 - inputY, c2 = inputX2 - inputX; float c0 = inputY2 - inputY, c2 = inputX2 - inputX;
float s = c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY); float s = c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY);
if (Math.Abs(s) > 0.000001f) { if (Math.Abs(s) > 0.000001f) {
@ -259,12 +257,10 @@ namespace Spine {
if (originalOutput != output) { if (originalOutput != output) {
originalOutput.Clear(); originalOutput.Clear();
for (int i = 0, n = output.Count - 2; i < n; i++) { for (int i = 0, n = output.Count - 2; i < n; i++)
originalOutput.Add(output.Items[i]); originalOutput.Add(output.Items[i]);
} } else
} else {
originalOutput.Resize(originalOutput.Count - 2); originalOutput.Resize(originalOutput.Count - 2);
}
return clipped; return clipped;
} }

View File

@ -136,9 +136,9 @@ namespace Spine {
/// <returns>-1 if the slot was not found.</returns> /// <returns>-1 if the slot was not found.</returns>
public int FindSlotIndex (string slotName) { public int FindSlotIndex (string slotName) {
if (slotName == null) throw new ArgumentNullException("slotName", "slotName cannot be null."); if (slotName == null) throw new ArgumentNullException("slotName", "slotName cannot be null.");
ExposedList<SlotData> slots = this.slots; SlotData[] slots = this.slots.Items;
for (int i = 0, n = slots.Count; i < n; i++) for (int i = 0, n = this.slots.Count; i < n; i++)
if (slots.Items[i].name == slotName) return i; if (slots[i].name == slotName) return i;
return -1; return -1;
} }
@ -217,9 +217,9 @@ namespace Spine {
/// <returns>-1 if the path constraint was not found.</returns> /// <returns>-1 if the path constraint was not found.</returns>
public int FindPathConstraintIndex (string pathConstraintName) { public int FindPathConstraintIndex (string pathConstraintName) {
if (pathConstraintName == null) throw new ArgumentNullException("pathConstraintName", "pathConstraintName cannot be null."); if (pathConstraintName == null) throw new ArgumentNullException("pathConstraintName", "pathConstraintName cannot be null.");
ExposedList<PathConstraintData> pathConstraints = this.pathConstraints; PathConstraintData[] pathConstraints = this.pathConstraints.Items;
for (int i = 0, n = pathConstraints.Count; i < n; i++) for (int i = 0, n = this.pathConstraints.Count; i < n; i++)
if (pathConstraints.Items[i].name.Equals(pathConstraintName)) return i; if (pathConstraints[i].name.Equals(pathConstraintName)) return i;
return -1; return -1;
} }

View File

@ -590,8 +590,7 @@ namespace Spine {
} }
timelines.Add(timeline); timelines.Add(timeline);
} } else if (timelineName == "rgb") {
else if (timelineName == "rgb") {
var timeline = new RGBTimeline(values.Count, values.Count * 3, slotIndex); var timeline = new RGBTimeline(values.Count, values.Count * 3, slotIndex);
var keyMapEnumerator = values.GetEnumerator(); var keyMapEnumerator = values.GetEnumerator();
@ -772,28 +771,23 @@ namespace Spine {
else if (timelineName == "translate") { else if (timelineName == "translate") {
TranslateTimeline timeline = new TranslateTimeline(values.Count, values.Count << 1, boneIndex); TranslateTimeline timeline = new TranslateTimeline(values.Count, values.Count << 1, boneIndex);
timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, "x", "y", 0, scale)); timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, "x", "y", 0, scale));
} } else if (timelineName == "translatex") {
else if (timelineName == "translatex") {
timelines timelines
.Add(ReadTimeline(ref keyMapEnumerator, new TranslateXTimeline(values.Count, values.Count, boneIndex), 0, scale)); .Add(ReadTimeline(ref keyMapEnumerator, new TranslateXTimeline(values.Count, values.Count, boneIndex), 0, scale));
} } else if (timelineName == "translatey") {
else if (timelineName == "translatey") {
timelines timelines
.Add(ReadTimeline(ref keyMapEnumerator, new TranslateYTimeline(values.Count, values.Count, boneIndex), 0, scale)); .Add(ReadTimeline(ref keyMapEnumerator, new TranslateYTimeline(values.Count, values.Count, boneIndex), 0, scale));
} } else if (timelineName == "scale") {
else if (timelineName == "scale") {
ScaleTimeline timeline = new ScaleTimeline(values.Count, values.Count << 1, boneIndex); ScaleTimeline timeline = new ScaleTimeline(values.Count, values.Count << 1, boneIndex);
timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, "x", "y", 1, 1)); timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, "x", "y", 1, 1));
} } else if (timelineName == "scalex")
else if (timelineName == "scalex")
timelines.Add(ReadTimeline(ref keyMapEnumerator, new ScaleXTimeline(values.Count, values.Count, boneIndex), 1, 1)); timelines.Add(ReadTimeline(ref keyMapEnumerator, new ScaleXTimeline(values.Count, values.Count, boneIndex), 1, 1));
else if (timelineName == "scaley") else if (timelineName == "scaley")
timelines.Add(ReadTimeline(ref keyMapEnumerator, new ScaleYTimeline(values.Count, values.Count, boneIndex), 1, 1)); timelines.Add(ReadTimeline(ref keyMapEnumerator, new ScaleYTimeline(values.Count, values.Count, boneIndex), 1, 1));
else if (timelineName == "shear") { else if (timelineName == "shear") {
ShearTimeline timeline = new ShearTimeline(values.Count, values.Count << 1, boneIndex); ShearTimeline timeline = new ShearTimeline(values.Count, values.Count << 1, boneIndex);
timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, "x", "y", 0, 1)); timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, "x", "y", 0, 1));
} } else if (timelineName == "shearx")
else if (timelineName == "shearx")
timelines.Add(ReadTimeline(ref keyMapEnumerator, new ShearXTimeline(values.Count, values.Count, boneIndex), 0, 1)); timelines.Add(ReadTimeline(ref keyMapEnumerator, new ShearXTimeline(values.Count, values.Count, boneIndex), 0, 1));
else if (timelineName == "sheary") else if (timelineName == "sheary")
timelines.Add(ReadTimeline(ref keyMapEnumerator, new ShearYTimeline(values.Count, values.Count, boneIndex), 0, 1)); timelines.Add(ReadTimeline(ref keyMapEnumerator, new ShearYTimeline(values.Count, values.Count, boneIndex), 0, 1));
@ -906,13 +900,11 @@ namespace Spine {
if (timelineName == "position") { if (timelineName == "position") {
CurveTimeline1 timeline = new PathConstraintPositionTimeline(values.Count, values.Count, index); CurveTimeline1 timeline = new PathConstraintPositionTimeline(values.Count, values.Count, index);
timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, 0, data.positionMode == PositionMode.Fixed ? scale : 1)); timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, 0, data.positionMode == PositionMode.Fixed ? scale : 1));
} } else if (timelineName == "spacing") {
else if (timelineName == "spacing") {
CurveTimeline1 timeline = new PathConstraintSpacingTimeline(values.Count, values.Count, index); CurveTimeline1 timeline = new PathConstraintSpacingTimeline(values.Count, values.Count, index);
timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, 0, timelines.Add(ReadTimeline(ref keyMapEnumerator, timeline, 0,
data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed ? scale : 1)); data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed ? scale : 1));
} } else if (timelineName == "mix") {
else if (timelineName == "mix") {
PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(values.Count, values.Count * 3, index); PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(values.Count, values.Count * 3, index);
var keyMap = (Dictionary<string, Object>)keyMapEnumerator.Current; var keyMap = (Dictionary<string, Object>)keyMapEnumerator.Current;
float time = GetFloat(keyMap, "time", 0); float time = GetFloat(keyMap, "time", 0);
@ -1135,8 +1127,7 @@ namespace Spine {
if (curve is string) { if (curve is string) {
if (value != 0) timeline.SetStepped(frame); if (value != 0) timeline.SetStepped(frame);
} } else {
else {
var curveValues = (List<object>)curve; var curveValues = (List<object>)curve;
int index = value << 2; int index = value << 2;
float cx1 = (float)curveValues[index]; float cx1 = (float)curveValues[index];

View File

@ -132,10 +132,11 @@ namespace Spine {
/// <summary>Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached.</summary> /// <summary>Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached.</summary>
internal void AttachAll (Skeleton skeleton, Skin oldSkin) { internal void AttachAll (Skeleton skeleton, Skin oldSkin) {
Slot[] slots = skeleton.slots.Items;
foreach (var item in oldSkin.attachments) { foreach (var item in oldSkin.attachments) {
SkinEntry entry = item.Value; SkinEntry entry = item.Value;
int slotIndex = entry.slotIndex; int slotIndex = entry.slotIndex;
Slot slot = skeleton.slots.Items[slotIndex]; Slot slot = slots[slotIndex];
if (slot.Attachment == entry.attachment) { if (slot.Attachment == entry.attachment) {
Attachment attachment = GetAttachment(slotIndex, entry.name); Attachment attachment = GetAttachment(slotIndex, entry.name);
if (attachment != null) slot.Attachment = attachment; if (attachment != null) slot.Attachment = attachment;

View File

@ -124,15 +124,13 @@ namespace Spine {
public ExposedList<ExposedList<float>> Decompose (ExposedList<float> verticesArray, ExposedList<int> triangles) { public ExposedList<ExposedList<float>> Decompose (ExposedList<float> verticesArray, ExposedList<int> triangles) {
var vertices = verticesArray.Items; var vertices = verticesArray.Items;
var convexPolygons = this.convexPolygons; var convexPolygons = this.convexPolygons;
for (int i = 0, n = convexPolygons.Count; i < n; i++) { for (int i = 0, n = convexPolygons.Count; i < n; i++)
polygonPool.Free(convexPolygons.Items[i]); polygonPool.Free(convexPolygons.Items[i]);
}
convexPolygons.Clear(); convexPolygons.Clear();
var convexPolygonsIndices = this.convexPolygonsIndices; var convexPolygonsIndices = this.convexPolygonsIndices;
for (int i = 0, n = convexPolygonsIndices.Count; i < n; i++) { for (int i = 0, n = convexPolygonsIndices.Count; i < n; i++)
polygonIndicesPool.Free(convexPolygonsIndices.Items[i]); polygonIndicesPool.Free(convexPolygonsIndices.Items[i]);
}
convexPolygonsIndices.Clear(); convexPolygonsIndices.Clear();
var polygonIndices = polygonIndicesPool.Obtain(); var polygonIndices = polygonIndicesPool.Obtain();

View File

@ -1994,22 +1994,23 @@ public class Animation {
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend, public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
MixDirection direction) { MixDirection direction) {
Object[] drawOrder = skeleton.drawOrder.items;
if (direction == out) { if (direction == out) {
if (blend == setup) arraycopy(skeleton.slots.items, 0, drawOrder, 0, skeleton.slots.size); if (blend == setup) arraycopy(skeleton.slots.items, 0, skeleton.drawOrder.items, 0, skeleton.slots.size);
return; return;
} }
if (time < frames[0]) { // Time is before first frame. if (time < frames[0]) { // Time is before first frame.
if (blend == setup || blend == first) arraycopy(skeleton.slots.items, 0, drawOrder, 0, skeleton.slots.size); if (blend == setup || blend == first)
arraycopy(skeleton.slots.items, 0, skeleton.drawOrder.items, 0, skeleton.slots.size);
return; return;
} }
int[] drawOrderToSetupIndex = drawOrders[search(frames, time)]; int[] drawOrderToSetupIndex = drawOrders[search(frames, time)];
if (drawOrderToSetupIndex == null) if (drawOrderToSetupIndex == null)
arraycopy(skeleton.slots.items, 0, drawOrder, 0, skeleton.slots.size); arraycopy(skeleton.slots.items, 0, skeleton.drawOrder.items, 0, skeleton.slots.size);
else { else {
Object[] slots = skeleton.slots.items; Object[] slots = skeleton.slots.items;
Object[] drawOrder = skeleton.drawOrder.items;
for (int i = 0, n = drawOrderToSetupIndex.length; i < n; i++) for (int i = 0, n = drawOrderToSetupIndex.length; i < n; i++)
drawOrder[i] = slots[drawOrderToSetupIndex[i]]; drawOrder[i] = slots[drawOrderToSetupIndex[i]];
} }

View File

@ -66,7 +66,6 @@ abstract public class VertexAttachment extends Attachment {
* @param stride The number of <code>worldVertices</code> entries between the value pairs written. */ * @param stride The number of <code>worldVertices</code> entries between the value pairs written. */
public void computeWorldVertices (Slot slot, int start, int count, float[] worldVertices, int offset, int stride) { public void computeWorldVertices (Slot slot, int start, int count, float[] worldVertices, int offset, int stride) {
count = offset + (count >> 1) * stride; count = offset + (count >> 1) * stride;
Skeleton skeleton = slot.getSkeleton();
FloatArray deformArray = slot.getDeform(); FloatArray deformArray = slot.getDeform();
float[] vertices = this.vertices; float[] vertices = this.vertices;
int[] bones = this.bones; int[] bones = this.bones;
@ -88,7 +87,7 @@ abstract public class VertexAttachment extends Attachment {
v += n + 1; v += n + 1;
skip += n; skip += n;
} }
Object[] skeletonBones = skeleton.getBones().items; Object[] skeletonBones = slot.getSkeleton().getBones().items;
if (deformArray.size == 0) { if (deformArray.size == 0) {
for (int w = offset, b = skip * 3; w < count; w += stride) { for (int w = offset, b = skip * 3; w < count; w += stride) {
float wx = 0, wy = 0; float wx = 0, wy = 0;