[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

File diff suppressed because it is too large Load Diff

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,44 +369,44 @@ 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;
switch (timelineMode[i]) { switch (timelineMode[i]) {
case AnimationState.Subsequent: case AnimationState.Subsequent:
if (!drawOrder && timeline is DrawOrderTimeline) continue; if (!drawOrder && timeline is DrawOrderTimeline) continue;
timelineBlend = blend; timelineBlend = blend;
alpha = alphaMix; alpha = alphaMix;
break; break;
case AnimationState.First: case AnimationState.First:
timelineBlend = MixBlend.Setup; timelineBlend = MixBlend.Setup;
alpha = alphaMix; alpha = alphaMix;
break; break;
case AnimationState.HoldSubsequent: case AnimationState.HoldSubsequent:
timelineBlend = blend; timelineBlend = blend;
alpha = alphaHold; alpha = alphaHold;
break; break;
case AnimationState.HoldFirst: case AnimationState.HoldFirst:
timelineBlend = MixBlend.Setup; timelineBlend = MixBlend.Setup;
alpha = alphaHold; alpha = alphaHold;
break; break;
default: // HoldMix default: // HoldMix
timelineBlend = MixBlend.Setup; timelineBlend = MixBlend.Setup;
TrackEntry holdMix = timelineHoldMix[i]; TrackEntry holdMix = timelineHoldMix[i];
alpha = alphaHold * Math.Max(0, 1 - holdMix.mixTime / holdMix.mixDuration); alpha = alphaHold * Math.Max(0, 1 - holdMix.mixTime / holdMix.mixDuration);
break; break;
} }
from.totalAlpha += alpha; from.totalAlpha += alpha;
var rotateTimeline = timeline as RotateTimeline; var rotateTimeline = timeline as RotateTimeline;
@ -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,9 +688,8 @@ 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);
@ -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;
}
}
enum EventType {
Start, Interrupt, End, Dispose, Complete, Event
}
} }
public class Pool<T> where T : class, new() { 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

@ -174,77 +174,77 @@ namespace Spine {
switch (data.transformMode) { switch (data.transformMode) {
case TransformMode.Normal: { case TransformMode.Normal: {
float rotationY = rotation + 90 + shearY; float rotationY = rotation + 90 + shearY;
float la = MathUtils.CosDeg(rotation + shearX) * scaleX; float la = MathUtils.CosDeg(rotation + shearX) * scaleX;
float lb = MathUtils.CosDeg(rotationY) * scaleY; float lb = MathUtils.CosDeg(rotationY) * scaleY;
float lc = MathUtils.SinDeg(rotation + shearX) * scaleX; float lc = MathUtils.SinDeg(rotation + shearX) * scaleX;
float ld = MathUtils.SinDeg(rotationY) * scaleY; float ld = MathUtils.SinDeg(rotationY) * scaleY;
a = pa * la + pb * lc; a = pa * la + pb * lc;
b = pa * lb + pb * ld; b = pa * lb + pb * ld;
c = pc * la + pd * lc; c = pc * la + pd * lc;
d = pc * lb + pd * ld; d = pc * lb + pd * ld;
return; return;
} }
case TransformMode.OnlyTranslation: { case TransformMode.OnlyTranslation: {
float rotationY = rotation + 90 + shearY; float rotationY = rotation + 90 + shearY;
a = MathUtils.CosDeg(rotation + shearX) * scaleX; a = MathUtils.CosDeg(rotation + shearX) * scaleX;
b = MathUtils.CosDeg(rotationY) * scaleY; b = MathUtils.CosDeg(rotationY) * scaleY;
c = MathUtils.SinDeg(rotation + shearX) * scaleX; c = MathUtils.SinDeg(rotation + shearX) * scaleX;
d = MathUtils.SinDeg(rotationY) * scaleY; d = MathUtils.SinDeg(rotationY) * scaleY;
break; break;
} }
case TransformMode.NoRotationOrReflection: { case TransformMode.NoRotationOrReflection: {
float s = pa * pa + pc * pc, prx; float s = pa * pa + pc * pc, prx;
if (s > 0.0001f) { if (s > 0.0001f) {
s = Math.Abs(pa * pd - pb * pc) / s; s = Math.Abs(pa * pd - pb * pc) / s;
pa /= skeleton.ScaleX; pa /= skeleton.ScaleX;
pc /= skeleton.ScaleY; pc /= skeleton.ScaleY;
pb = pc * s; pb = pc * s;
pd = pa * s; pd = pa * s;
prx = MathUtils.Atan2(pc, pa) * MathUtils.RadDeg; prx = MathUtils.Atan2(pc, pa) * MathUtils.RadDeg;
} else { } else {
pa = 0; pa = 0;
pc = 0; pc = 0;
prx = 90 - MathUtils.Atan2(pd, pb) * MathUtils.RadDeg; prx = 90 - MathUtils.Atan2(pd, pb) * MathUtils.RadDeg;
}
float rx = rotation + shearX - prx;
float ry = rotation + shearY - prx + 90;
float la = MathUtils.CosDeg(rx) * scaleX;
float lb = MathUtils.CosDeg(ry) * scaleY;
float lc = MathUtils.SinDeg(rx) * scaleX;
float ld = MathUtils.SinDeg(ry) * scaleY;
a = pa * la - pb * lc;
b = pa * lb - pb * ld;
c = pc * la + pd * lc;
d = pc * lb + pd * ld;
break;
} }
float rx = rotation + shearX - prx;
float ry = rotation + shearY - prx + 90;
float la = MathUtils.CosDeg(rx) * scaleX;
float lb = MathUtils.CosDeg(ry) * scaleY;
float lc = MathUtils.SinDeg(rx) * scaleX;
float ld = MathUtils.SinDeg(ry) * scaleY;
a = pa * la - pb * lc;
b = pa * lb - pb * ld;
c = pc * la + pd * lc;
d = pc * lb + pd * ld;
break;
}
case TransformMode.NoScale: case TransformMode.NoScale:
case TransformMode.NoScaleOrReflection: { case TransformMode.NoScaleOrReflection: {
float cos = MathUtils.CosDeg(rotation), sin = MathUtils.SinDeg(rotation); float cos = MathUtils.CosDeg(rotation), sin = MathUtils.SinDeg(rotation);
float za = (pa * cos + pb * sin) / skeleton.ScaleX; float za = (pa * cos + pb * sin) / skeleton.ScaleX;
float zc = (pc * cos + pd * sin) / skeleton.ScaleY; float zc = (pc * cos + pd * sin) / skeleton.ScaleY;
float s = (float)Math.Sqrt(za * za + zc * zc); float s = (float)Math.Sqrt(za * za + zc * zc);
if (s > 0.00001f) s = 1 / s; if (s > 0.00001f) s = 1 / s;
za *= s; za *= s;
zc *= s; zc *= s;
s = (float)Math.Sqrt(za * za + zc * zc); s = (float)Math.Sqrt(za * za + zc * zc);
if (data.transformMode == TransformMode.NoScale if (data.transformMode == TransformMode.NoScale
&& (pa * pd - pb * pc < 0) != (skeleton.ScaleX < 0 != skeleton.ScaleY < 0)) s = -s; && (pa * pd - pb * pc < 0) != (skeleton.ScaleX < 0 != skeleton.ScaleY < 0)) s = -s;
float r = MathUtils.PI / 2 + MathUtils.Atan2(zc, za); float r = MathUtils.PI / 2 + MathUtils.Atan2(zc, za);
float zb = MathUtils.Cos(r) * s; float zb = MathUtils.Cos(r) * s;
float zd = MathUtils.Sin(r) * s; float zd = MathUtils.Sin(r) * s;
float la = MathUtils.CosDeg(shearX) * scaleX; float la = MathUtils.CosDeg(shearX) * scaleX;
float lb = MathUtils.CosDeg(90 + shearY) * scaleY; float lb = MathUtils.CosDeg(90 + shearY) * scaleY;
float lc = MathUtils.SinDeg(shearX) * scaleX; float lc = MathUtils.SinDeg(shearX) * scaleX;
float ld = MathUtils.SinDeg(90 + shearY) * scaleY; float ld = MathUtils.SinDeg(90 + shearY) * scaleY;
a = za * la + zb * lc; a = za * la + zb * lc;
b = za * lb + zb * ld; b = za * lb + zb * ld;
c = zc * la + zd * lc; c = zc * la + zd * lc;
d = zc * lb + zd * ld; d = zc * lb + zd * ld;
break; break;
} }
} }
a *= skeleton.ScaleX; a *= skeleton.ScaleX;

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

@ -103,63 +103,62 @@ namespace Spine {
float[] spaces = this.spaces.Resize(spacesCount).Items, lengths = scale ? this.lengths.Resize(boneCount).Items : null; float[] spaces = this.spaces.Resize(spacesCount).Items, lengths = scale ? this.lengths.Resize(boneCount).Items : null;
float spacing = this.spacing; float spacing = this.spacing;
switch (data.spacingMode) { switch (data.spacingMode) {
case SpacingMode.Percent: case SpacingMode.Percent:
if (scale) { if (scale) {
for (int i = 0, n = spacesCount - 1; i < n; i++) { for (int i = 0, n = spacesCount - 1; i < n; i++) {
Bone bone = bonesItems[i];
float setupLength = bone.data.length;
if (setupLength < PathConstraint.Epsilon)
lengths[i] = 0;
else {
float x = setupLength * bone.a, y = setupLength * bone.c;
lengths[i] = (float)Math.Sqrt(x * x + y * y);
}
}
}
ArraysFill(spaces, 1, spacesCount, spacing);
break;
case SpacingMode.Proportional: {
float sum = 0;
for (int i = 0; i < boneCount;) {
Bone bone = bonesItems[i]; Bone bone = bonesItems[i];
float setupLength = bone.data.length; float setupLength = bone.data.length;
if (setupLength < PathConstraint.Epsilon) { if (setupLength < PathConstraint.Epsilon)
if (scale) lengths[i] = 0; lengths[i] = 0;
spaces[++i] = spacing;
} else {
float x = setupLength * bone.a, y = setupLength * bone.c;
float length = (float)Math.Sqrt(x * x + y * y);
if (scale) lengths[i] = length;
spaces[++i] = length;
sum += length;
}
}
if (sum > 0) {
sum = spacesCount / sum * spacing;
for (int i = 1; i < spacesCount; i++)
spaces[i] *= sum;
}
break;
}
default: {
bool lengthSpacing = data.spacingMode == SpacingMode.Length;
for (int i = 0, n = spacesCount - 1; i < n;) {
Bone bone = bonesItems[i];
float setupLength = bone.data.length;
if (setupLength < PathConstraint.Epsilon) {
if (scale) lengths[i] = 0;
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); lengths[i] = (float)Math.Sqrt(x * x + y * y);
if (scale) lengths[i] = length;
spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength;
} }
} }
break;
} }
ArraysFill(spaces, 1, spacesCount, spacing);
break;
case SpacingMode.Proportional: {
float sum = 0;
for (int i = 0; i < boneCount;) {
Bone bone = bonesItems[i];
float setupLength = bone.data.length;
if (setupLength < PathConstraint.Epsilon) {
if (scale) lengths[i] = 0;
spaces[++i] = spacing;
} else {
float x = setupLength * bone.a, y = setupLength * bone.c;
float length = (float)Math.Sqrt(x * x + y * y);
if (scale) lengths[i] = length;
spaces[++i] = length;
sum += length;
}
}
if (sum > 0) {
sum = spacesCount / sum * spacing;
for (int i = 1; i < spacesCount; i++)
spaces[i] *= sum;
}
break;
}
default: {
bool lengthSpacing = data.spacingMode == SpacingMode.Length;
for (int i = 0, n = spacesCount - 1; i < n;) {
Bone bone = bonesItems[i];
float setupLength = bone.data.length;
if (setupLength < PathConstraint.Epsilon) {
if (scale) lengths[i] = 0;
spaces[++i] = spacing;
} else {
float x = setupLength * bone.a, y = setupLength * bone.c;
float length = (float)Math.Sqrt(x * x + y * y);
if (scale) lengths[i] = length;
spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength;
}
}
break;
}
} }
float[] positions = ComputeWorldPositions(attachment, spacesCount, tangents); float[] positions = ComputeWorldPositions(attachment, spacesCount, tangents);
@ -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,17 +234,16 @@ 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;
break; break;
case SpacingMode.Proportional: case SpacingMode.Proportional:
multiplier = pathLength / spacesCount; multiplier = pathLength / spacesCount;
break; break;
default: default:
multiplier = 1; multiplier = 1;
break; break;
} }
world = this.world.Resize(8).Items; world = this.world.Resize(8).Items;
@ -355,17 +352,16 @@ 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;
break; break;
case SpacingMode.Proportional: case SpacingMode.Proportional:
multiplier = pathLength / spacesCount; multiplier = pathLength / spacesCount;
break; break;
default: default:
multiplier = 1; multiplier = 1;
break; break;
} }
float[] segments = this.segments; float[] segments = this.segments;

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,9 +267,8 @@ 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) {
@ -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

@ -376,162 +376,162 @@ namespace Spine {
switch ((AttachmentType)input.ReadByte()) { switch ((AttachmentType)input.ReadByte()) {
case AttachmentType.Region: { case AttachmentType.Region: {
String path = input.ReadStringRef(); String path = input.ReadStringRef();
float rotation = input.ReadFloat(); float rotation = input.ReadFloat();
float x = input.ReadFloat(); float x = input.ReadFloat();
float y = input.ReadFloat(); float y = input.ReadFloat();
float scaleX = input.ReadFloat(); float scaleX = input.ReadFloat();
float scaleY = input.ReadFloat(); float scaleY = input.ReadFloat();
float width = input.ReadFloat(); float width = input.ReadFloat();
float height = input.ReadFloat(); float height = input.ReadFloat();
int color = input.ReadInt(); int color = input.ReadInt();
if (path == null) path = name; if (path == null) path = name;
RegionAttachment region = attachmentLoader.NewRegionAttachment(skin, name, path); RegionAttachment region = attachmentLoader.NewRegionAttachment(skin, name, path);
if (region == null) return null; if (region == null) return null;
region.Path = path; region.Path = path;
region.x = x * scale; region.x = x * scale;
region.y = y * scale; region.y = y * scale;
region.scaleX = scaleX; region.scaleX = scaleX;
region.scaleY = scaleY; region.scaleY = scaleY;
region.rotation = rotation; region.rotation = rotation;
region.width = width * scale; region.width = width * scale;
region.height = height * scale; region.height = height * scale;
region.r = ((color & 0xff000000) >> 24) / 255f; region.r = ((color & 0xff000000) >> 24) / 255f;
region.g = ((color & 0x00ff0000) >> 16) / 255f; region.g = ((color & 0x00ff0000) >> 16) / 255f;
region.b = ((color & 0x0000ff00) >> 8) / 255f; region.b = ((color & 0x0000ff00) >> 8) / 255f;
region.a = ((color & 0x000000ff)) / 255f; region.a = ((color & 0x000000ff)) / 255f;
region.UpdateOffset(); region.UpdateOffset();
return region; return region;
} }
case AttachmentType.Boundingbox: { case AttachmentType.Boundingbox: {
int vertexCount = input.ReadInt(true); int vertexCount = input.ReadInt(true);
Vertices vertices = ReadVertices(input, vertexCount); Vertices vertices = ReadVertices(input, vertexCount);
if (nonessential) input.ReadInt(); //int color = nonessential ? input.ReadInt() : 0; // Avoid unused local warning. if (nonessential) input.ReadInt(); //int color = nonessential ? input.ReadInt() : 0; // Avoid unused local warning.
BoundingBoxAttachment box = attachmentLoader.NewBoundingBoxAttachment(skin, name); BoundingBoxAttachment box = attachmentLoader.NewBoundingBoxAttachment(skin, name);
if (box == null) return null; if (box == null) return null;
box.worldVerticesLength = vertexCount << 1; box.worldVerticesLength = vertexCount << 1;
box.vertices = vertices.vertices; box.vertices = vertices.vertices;
box.bones = vertices.bones; box.bones = vertices.bones;
// skipped porting: if (nonessential) Color.rgba8888ToColor(box.getColor(), color); // skipped porting: if (nonessential) Color.rgba8888ToColor(box.getColor(), color);
return box; return box;
} }
case AttachmentType.Mesh: { case AttachmentType.Mesh: {
String path = input.ReadStringRef(); String path = input.ReadStringRef();
int color = input.ReadInt(); int color = input.ReadInt();
int vertexCount = input.ReadInt(true); int vertexCount = input.ReadInt(true);
float[] uvs = ReadFloatArray(input, vertexCount << 1, 1); float[] uvs = ReadFloatArray(input, vertexCount << 1, 1);
int[] triangles = ReadShortArray(input); int[] triangles = ReadShortArray(input);
Vertices vertices = ReadVertices(input, vertexCount); Vertices vertices = ReadVertices(input, vertexCount);
int hullLength = input.ReadInt(true); int hullLength = input.ReadInt(true);
int[] edges = null; int[] edges = null;
float width = 0, height = 0; float width = 0, height = 0;
if (nonessential) { if (nonessential) {
edges = ReadShortArray(input); edges = ReadShortArray(input);
width = input.ReadFloat(); width = input.ReadFloat();
height = input.ReadFloat(); height = input.ReadFloat();
}
if (path == null) path = name;
MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path);
if (mesh == null) return null;
mesh.Path = path;
mesh.r = ((color & 0xff000000) >> 24) / 255f;
mesh.g = ((color & 0x00ff0000) >> 16) / 255f;
mesh.b = ((color & 0x0000ff00) >> 8) / 255f;
mesh.a = ((color & 0x000000ff)) / 255f;
mesh.bones = vertices.bones;
mesh.vertices = vertices.vertices;
mesh.WorldVerticesLength = vertexCount << 1;
mesh.triangles = triangles;
mesh.regionUVs = uvs;
mesh.UpdateUVs();
mesh.HullLength = hullLength << 1;
if (nonessential) {
mesh.Edges = edges;
mesh.Width = width * scale;
mesh.Height = height * scale;
}
return mesh;
} }
if (path == null) path = name;
MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path);
if (mesh == null) return null;
mesh.Path = path;
mesh.r = ((color & 0xff000000) >> 24) / 255f;
mesh.g = ((color & 0x00ff0000) >> 16) / 255f;
mesh.b = ((color & 0x0000ff00) >> 8) / 255f;
mesh.a = ((color & 0x000000ff)) / 255f;
mesh.bones = vertices.bones;
mesh.vertices = vertices.vertices;
mesh.WorldVerticesLength = vertexCount << 1;
mesh.triangles = triangles;
mesh.regionUVs = uvs;
mesh.UpdateUVs();
mesh.HullLength = hullLength << 1;
if (nonessential) {
mesh.Edges = edges;
mesh.Width = width * scale;
mesh.Height = height * scale;
}
return mesh;
}
case AttachmentType.Linkedmesh: { case AttachmentType.Linkedmesh: {
String path = input.ReadStringRef(); String path = input.ReadStringRef();
int color = input.ReadInt(); int color = input.ReadInt();
String skinName = input.ReadStringRef(); String skinName = input.ReadStringRef();
String parent = input.ReadStringRef(); String parent = input.ReadStringRef();
bool inheritDeform = input.ReadBoolean(); bool inheritDeform = input.ReadBoolean();
float width = 0, height = 0; float width = 0, height = 0;
if (nonessential) { if (nonessential) {
width = input.ReadFloat(); width = input.ReadFloat();
height = input.ReadFloat(); height = input.ReadFloat();
}
if (path == null) path = name;
MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path);
if (mesh == null) return null;
mesh.Path = path;
mesh.r = ((color & 0xff000000) >> 24) / 255f;
mesh.g = ((color & 0x00ff0000) >> 16) / 255f;
mesh.b = ((color & 0x0000ff00) >> 8) / 255f;
mesh.a = ((color & 0x000000ff)) / 255f;
if (nonessential) {
mesh.Width = width * scale;
mesh.Height = height * scale;
}
linkedMeshes.Add(new SkeletonJson.LinkedMesh(mesh, skinName, slotIndex, parent, inheritDeform));
return mesh;
} }
if (path == null) path = name;
MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path);
if (mesh == null) return null;
mesh.Path = path;
mesh.r = ((color & 0xff000000) >> 24) / 255f;
mesh.g = ((color & 0x00ff0000) >> 16) / 255f;
mesh.b = ((color & 0x0000ff00) >> 8) / 255f;
mesh.a = ((color & 0x000000ff)) / 255f;
if (nonessential) {
mesh.Width = width * scale;
mesh.Height = height * scale;
}
linkedMeshes.Add(new SkeletonJson.LinkedMesh(mesh, skinName, slotIndex, parent, inheritDeform));
return mesh;
}
case AttachmentType.Path: { case AttachmentType.Path: {
bool closed = input.ReadBoolean(); bool closed = input.ReadBoolean();
bool constantSpeed = input.ReadBoolean(); bool constantSpeed = input.ReadBoolean();
int vertexCount = input.ReadInt(true); int vertexCount = input.ReadInt(true);
Vertices vertices = ReadVertices(input, vertexCount); Vertices vertices = ReadVertices(input, vertexCount);
float[] lengths = new float[vertexCount / 3]; float[] lengths = new float[vertexCount / 3];
for (int i = 0, n = lengths.Length; i < n; i++) for (int i = 0, n = lengths.Length; i < n; i++)
lengths[i] = input.ReadFloat() * scale; lengths[i] = input.ReadFloat() * scale;
if (nonessential) input.ReadInt(); //int color = nonessential ? input.ReadInt() : 0; if (nonessential) input.ReadInt(); //int color = nonessential ? input.ReadInt() : 0;
PathAttachment path = attachmentLoader.NewPathAttachment(skin, name); PathAttachment path = attachmentLoader.NewPathAttachment(skin, name);
if (path == null) return null; if (path == null) return null;
path.closed = closed; path.closed = closed;
path.constantSpeed = constantSpeed; path.constantSpeed = constantSpeed;
path.worldVerticesLength = vertexCount << 1; path.worldVerticesLength = vertexCount << 1;
path.vertices = vertices.vertices; path.vertices = vertices.vertices;
path.bones = vertices.bones; path.bones = vertices.bones;
path.lengths = lengths; path.lengths = lengths;
// skipped porting: if (nonessential) Color.rgba8888ToColor(path.getColor(), color); // skipped porting: if (nonessential) Color.rgba8888ToColor(path.getColor(), color);
return path; return path;
} }
case AttachmentType.Point: { case AttachmentType.Point: {
float rotation = input.ReadFloat(); float rotation = input.ReadFloat();
float x = input.ReadFloat(); float x = input.ReadFloat();
float y = input.ReadFloat(); float y = input.ReadFloat();
if (nonessential) input.ReadInt(); //int color = nonessential ? input.ReadInt() : 0; if (nonessential) input.ReadInt(); //int color = nonessential ? input.ReadInt() : 0;
PointAttachment point = attachmentLoader.NewPointAttachment(skin, name); PointAttachment point = attachmentLoader.NewPointAttachment(skin, name);
if (point == null) return null; if (point == null) return null;
point.x = x * scale; point.x = x * scale;
point.y = y * scale; point.y = y * scale;
point.rotation = rotation; point.rotation = rotation;
// skipped porting: if (nonessential) point.color = color; // skipped porting: if (nonessential) point.color = color;
return point; return point;
} }
case AttachmentType.Clipping: { case AttachmentType.Clipping: {
int endSlotIndex = input.ReadInt(true); int endSlotIndex = input.ReadInt(true);
int vertexCount = input.ReadInt(true); int vertexCount = input.ReadInt(true);
Vertices vertices = ReadVertices(input, vertexCount); Vertices vertices = ReadVertices(input, vertexCount);
if (nonessential) input.ReadInt(); if (nonessential) input.ReadInt();
ClippingAttachment clip = attachmentLoader.NewClippingAttachment(skin, name); ClippingAttachment clip = attachmentLoader.NewClippingAttachment(skin, name);
if (clip == null) return null; if (clip == null) return null;
clip.EndSlot = skeletonData.slots.Items[endSlotIndex]; clip.EndSlot = skeletonData.slots.Items[endSlotIndex];
clip.worldVerticesLength = vertexCount << 1; clip.worldVerticesLength = vertexCount << 1;
clip.vertices = vertices.vertices; clip.vertices = vertices.vertices;
clip.bones = vertices.bones; clip.bones = vertices.bones;
// skipped porting: if (nonessential) Color.rgba8888ToColor(clip.getColor(), color); // skipped porting: if (nonessential) Color.rgba8888ToColor(clip.getColor(), color);
return clip; return clip;
} }
} }
return null; return null;
} }
@ -865,42 +865,42 @@ namespace Spine {
PathConstraintData data = skeletonData.pathConstraints.Items[index]; PathConstraintData data = skeletonData.pathConstraints.Items[index];
for (int ii = 0, nn = input.ReadInt(true); ii < nn; ii++) { for (int ii = 0, nn = input.ReadInt(true); ii < nn; ii++) {
switch (input.ReadByte()) { switch (input.ReadByte()) {
case PATH_POSITION: case PATH_POSITION:
timelines timelines
.Add(ReadTimeline(input, new PathConstraintPositionTimeline(input.ReadInt(true), input.ReadInt(true), index), .Add(ReadTimeline(input, new PathConstraintPositionTimeline(input.ReadInt(true), input.ReadInt(true), index),
data.positionMode == PositionMode.Fixed ? scale : 1)); data.positionMode == PositionMode.Fixed ? scale : 1));
break; break;
case PATH_SPACING: case PATH_SPACING:
timelines timelines
.Add(ReadTimeline(input, new PathConstraintSpacingTimeline(input.ReadInt(true), input.ReadInt(true), index), .Add(ReadTimeline(input, new PathConstraintSpacingTimeline(input.ReadInt(true), input.ReadInt(true), index),
data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed ? scale : 1)); data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed ? scale : 1));
break; break;
case PATH_MIX: case PATH_MIX:
PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(input.ReadInt(true), input.ReadInt(true), PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(input.ReadInt(true), input.ReadInt(true),
index); index);
float time = input.ReadFloat(), mixRotate = input.ReadFloat(), mixX = input.ReadFloat(), mixY = input.ReadFloat(); float time = input.ReadFloat(), mixRotate = input.ReadFloat(), mixX = input.ReadFloat(), mixY = input.ReadFloat();
for (int frame = 0, bezier = 0, frameLast = timeline.FrameCount - 1; ; frame++) { for (int frame = 0, bezier = 0, frameLast = timeline.FrameCount - 1; ; frame++) {
timeline.SetFrame(frame, time, mixRotate, mixX, mixY); timeline.SetFrame(frame, time, mixRotate, mixX, mixY);
if (frame == frameLast) break; if (frame == frameLast) break;
float time2 = input.ReadFloat(), mixRotate2 = input.ReadFloat(), mixX2 = input.ReadFloat(), float time2 = input.ReadFloat(), mixRotate2 = input.ReadFloat(), mixX2 = input.ReadFloat(),
mixY2 = input.ReadFloat(); mixY2 = input.ReadFloat();
switch (input.ReadByte()) { switch (input.ReadByte()) {
case CURVE_STEPPED: case CURVE_STEPPED:
timeline.SetStepped(frame); timeline.SetStepped(frame);
break; break;
case CURVE_BEZIER: case CURVE_BEZIER:
SetBezier(input, timeline, bezier++, frame, 0, time, time2, mixRotate, mixRotate2, 1); SetBezier(input, timeline, bezier++, frame, 0, time, time2, mixRotate, mixRotate2, 1);
SetBezier(input, timeline, bezier++, frame, 1, time, time2, mixX, mixX2, 1); SetBezier(input, timeline, bezier++, frame, 1, time, time2, mixX, mixX2, 1);
SetBezier(input, timeline, bezier++, frame, 2, time, time2, mixY, mixY2, 1); SetBezier(input, timeline, bezier++, frame, 2, time, time2, mixY, mixY2, 1);
break; break;
}
time = time2;
mixRotate = mixRotate2;
mixX = mixX2;
mixY = mixY2;
} }
timelines.Add(timeline); time = time2;
break; mixRotate = mixRotate2;
mixX = mixX2;
mixY = mixY2;
}
timelines.Add(timeline);
break;
} }
} }
} }
@ -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;
} }
@ -948,12 +947,12 @@ namespace Spine {
if (frame == frameLast) break; if (frame == frameLast) break;
float time2 = input.ReadFloat(); float time2 = input.ReadFloat();
switch (input.ReadByte()) { switch (input.ReadByte()) {
case CURVE_STEPPED: case CURVE_STEPPED:
timeline.SetStepped(frame); timeline.SetStepped(frame);
break; break;
case CURVE_BEZIER: case CURVE_BEZIER:
SetBezier(input, timeline, bezier++, frame, 0, time, time2, 0, 1, 1); SetBezier(input, timeline, bezier++, frame, 0, time, time2, 0, 1, 1);
break; break;
} }
time = time2; time = time2;
} }

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;