Don't use properties internally.

Mono is slower using properties.
This commit is contained in:
NathanSweet 2013-09-23 20:25:15 +02:00
parent 04ba16e221
commit 60ac4d7533
15 changed files with 492 additions and 454 deletions

View File

@ -36,16 +36,20 @@ using System.Collections.Generic;
namespace Spine { namespace Spine {
public class Animation { public class Animation {
public String Name { get; private set; } internal List<Timeline> timelines;
public List<Timeline> Timelines { get; set; } internal float duration;
public float Duration { get; set; } internal String name;
public String Name { get { return name; } }
public List<Timeline> Timelines { get { return timelines; } set { timelines = value; } }
public float Duration { get { return duration; } set { duration = value; } }
public Animation (String name, List<Timeline> timelines, float duration) { public Animation (String name, List<Timeline> timelines, float duration) {
if (name == null) throw new ArgumentNullException("name cannot be null."); if (name == null) throw new ArgumentNullException("name cannot be null.");
if (timelines == null) throw new ArgumentNullException("timelines cannot be null."); if (timelines == null) throw new ArgumentNullException("timelines cannot be null.");
Name = name; this.name = name;
Timelines = timelines; this.timelines = timelines;
Duration = duration; this.duration = duration;
} }
/** @deprecated */ /** @deprecated */
@ -59,12 +63,12 @@ namespace Spine {
public void Apply (Skeleton skeleton, float lastTime, float time, bool loop, List<Event> events) { public void Apply (Skeleton skeleton, float lastTime, float time, bool loop, List<Event> events) {
if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null."); if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null.");
if (loop && Duration != 0) { if (loop && duration != 0) {
time %= Duration; time %= duration;
lastTime %= Duration; lastTime %= duration;
} }
List<Timeline> timelines = Timelines; List<Timeline> timelines = this.timelines;
for (int i = 0, n = timelines.Count; i < n; i++) for (int i = 0, n = timelines.Count; i < n; i++)
timelines[i].Apply(skeleton, lastTime, time, 1, events); timelines[i].Apply(skeleton, lastTime, time, 1, events);
} }
@ -81,12 +85,12 @@ namespace Spine {
public void Mix (Skeleton skeleton, float lastTime, float time, bool loop, List<Event> events, float alpha) { public void Mix (Skeleton skeleton, float lastTime, float time, bool loop, List<Event> events, float alpha) {
if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null."); if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null.");
if (loop && Duration != 0) { if (loop && duration != 0) {
time %= Duration; time %= duration;
lastTime %= Duration; lastTime %= duration;
} }
List<Timeline> timelines = Timelines; List<Timeline> timelines = this.timelines;
for (int i = 0, n = timelines.Count; i < n; i++) for (int i = 0, n = timelines.Count; i < n; i++)
timelines[i].Apply(skeleton, lastTime, time, alpha, events); timelines[i].Apply(skeleton, lastTime, time, alpha, events);
} }
@ -126,11 +130,7 @@ namespace Spine {
static protected int BEZIER_SEGMENTS = 10; static protected int BEZIER_SEGMENTS = 10;
private float[] curves; // dfx, dfy, ddfx, ddfy, dddfx, dddfy, ... private float[] curves; // dfx, dfy, ddfx, ddfy, dddfx, dddfy, ...
public int FrameCount { public int FrameCount { get { return curves.Length / 6 + 1; } }
get {
return curves.Length / 6 + 1;
}
}
public CurveTimeline (int frameCount) { public CurveTimeline (int frameCount) {
curves = new float[(frameCount - 1) * 6]; curves = new float[(frameCount - 1) * 6];
@ -207,36 +207,39 @@ namespace Spine {
static protected int LAST_FRAME_TIME = -2; static protected int LAST_FRAME_TIME = -2;
static protected int FRAME_VALUE = 1; static protected int FRAME_VALUE = 1;
public int BoneIndex { get; set; } internal int boneIndex;
public float[] Frames { get; private set; } // time, value, ... internal float[] frames;
public int BoneIndex { get { return boneIndex; } set { boneIndex = value; } }
public float[] Frames { get { return frames; } set { frames = value; } } // time, value, ...
public RotateTimeline (int frameCount) public RotateTimeline (int frameCount)
: base(frameCount) { : base(frameCount) {
Frames = new float[frameCount * 2]; frames = new float[frameCount * 2];
} }
/** Sets the time and value of the specified keyframe. */ /** Sets the time and value of the specified keyframe. */
public void SetFrame (int frameIndex, float time, float angle) { public void SetFrame (int frameIndex, float time, float angle) {
frameIndex *= 2; frameIndex *= 2;
Frames[frameIndex] = time; frames[frameIndex] = time;
Frames[frameIndex + 1] = angle; frames[frameIndex + 1] = angle;
} }
override public void Apply (Skeleton skeleton, float lastTime, float time, float alpha, List<Event> firedEvents) { override public void Apply (Skeleton skeleton, float lastTime, float time, float alpha, List<Event> firedEvents) {
float[] frames = Frames; float[] frames = this.frames;
if (time < frames[0]) return; // Time is before first frame. if (time < frames[0]) return; // Time is before first frame.
Bone bone = skeleton.Bones[BoneIndex]; Bone bone = skeleton.bones[boneIndex];
float amount; float amount;
if (time >= frames[frames.Length - 2]) { // Time is after last frame. if (time >= frames[frames.Length - 2]) { // Time is after last frame.
amount = bone.Data.Rotation + frames[frames.Length - 1] - bone.Rotation; amount = bone.data.rotation + frames[frames.Length - 1] - bone.rotation;
while (amount > 180) while (amount > 180)
amount -= 360; amount -= 360;
while (amount < -180) while (amount < -180)
amount += 360; amount += 360;
bone.Rotation += amount * alpha; bone.rotation += amount * alpha;
return; return;
} }
@ -252,12 +255,12 @@ namespace Spine {
amount -= 360; amount -= 360;
while (amount < -180) while (amount < -180)
amount += 360; amount += 360;
amount = bone.Data.Rotation + (lastFrameValue + amount * percent) - bone.Rotation; amount = bone.data.rotation + (lastFrameValue + amount * percent) - bone.rotation;
while (amount > 180) while (amount > 180)
amount -= 360; amount -= 360;
while (amount < -180) while (amount < -180)
amount += 360; amount += 360;
bone.Rotation += amount * alpha; bone.rotation += amount * alpha;
} }
} }
@ -266,31 +269,34 @@ namespace Spine {
static protected int FRAME_X = 1; static protected int FRAME_X = 1;
static protected int FRAME_Y = 2; static protected int FRAME_Y = 2;
public int BoneIndex { get; set; } internal int boneIndex;
public float[] Frames { get; private set; } // time, value, value, ... internal float[] frames;
public int BoneIndex { get { return boneIndex; } set { boneIndex = value; } }
public float[] Frames { get { return frames; } set { frames = value; } } // time, value, value, ...
public TranslateTimeline (int frameCount) public TranslateTimeline (int frameCount)
: base(frameCount) { : base(frameCount) {
Frames = new float[frameCount * 3]; frames = new float[frameCount * 3];
} }
/** Sets the time and value of the specified keyframe. */ /** Sets the time and value of the specified keyframe. */
public void SetFrame (int frameIndex, float time, float x, float y) { public void SetFrame (int frameIndex, float time, float x, float y) {
frameIndex *= 3; frameIndex *= 3;
Frames[frameIndex] = time; frames[frameIndex] = time;
Frames[frameIndex + 1] = x; frames[frameIndex + 1] = x;
Frames[frameIndex + 2] = y; frames[frameIndex + 2] = y;
} }
override public void Apply (Skeleton skeleton, float lastTime, float time, float alpha, List<Event> firedEvents) { override public void Apply (Skeleton skeleton, float lastTime, float time, float alpha, List<Event> firedEvents) {
float[] frames = Frames; float[] frames = this.frames;
if (time < frames[0]) return; // Time is before first frame. if (time < frames[0]) return; // Time is before first frame.
Bone bone = skeleton.Bones[BoneIndex]; Bone bone = skeleton.bones[boneIndex];
if (time >= frames[frames.Length - 3]) { // Time is after last frame. if (time >= frames[frames.Length - 3]) { // Time is after last frame.
bone.X += (bone.Data.X + frames[frames.Length - 2] - bone.X) * alpha; bone.x += (bone.data.x + frames[frames.Length - 2] - bone.x) * alpha;
bone.Y += (bone.Data.Y + frames[frames.Length - 1] - bone.Y) * alpha; bone.y += (bone.data.y + frames[frames.Length - 1] - bone.y) * alpha;
return; return;
} }
@ -302,8 +308,8 @@ namespace Spine {
float percent = 1 - (time - frameTime) / (frames[frameIndex + LAST_FRAME_TIME] - frameTime); float percent = 1 - (time - frameTime) / (frames[frameIndex + LAST_FRAME_TIME] - frameTime);
percent = GetCurvePercent(frameIndex / 3 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent)); percent = GetCurvePercent(frameIndex / 3 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
bone.X += (bone.Data.X + lastFrameX + (frames[frameIndex + FRAME_X] - lastFrameX) * percent - bone.X) * alpha; bone.x += (bone.data.x + lastFrameX + (frames[frameIndex + FRAME_X] - lastFrameX) * percent - bone.x) * alpha;
bone.Y += (bone.Data.Y + lastFrameY + (frames[frameIndex + FRAME_Y] - lastFrameY) * percent - bone.Y) * alpha; bone.y += (bone.data.y + lastFrameY + (frames[frameIndex + FRAME_Y] - lastFrameY) * percent - bone.y) * alpha;
} }
} }
@ -313,13 +319,13 @@ namespace Spine {
} }
override public void Apply (Skeleton skeleton, float lastTime, float time, float alpha, List<Event> firedEvents) { override public void Apply (Skeleton skeleton, float lastTime, float time, float alpha, List<Event> firedEvents) {
float[] frames = Frames; float[] frames = this.frames;
if (time < frames[0]) return; // Time is before first frame. if (time < frames[0]) return; // Time is before first frame.
Bone bone = skeleton.Bones[BoneIndex]; Bone bone = skeleton.bones[boneIndex];
if (time >= frames[frames.Length - 3]) { // Time is after last frame. if (time >= frames[frames.Length - 3]) { // Time is after last frame.
bone.ScaleX += (bone.Data.ScaleX - 1 + frames[frames.Length - 2] - bone.ScaleX) * alpha; bone.scaleX += (bone.data.scaleX - 1 + frames[frames.Length - 2] - bone.scaleX) * alpha;
bone.ScaleY += (bone.Data.ScaleY - 1 + frames[frames.Length - 1] - bone.ScaleY) * alpha; bone.scaleY += (bone.data.scaleY - 1 + frames[frames.Length - 1] - bone.scaleY) * alpha;
return; return;
} }
@ -331,8 +337,8 @@ namespace Spine {
float percent = 1 - (time - frameTime) / (frames[frameIndex + LAST_FRAME_TIME] - frameTime); float percent = 1 - (time - frameTime) / (frames[frameIndex + LAST_FRAME_TIME] - frameTime);
percent = GetCurvePercent(frameIndex / 3 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent)); percent = GetCurvePercent(frameIndex / 3 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
bone.ScaleX += (bone.Data.ScaleX - 1 + lastFrameX + (frames[frameIndex + FRAME_X] - lastFrameX) * percent - bone.ScaleX) * alpha; bone.scaleX += (bone.data.scaleX - 1 + lastFrameX + (frames[frameIndex + FRAME_X] - lastFrameX) * percent - bone.scaleX) * alpha;
bone.ScaleY += (bone.Data.ScaleY - 1 + lastFrameY + (frames[frameIndex + FRAME_Y] - lastFrameY) * percent - bone.ScaleY) * alpha; bone.scaleY += (bone.data.scaleY - 1 + lastFrameY + (frames[frameIndex + FRAME_Y] - lastFrameY) * percent - bone.scaleY) * alpha;
} }
} }
@ -343,36 +349,39 @@ namespace Spine {
static protected int FRAME_B = 3; static protected int FRAME_B = 3;
static protected int FRAME_A = 4; static protected int FRAME_A = 4;
public int SlotIndex { get; set; } internal int slotIndex;
public float[] Frames { get; private set; } // time, r, g, b, a, ... internal float[] frames;
public int SlotIndex { get { return slotIndex; } set { slotIndex = value; } }
public float[] Frames { get { return frames; } set { frames = value; } } // time, r, g, b, a, ...
public ColorTimeline (int frameCount) public ColorTimeline (int frameCount)
: base(frameCount) { : base(frameCount) {
Frames = new float[frameCount * 5]; frames = new float[frameCount * 5];
} }
/** Sets the time and value of the specified keyframe. */ /** Sets the time and value of the specified keyframe. */
public void setFrame (int frameIndex, float time, float r, float g, float b, float a) { public void setFrame (int frameIndex, float time, float r, float g, float b, float a) {
frameIndex *= 5; frameIndex *= 5;
Frames[frameIndex] = time; frames[frameIndex] = time;
Frames[frameIndex + 1] = r; frames[frameIndex + 1] = r;
Frames[frameIndex + 2] = g; frames[frameIndex + 2] = g;
Frames[frameIndex + 3] = b; frames[frameIndex + 3] = b;
Frames[frameIndex + 4] = a; frames[frameIndex + 4] = a;
} }
override public void Apply (Skeleton skeleton, float lastTime, float time, float alpha, List<Event> firedEvents) { override public void Apply (Skeleton skeleton, float lastTime, float time, float alpha, List<Event> firedEvents) {
float[] frames = Frames; float[] frames = this.frames;
if (time < frames[0]) return; // Time is before first frame. if (time < frames[0]) return; // Time is before first frame.
Slot slot = skeleton.Slots[SlotIndex]; Slot slot = skeleton.slots[slotIndex];
if (time >= frames[frames.Length - 5]) { // Time is after last frame. if (time >= frames[frames.Length - 5]) { // Time is after last frame.
int i = frames.Length - 1; int i = frames.Length - 1;
slot.R = frames[i - 3]; slot.r = frames[i - 3];
slot.G = frames[i - 2]; slot.g = frames[i - 2];
slot.B = frames[i - 1]; slot.b = frames[i - 1];
slot.A = frames[i]; slot.a = frames[i];
return; return;
} }
@ -391,42 +400,42 @@ namespace Spine {
float b = lastFrameB + (frames[frameIndex + FRAME_B] - lastFrameB) * percent; float b = lastFrameB + (frames[frameIndex + FRAME_B] - lastFrameB) * percent;
float a = lastFrameA + (frames[frameIndex + FRAME_A] - lastFrameA) * percent; float a = lastFrameA + (frames[frameIndex + FRAME_A] - lastFrameA) * percent;
if (alpha < 1) { if (alpha < 1) {
slot.R += (r - slot.R) * alpha; slot.r += (r - slot.r) * alpha;
slot.G += (g - slot.G) * alpha; slot.g += (g - slot.g) * alpha;
slot.B += (b - slot.B) * alpha; slot.b += (b - slot.b) * alpha;
slot.A += (a - slot.A) * alpha; slot.a += (a - slot.a) * alpha;
} else { } else {
slot.R = r; slot.r = r;
slot.G = g; slot.g = g;
slot.B = b; slot.b = b;
slot.A = a; slot.a = a;
} }
} }
} }
public class AttachmentTimeline : Timeline { public class AttachmentTimeline : Timeline {
public int SlotIndex { get; set; } internal int slotIndex;
public float[] Frames { get; private set; } // time, ... internal float[] frames;
public String[] AttachmentNames { get; private set; } private String[] attachmentNames;
public int FrameCount {
get { public int SlotIndex { get { return slotIndex; } set { slotIndex = value; } }
return Frames.Length; public float[] Frames { get { return frames; } set { frames = value; } } // time, ...
} public String[] AttachmentNames { get { return attachmentNames; } set { attachmentNames = value; } }
} public int FrameCount { get { return frames.Length; } }
public AttachmentTimeline (int frameCount) { public AttachmentTimeline (int frameCount) {
Frames = new float[frameCount]; frames = new float[frameCount];
AttachmentNames = new String[frameCount]; attachmentNames = new String[frameCount];
} }
/** Sets the time and value of the specified keyframe. */ /** Sets the time and value of the specified keyframe. */
public void setFrame (int frameIndex, float time, String attachmentName) { public void setFrame (int frameIndex, float time, String attachmentName) {
Frames[frameIndex] = time; frames[frameIndex] = time;
AttachmentNames[frameIndex] = attachmentName; attachmentNames[frameIndex] = attachmentName;
} }
public void Apply (Skeleton skeleton, float lastTime, float time, float alpha, List<Event> firedEvents) { public void Apply (Skeleton skeleton, float lastTime, float time, float alpha, List<Event> firedEvents) {
float[] frames = Frames; float[] frames = this.frames;
if (time < frames[0]) return; // Time is before first frame. if (time < frames[0]) return; // Time is before first frame.
int frameIndex; int frameIndex;
@ -435,34 +444,33 @@ namespace Spine {
else else
frameIndex = Animation.binarySearch(frames, time, 1) - 1; frameIndex = Animation.binarySearch(frames, time, 1) - 1;
String attachmentName = AttachmentNames[frameIndex]; String attachmentName = attachmentNames[frameIndex];
skeleton.Slots[SlotIndex].Attachment = skeleton.slots[slotIndex].Attachment =
attachmentName == null ? null : skeleton.GetAttachment(SlotIndex, attachmentName); attachmentName == null ? null : skeleton.GetAttachment(slotIndex, attachmentName);
} }
} }
public class EventTimeline : Timeline { public class EventTimeline : Timeline {
public float[] Frames { get; private set; } // time, ... internal float[] frames;
public Event[] Events { get; private set; } private Event[] events;
public int FrameCount {
get { public float[] Frames { get { return frames; } set { frames = value; } } // time, ...
return Frames.Length; public Event[] Events { get { return events; } set { events = value; } }
} public int FrameCount { get { return frames.Length; } }
}
public EventTimeline (int frameCount) { public EventTimeline (int frameCount) {
Frames = new float[frameCount]; frames = new float[frameCount];
Events = new Event[frameCount]; events = new Event[frameCount];
} }
/** Sets the time and value of the specified keyframe. */ /** Sets the time and value of the specified keyframe. */
public void setFrame (int frameIndex, float time, Event e) { public void setFrame (int frameIndex, float time, Event e) {
Frames[frameIndex] = time; frames[frameIndex] = time;
Events[frameIndex] = e; events[frameIndex] = e;
} }
public void Apply (Skeleton skeleton, float lastTime, float time, float alpha, List<Event> firedEvents) { public void Apply (Skeleton skeleton, float lastTime, float time, float alpha, List<Event> firedEvents) {
float[] frames = Frames; float[] frames = this.frames;
if (time < frames[0]) return; // Time is before first frame. if (time < frames[0]) return; // Time is before first frame.
int frameCount = frames.Length; int frameCount = frames.Length;
@ -488,32 +496,31 @@ namespace Spine {
} }
} }
for (; frameIndex < frameCount && time > frames[frameIndex]; frameIndex++) for (; frameIndex < frameCount && time > frames[frameIndex]; frameIndex++)
firedEvents.Add(Events[frameIndex]); firedEvents.Add(events[frameIndex]);
} }
} }
public class DrawOrderTimeline : Timeline { public class DrawOrderTimeline : Timeline {
public float[] Frames { get; private set; } // time, ... internal float[] frames;
public int[][] DrawOrders { get; private set; } private int[][] drawOrders;
public int FrameCount {
get { public float[] Frames { get { return frames; } set { frames = value; } } // time, ...
return Frames.Length; public int[][] DrawOrders { get { return drawOrders; } set { drawOrders = value; } }
} public int FrameCount { get { return frames.Length; } }
}
public DrawOrderTimeline (int frameCount) { public DrawOrderTimeline (int frameCount) {
Frames = new float[frameCount]; frames = new float[frameCount];
DrawOrders = new int[frameCount][]; drawOrders = new int[frameCount][];
} }
/** Sets the time and value of the specified keyframe. */ /** Sets the time and value of the specified keyframe. */
public void setFrame (int frameIndex, float time, int[] drawOrder) { public void setFrame (int frameIndex, float time, int[] drawOrder) {
Frames[frameIndex] = time; frames[frameIndex] = time;
DrawOrders[frameIndex] = drawOrder; drawOrders[frameIndex] = drawOrder;
} }
public void Apply (Skeleton skeleton, float lastTime, float time, float alpha, List<Event> firedEvents) { public void Apply (Skeleton skeleton, float lastTime, float time, float alpha, List<Event> firedEvents) {
float[] frames = Frames; float[] frames = this.frames;
if (time < frames[0]) return; // Time is before first frame. if (time < frames[0]) return; // Time is before first frame.
int frameIndex; int frameIndex;
@ -522,9 +529,9 @@ namespace Spine {
else else
frameIndex = Animation.binarySearch(frames, time, 1) - 1; frameIndex = Animation.binarySearch(frames, time, 1) - 1;
List<Slot> drawOrder = skeleton.DrawOrder; List<Slot> drawOrder = skeleton.drawOrder;
List<Slot> slots = skeleton.Slots; List<Slot> slots = skeleton.slots;
int[] drawOrderToSetupIndex = DrawOrders[frameIndex]; int[] drawOrderToSetupIndex = drawOrders[frameIndex];
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

@ -36,28 +36,27 @@ using System.Collections.Generic;
namespace Spine { namespace Spine {
public class AnimationState { public class AnimationState {
public AnimationStateData Data { get; private set; } private AnimationStateData data;
public Animation Animation { get; private set; } private Animation current, previous;
private float currentTime, currentLastTime, previousTime;
private float time; private bool currentLoop, previousLoop;
public float Time {
get { return time; }
set {
time = value;
currentLastTime = value - 0.00001f;
}
}
private float currentLastTime;
public bool Loop { get; set; }
private Animation previous;
private float previousTime;
private bool previousLoop;
private QueueEntry currentQueueEntry; private QueueEntry currentQueueEntry;
private float mixTime, mixDuration; private float mixTime, mixDuration;
private List<Event> events = new List<Event>(); private List<Event> events = new List<Event>();
private List<QueueEntry> queue = new List<QueueEntry>(); private List<QueueEntry> queue = new List<QueueEntry>();
public AnimationStateData Data { get { return data; } }
public Animation Animation { get { return current; } }
public bool Loop { get { return currentLoop; } set { currentLoop = value; } }
public float Time {
get { return currentTime; }
set {
currentTime = value;
currentLastTime = value - 0.00001f;
}
}
public event EventHandler Start; public event EventHandler Start;
public event EventHandler End; public event EventHandler End;
public event EventHandler<EventTriggeredArgs> Event; public event EventHandler<EventTriggeredArgs> Event;
@ -65,19 +64,19 @@ namespace Spine {
public AnimationState (AnimationStateData data) { public AnimationState (AnimationStateData data) {
if (data == null) throw new ArgumentNullException("data cannot be null."); if (data == null) throw new ArgumentNullException("data cannot be null.");
Data = data; this.data = data;
} }
public void Update (float delta) { public void Update (float delta) {
time += delta; currentTime += delta;
previousTime += delta; previousTime += delta;
mixTime += delta; mixTime += delta;
if (Animation != null) { if (current != null) {
float duration = Animation.Duration; float duration = current.duration;
if (Loop ? (currentLastTime % duration > time % duration) if (currentLoop ? (currentLastTime % duration > currentTime % duration)
: (currentLastTime < duration && time >= duration)) { : (currentLastTime < duration && currentTime >= duration)) {
int count = (int)(time / duration); int count = (int)(currentTime / duration);
if (currentQueueEntry != null) currentQueueEntry.OnComplete(this, count); if (currentQueueEntry != null) currentQueueEntry.OnComplete(this, count);
if (Complete != null) Complete(this, new CompleteArgs(count)); if (Complete != null) Complete(this, new CompleteArgs(count));
} }
@ -85,7 +84,7 @@ namespace Spine {
if (queue.Count > 0) { if (queue.Count > 0) {
QueueEntry entry = queue[0]; QueueEntry entry = queue[0];
if (time >= entry.delay) { if (currentTime >= entry.delay) {
SetAnimationInternal(entry.animation, entry.loop, entry); SetAnimationInternal(entry.animation, entry.loop, entry);
queue.RemoveAt(0); queue.RemoveAt(0);
} }
@ -93,7 +92,7 @@ namespace Spine {
} }
public void Apply (Skeleton skeleton) { public void Apply (Skeleton skeleton) {
if (Animation == null) return; if (current == null) return;
List<Event> events = this.events; List<Event> events = this.events;
events.Clear(); events.Clear();
@ -105,9 +104,9 @@ namespace Spine {
alpha = 1; alpha = 1;
previous = null; previous = null;
} }
Animation.Mix(skeleton, currentLastTime, time, Loop, events, alpha); current.Mix(skeleton, currentLastTime, currentTime, currentLoop, events, alpha);
} else } else
Animation.Apply(skeleton, currentLastTime, time, Loop, events); current.Apply(skeleton, currentLastTime, currentTime, currentLoop, events);
if (Event != null || currentQueueEntry != null) { if (Event != null || currentQueueEntry != null) {
foreach (Event e in events) { foreach (Event e in events) {
@ -116,34 +115,34 @@ namespace Spine {
} }
} }
currentLastTime = time; currentLastTime = currentTime;
} }
public void ClearAnimation () { public void ClearAnimation () {
previous = null; previous = null;
Animation = null; current = null;
queue.Clear(); queue.Clear();
} }
private void SetAnimationInternal (Animation animation, bool loop, QueueEntry entry) { private void SetAnimationInternal (Animation animation, bool loop, QueueEntry entry) {
previous = null; previous = null;
if (Animation != null) { if (current != null) {
if (currentQueueEntry != null) currentQueueEntry.OnEnd(this); if (currentQueueEntry != null) currentQueueEntry.OnEnd(this);
if (End != null) End(this, EventArgs.Empty); if (End != null) End(this, EventArgs.Empty);
if (animation != null) { if (animation != null) {
mixDuration = Data.GetMix(Animation, animation); mixDuration = data.GetMix(current, animation);
if (mixDuration > 0) { if (mixDuration > 0) {
mixTime = 0; mixTime = 0;
previous = Animation; previous = current;
previousTime = time; previousTime = currentTime;
previousLoop = Loop; previousLoop = currentLoop;
} }
} }
} }
Animation = animation; current = animation;
Loop = loop; currentLoop = loop;
time = 0; currentTime = 0;
currentLastTime = 0; currentLastTime = 0;
currentQueueEntry = entry; currentQueueEntry = entry;
@ -152,7 +151,7 @@ namespace Spine {
} }
public void SetAnimation (String animationName, bool loop) { public void SetAnimation (String animationName, bool loop) {
Animation animation = Data.SkeletonData.FindAnimation(animationName); Animation animation = data.skeletonData.FindAnimation(animationName);
if (animation == null) throw new ArgumentException("Animation not found: " + animationName); if (animation == null) throw new ArgumentException("Animation not found: " + animationName);
SetAnimation(animation, loop); SetAnimation(animation, loop);
} }
@ -170,7 +169,7 @@ namespace Spine {
} }
public QueueEntry AddAnimation (String animationName, bool loop, float delay) { public QueueEntry AddAnimation (String animationName, bool loop, float delay) {
Animation animation = Data.SkeletonData.FindAnimation(animationName); Animation animation = data.skeletonData.FindAnimation(animationName);
if (animation == null) throw new ArgumentException("Animation not found: " + animationName); if (animation == null) throw new ArgumentException("Animation not found: " + animationName);
return AddAnimation(animation, loop, delay); return AddAnimation(animation, loop, delay);
} }
@ -187,9 +186,9 @@ namespace Spine {
entry.loop = loop; entry.loop = loop;
if (delay <= 0) { if (delay <= 0) {
Animation previousAnimation = queue.Count == 0 ? Animation : queue[queue.Count - 1].animation; Animation previousAnimation = queue.Count == 0 ? current : queue[queue.Count - 1].animation;
if (previousAnimation != null) if (previousAnimation != null)
delay = previousAnimation.Duration - Data.GetMix(previousAnimation, animation) + delay; delay = previousAnimation.duration - data.GetMix(previousAnimation, animation) + delay;
else else
delay = 0; delay = 0;
} }
@ -201,11 +200,11 @@ namespace Spine {
/** Returns true if no animation is set or if the current time is greater than the animation duration, regardless of looping. */ /** Returns true if no animation is set or if the current time is greater than the animation duration, regardless of looping. */
public bool IsComplete () { public bool IsComplete () {
return Animation == null || time >= Animation.Duration; return current == null || currentTime >= current.duration;
} }
override public String ToString () { override public String ToString () {
return (Animation != null && Animation.Name != null) ? Animation.Name : base.ToString(); return (current != null && current.name != null) ? current.name : base.ToString();
} }
} }

View File

@ -36,18 +36,21 @@ using System.Collections.Generic;
namespace Spine { namespace Spine {
public class AnimationStateData { public class AnimationStateData {
public SkeletonData SkeletonData { get; private set; } internal SkeletonData skeletonData;
private Dictionary<KeyValuePair<Animation, Animation>, float> animationToMixTime = new Dictionary<KeyValuePair<Animation, Animation>, float>(); private Dictionary<KeyValuePair<Animation, Animation>, float> animationToMixTime = new Dictionary<KeyValuePair<Animation, Animation>, float>();
public float defaultMix { get; set; } internal float defaultMix;
public SkeletonData SkeletonData { get { return skeletonData; } }
public float DefaultMix { get { return defaultMix; } set { defaultMix = value; } }
public AnimationStateData (SkeletonData skeletonData) { public AnimationStateData (SkeletonData skeletonData) {
SkeletonData = skeletonData; this.skeletonData = skeletonData;
} }
public void SetMix (String fromName, String toName, float duration) { public void SetMix (String fromName, String toName, float duration) {
Animation from = SkeletonData.FindAnimation(fromName); Animation from = skeletonData.FindAnimation(fromName);
if (from == null) throw new ArgumentException("Animation not found: " + fromName); if (from == null) throw new ArgumentException("Animation not found: " + fromName);
Animation to = SkeletonData.FindAnimation(toName); Animation to = skeletonData.FindAnimation(toName);
if (to == null) throw new ArgumentException("Animation not found: " + toName); if (to == null) throw new ArgumentException("Animation not found: " + toName);
SetMix(from, to, duration); SetMix(from, to, duration);
} }

View File

@ -50,12 +50,12 @@ namespace Spine {
RegionAttachment attachment = new RegionAttachment(name); RegionAttachment attachment = new RegionAttachment(name);
attachment.RendererObject = region; attachment.RendererObject = region;
attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.rotate); attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.rotate);
attachment.RegionOffsetX = region.offsetX; attachment.regionOffsetX = region.offsetX;
attachment.RegionOffsetY = region.offsetY; attachment.regionOffsetY = region.offsetY;
attachment.RegionWidth = region.width; attachment.regionWidth = region.width;
attachment.RegionHeight = region.height; attachment.regionHeight = region.height;
attachment.RegionOriginalWidth = region.originalWidth; attachment.regionOriginalWidth = region.originalWidth;
attachment.RegionOriginalHeight = region.originalHeight; attachment.regionOriginalHeight = region.originalHeight;
return attachment; return attachment;
case AttachmentType.boundingbox: case AttachmentType.boundingbox:
return new BoundingBoxAttachment(name); return new BoundingBoxAttachment(name);

View File

@ -44,12 +44,12 @@ namespace Spine {
/** @param worldVertices Must have at least the same length as this attachment's vertices. */ /** @param worldVertices Must have at least the same length as this attachment's vertices. */
public void ComputeWorldVertices (float x, float y, Bone bone, float[] worldVertices) { public void ComputeWorldVertices (float x, float y, Bone bone, float[] worldVertices) {
x += bone.WorldX; x += bone.worldX;
y += bone.WorldY; y += bone.worldY;
float m00 = bone.M00; float m00 = bone.m00;
float m01 = bone.M01; float m01 = bone.m01;
float m10 = bone.M10; float m10 = bone.m10;
float m11 = bone.M11; float m11 = bone.m11;
float[] vertices = Vertices; float[] vertices = Vertices;
for (int i = 0, n = vertices.Length; i < n; i += 2) { for (int i = 0, n = vertices.Length; i < n; i += 2) {
float px = vertices[i]; float px = vertices[i];

View File

@ -45,35 +45,35 @@ namespace Spine {
public const int X4 = 6; public const int X4 = 6;
public const int Y4 = 7; public const int Y4 = 7;
public float X { get; set; } internal float x, y, rotation, scaleX = 1, scaleY = 1, width, height;
public float Y { get; set; } internal float regionOffsetX, regionOffsetY, regionWidth, regionHeight, regionOriginalWidth, regionOriginalHeight;
public float ScaleX { get; set; } internal float[] offset = new float[8], uvs = new float[8];
public float ScaleY { get; set; }
public float Rotation { get; set; } public float X { get { return x; } set { x = value; } }
public float Width { get; set; } public float Y { get { return y; } set { y = value; } }
public float Height { get; set; } public float Rotation { get { return rotation; } set { rotation = value; } }
public float ScaleX { get { return scaleX; } set { scaleX = value; } }
public float ScaleY { get { return scaleY; } set { scaleY = value; } }
public float Width { get { return width; } set { width = value; } }
public float Height { get { return height; } set { height = value; } }
public Object RendererObject { get; set; } public Object RendererObject { get; set; }
public float RegionOffsetX { get; set; } public float RegionOffsetX { get { return regionOffsetX; } set { regionOffsetX = value; } }
public float RegionOffsetY { get; set; } // Pixels stripped from the bottom left, unrotated. public float RegionOffsetY { get { return regionOffsetY; } set { regionOffsetY = value; } } // Pixels stripped from the bottom left, unrotated.
public float RegionWidth { get; set; } public float RegionWidth { get { return regionWidth; } set { regionWidth = value; } }
public float RegionHeight { get; set; } // Unrotated, stripped size. public float RegionHeight { get { return regionHeight; } set { regionHeight = value; } } // Unrotated, stripped size.
public float RegionOriginalWidth { get; set; } public float RegionOriginalWidth { get { return regionOriginalWidth; } set { regionOriginalWidth = value; } }
public float RegionOriginalHeight { get; set; } // Unrotated, unstripped size. public float RegionOriginalHeight { get { return regionOriginalHeight; } set { regionOriginalHeight = value; } } // Unrotated, unstripped size.
public float[] Offset { get; private set; } public float[] Offset { get { return offset; } }
public float[] UVs { get; private set; } public float[] UVs { get { return uvs; } }
public RegionAttachment (string name) public RegionAttachment (string name)
: base(name) { : base(name) {
Offset = new float[8];
UVs = new float[8];
ScaleX = 1;
ScaleY = 1;
} }
public void SetUVs (float u, float v, float u2, float v2, bool rotate) { public void SetUVs (float u, float v, float u2, float v2, bool rotate) {
float[] uvs = UVs; float[] uvs = this.uvs;
if (rotate) { if (rotate) {
uvs[X2] = u; uvs[X2] = u;
uvs[Y2] = v2; uvs[Y2] = v2;
@ -96,21 +96,21 @@ namespace Spine {
} }
public void UpdateOffset () { public void UpdateOffset () {
float width = Width; float width = this.width;
float height = Height; float height = this.height;
float scaleX = ScaleX; float scaleX = this.scaleX;
float scaleY = ScaleY; float scaleY = this.scaleY;
float regionScaleX = width / RegionOriginalWidth * scaleX; float regionScaleX = width / regionOriginalWidth * scaleX;
float regionScaleY = height / RegionOriginalHeight * scaleY; float regionScaleY = height / regionOriginalHeight * scaleY;
float localX = -width / 2 * scaleX + RegionOffsetX * regionScaleX; float localX = -width / 2 * scaleX + regionOffsetX * regionScaleX;
float localY = -height / 2 * scaleY + RegionOffsetY * regionScaleY; float localY = -height / 2 * scaleY + regionOffsetY * regionScaleY;
float localX2 = localX + RegionWidth * regionScaleX; float localX2 = localX + regionWidth * regionScaleX;
float localY2 = localY + RegionHeight * regionScaleY; float localY2 = localY + regionHeight * regionScaleY;
float radians = Rotation * (float)Math.PI / 180; float radians = rotation * (float)Math.PI / 180;
float cos = (float)Math.Cos(radians); float cos = (float)Math.Cos(radians);
float sin = (float)Math.Sin(radians); float sin = (float)Math.Sin(radians);
float x = X; float x = this.x;
float y = Y; float y = this.y;
float localXCos = localX * cos + x; float localXCos = localX * cos + x;
float localXSin = localX * sin; float localXSin = localX * sin;
float localYCos = localY * cos + y; float localYCos = localY * cos + y;
@ -119,7 +119,7 @@ namespace Spine {
float localX2Sin = localX2 * sin; float localX2Sin = localX2 * sin;
float localY2Cos = localY2 * cos + y; float localY2Cos = localY2 * cos + y;
float localY2Sin = localY2 * sin; float localY2Sin = localY2 * sin;
float[] offset = Offset; float[] offset = this.offset;
offset[X1] = localXCos - localYSin; offset[X1] = localXCos - localYSin;
offset[Y1] = localYCos + localXSin; offset[Y1] = localYCos + localXSin;
offset[X2] = localXCos - localY2Sin; offset[X2] = localXCos - localY2Sin;
@ -131,13 +131,13 @@ namespace Spine {
} }
public void ComputeVertices (float x, float y, Bone bone, float[] vertices) { public void ComputeVertices (float x, float y, Bone bone, float[] vertices) {
x += bone.WorldX; x += bone.worldX;
y += bone.WorldY; y += bone.worldY;
float m00 = bone.M00; float m00 = bone.m00;
float m01 = bone.M01; float m01 = bone.m01;
float m10 = bone.M10; float m10 = bone.m10;
float m11 = bone.M11; float m11 = bone.m11;
float[] offset = Offset; float[] offset = this.offset;
vertices[X1] = offset[X1] * m00 + offset[Y1] * m01 + x; vertices[X1] = offset[X1] * m00 + offset[Y1] * m01 + x;
vertices[Y1] = offset[X1] * m10 + offset[Y1] * m11 + y; vertices[Y1] = offset[X1] * m10 + offset[Y1] * m11 + y;
vertices[X2] = offset[X2] * m00 + offset[Y2] * m01 + x; vertices[X2] = offset[X2] * m00 + offset[Y2] * m01 + x;

View File

@ -37,81 +37,87 @@ namespace Spine {
public class Bone { public class Bone {
static public bool yDown; static public bool yDown;
public BoneData Data { get; private set; } internal BoneData data;
public Bone Parent { get; private set; } internal Bone parent;
public float X { get; set; } internal float x, y, rotation, scaleX, scaleY;
public float Y { get; set; } internal float m00, m01, m10, m11;
public float Rotation { get; set; } internal float worldX, worldY, worldRotation, worldScaleX, worldScaleY;
public float ScaleX { get; set; }
public float ScaleY { get; set; }
public float M00 { get; private set; } public BoneData Data { get { return data; } }
public float M01 { get; private set; } public Bone Parent { get { return parent; } }
public float M10 { get; private set; } public float X { get { return x; } set { x = value; } }
public float M11 { get; private set; } public float Y { get { return y; } set { y = value; } }
public float WorldX { get; private set; } public float Rotation { get { return rotation; } set { rotation = value; } }
public float WorldY { get; private set; } public float ScaleX { get { return scaleX; } set { scaleX = value; } }
public float WorldRotation { get; private set; } public float ScaleY { get { return scaleY; } set { scaleY = value; } }
public float WorldScaleX { get; private set; }
public float WorldScaleY { get; private set; } public float M00 { get { return m00; } }
public float M01 { get { return m01; } }
public float M10 { get { return m10; } }
public float M11 { get { return m11; } }
public float WorldX { get { return worldX; } }
public float WorldY { get { return worldY; } }
public float WorldRotation { get { return worldRotation; } }
public float WorldScaleX { get { return worldScaleX; } }
public float WorldScaleY { get { return worldScaleY; } }
/** @param parent May be null. */ /** @param parent May be null. */
public Bone (BoneData data, Bone parent) { public Bone (BoneData data, Bone parent) {
if (data == null) throw new ArgumentNullException("data cannot be null."); if (data == null) throw new ArgumentNullException("data cannot be null.");
Data = data; this.data = data;
Parent = parent; this.parent = parent;
SetToSetupPose(); SetToSetupPose();
} }
/** Computes the world SRT using the parent bone and the local SRT. */ /** Computes the world SRT using the parent bone and the local SRT. */
public void UpdateWorldTransform (bool flipX, bool flipY) { public void UpdateWorldTransform (bool flipX, bool flipY) {
Bone parent = Parent; Bone parent = this.parent;
if (parent != null) { if (parent != null) {
WorldX = X * parent.M00 + Y * parent.M01 + parent.WorldX; worldX = x * parent.m00 + y * parent.m01 + parent.worldX;
WorldY = X * parent.M10 + Y * parent.M11 + parent.WorldY; worldY = x * parent.m10 + y * parent.m11 + parent.worldY;
if (Data.InheritScale) { if (data.inheritScale) {
WorldScaleX = parent.WorldScaleX * ScaleX; worldScaleX = parent.worldScaleX * scaleX;
WorldScaleY = parent.WorldScaleY * ScaleY; worldScaleY = parent.worldScaleY * scaleY;
} else { } else {
WorldScaleX = ScaleX; worldScaleX = scaleX;
WorldScaleY = ScaleY; worldScaleY = scaleY;
} }
WorldRotation = Data.InheritRotation ? parent.WorldRotation + Rotation : Rotation; worldRotation = data.inheritRotation ? parent.worldRotation + rotation : rotation;
} else { } else {
WorldX = flipX ? -X : X; worldX = flipX ? -x : x;
WorldY = flipY ? -Y : Y; worldY = flipY ? -y : y;
WorldScaleX = ScaleX; worldScaleX = scaleX;
WorldScaleY = ScaleY; worldScaleY = scaleY;
WorldRotation = Rotation; worldRotation = rotation;
} }
float radians = WorldRotation * (float)Math.PI / 180; float radians = worldRotation * (float)Math.PI / 180;
float cos = (float)Math.Cos(radians); float cos = (float)Math.Cos(radians);
float sin = (float)Math.Sin(radians); float sin = (float)Math.Sin(radians);
M00 = cos * WorldScaleX; m00 = cos * worldScaleX;
M10 = sin * WorldScaleX; m10 = sin * worldScaleX;
M01 = -sin * WorldScaleY; m01 = -sin * worldScaleY;
M11 = cos * WorldScaleY; m11 = cos * worldScaleY;
if (flipX) { if (flipX) {
M00 = -M00; m00 = -m00;
M01 = -M01; m01 = -m01;
} }
if (flipY != yDown) { if (flipY != yDown) {
M10 = -M10; m10 = -m10;
M11 = -M11; m11 = -m11;
} }
} }
public void SetToSetupPose () { public void SetToSetupPose () {
BoneData data = Data; BoneData data = this.data;
X = data.X; x = data.x;
Y = data.Y; y = data.y;
Rotation = data.Rotation; rotation = data.rotation;
ScaleX = data.ScaleX; scaleX = data.scaleX;
ScaleY = data.ScaleY; scaleY = data.scaleY;
} }
override public String ToString () { override public String ToString () {
return Data.Name; return data.name;
} }
} }
} }

View File

@ -35,29 +35,32 @@ using System;
namespace Spine { namespace Spine {
public class BoneData { public class BoneData {
internal BoneData parent;
internal String name;
internal float length, x, y, rotation, scaleX = 1, scaleY = 1;
internal bool inheritScale, inheritRotation;
/** May be null. */ /** May be null. */
public BoneData Parent { get; private set; } public BoneData Parent { get { return parent; } }
public String Name { get; private set; } public String Name { get { return name; } }
public float Length { get; set; } public float Length { get { return length; } set { length = value; } }
public float X { get; set; } public float X { get { return x; } set { x = value; } }
public float Y { get; set; } public float Y { get { return y; } set { y = value; } }
public float Rotation { get; set; } public float Rotation { get { return rotation; } set { rotation = value; } }
public float ScaleX { get; set; } public float ScaleX { get { return scaleX; } set { scaleX = value; } }
public float ScaleY { get; set; } public float ScaleY { get { return scaleY; } set { scaleY = value; } }
public bool InheritScale { get; set; } public bool InheritScale { get { return inheritScale; } set { inheritScale = value; } }
public bool InheritRotation { get; set; } public bool InheritRotation { get { return inheritRotation; } set { inheritRotation = value; } }
/** @param parent May be null. */ /** @param parent May be null. */
public BoneData (String name, BoneData parent) { public BoneData (String name, BoneData parent) {
if (name == null) throw new ArgumentNullException("name cannot be null."); if (name == null) throw new ArgumentNullException("name cannot be null.");
Name = name; this.name = name;
Parent = parent; this.parent = parent;
ScaleX = 1;
ScaleY = 1;
} }
override public String ToString () { override public String ToString () {
return Name; return name;
} }
} }
} }

View File

@ -36,56 +36,62 @@ using System.Collections.Generic;
namespace Spine { namespace Spine {
public class Skeleton { public class Skeleton {
public SkeletonData Data { get; private set; } internal SkeletonData data;
public List<Bone> Bones { get; private set; } internal List<Bone> bones;
public List<Slot> Slots { get; private set; } internal List<Slot> slots;
public List<Slot> DrawOrder { get; private set; } internal List<Slot> drawOrder;
public Skin Skin { get; set; } internal Skin skin;
public float R { get; set; } internal float r = 1, g = 1, b = 1, a = 1;
public float G { get; set; } internal float time;
public float B { get; set; } internal bool flipX, flipY;
public float A { get; set; } internal float x, y;
public float Time { get; set; }
public bool FlipX { get; set; } public SkeletonData Data { get { return data; } }
public bool FlipY { get; set; } public List<Bone> Bones { get { return bones; } }
public List<Slot> Slots { get { return slots; } }
public List<Slot> DrawOrder { get { return drawOrder; } }
public Skin Skin { get { return skin; } set { skin = value; } }
public float R { get { return r; } set { r = value; } }
public float G { get { return g; } set { g = value; } }
public float B { get { return b; } set { b = value; } }
public float A { get { return a; } set { a = value; } }
public float Time { get { return time; } set { time = value; } }
public bool FlipX { get { return flipX; } set { flipX = value; } }
public bool FlipY { get { return flipY; } set { flipY = value; } }
public float X { get { return x; } set { x = value; } }
public float Y { get { return y; } set { y = value; } }
public Bone RootBone { public Bone RootBone {
get { get {
return Bones.Count == 0 ? null : Bones[0]; return bones.Count == 0 ? null : bones[0];
} }
} }
public float X { get; set; }
public float Y { get; set; }
public Skeleton (SkeletonData data) { public Skeleton (SkeletonData data) {
if (data == null) throw new ArgumentNullException("data cannot be null."); if (data == null) throw new ArgumentNullException("data cannot be null.");
Data = data; this.data = data;
Bones = new List<Bone>(Data.Bones.Count); bones = new List<Bone>(data.bones.Count);
foreach (BoneData boneData in Data.Bones) { foreach (BoneData boneData in data.bones) {
Bone parent = boneData.Parent == null ? null : Bones[Data.Bones.IndexOf(boneData.Parent)]; Bone parent = boneData.parent == null ? null : bones[data.bones.IndexOf(boneData.parent)];
Bones.Add(new Bone(boneData, parent)); bones.Add(new Bone(boneData, parent));
} }
Slots = new List<Slot>(Data.Slots.Count); slots = new List<Slot>(data.slots.Count);
DrawOrder = new List<Slot>(Data.Slots.Count); drawOrder = new List<Slot>(data.slots.Count);
foreach (SlotData slotData in Data.Slots) { foreach (SlotData slotData in data.slots) {
Bone bone = Bones[Data.Bones.IndexOf(slotData.BoneData)]; Bone bone = bones[data.bones.IndexOf(slotData.boneData)];
Slot slot = new Slot(slotData, this, bone); Slot slot = new Slot(slotData, this, bone);
Slots.Add(slot); slots.Add(slot);
DrawOrder.Add(slot); drawOrder.Add(slot);
} }
R = 1;
G = 1;
B = 1;
A = 1;
} }
/** Updates the world transform for each bone. */ /** Updates the world transform for each bone. */
public void UpdateWorldTransform () { public void UpdateWorldTransform () {
bool flipX = FlipX; bool flipX = this.flipX;
bool flipY = FlipY; bool flipY = this.flipY;
List<Bone> bones = Bones; List<Bone> bones = this.bones;
for (int i = 0, n = bones.Count; i < n; i++) for (int i = 0, n = bones.Count; i < n; i++)
bones[i].UpdateWorldTransform(flipX, flipY); bones[i].UpdateWorldTransform(flipX, flipY);
} }
@ -97,13 +103,13 @@ namespace Spine {
} }
public void SetBonesToSetupPose () { public void SetBonesToSetupPose () {
List<Bone> bones = this.Bones; List<Bone> bones = this.bones;
for (int i = 0, n = bones.Count; i < n; i++) for (int i = 0, n = bones.Count; i < n; i++)
bones[i].SetToSetupPose(); bones[i].SetToSetupPose();
} }
public void SetSlotsToSetupPose () { public void SetSlotsToSetupPose () {
List<Slot> slots = this.Slots; List<Slot> slots = this.slots;
for (int i = 0, n = slots.Count; i < n; i++) for (int i = 0, n = slots.Count; i < n; i++)
slots[i].SetToSetupPose(i); slots[i].SetToSetupPose(i);
} }
@ -111,10 +117,10 @@ namespace Spine {
/** @return May be null. */ /** @return May be null. */
public Bone FindBone (String boneName) { public Bone FindBone (String boneName) {
if (boneName == null) throw new ArgumentNullException("boneName cannot be null."); if (boneName == null) throw new ArgumentNullException("boneName cannot be null.");
List<Bone> bones = this.Bones; List<Bone> bones = this.bones;
for (int i = 0, n = bones.Count; i < n; i++) { for (int i = 0, n = bones.Count; i < n; i++) {
Bone bone = bones[i]; Bone bone = bones[i];
if (bone.Data.Name == boneName) return bone; if (bone.data.name == boneName) return bone;
} }
return null; return null;
} }
@ -122,19 +128,19 @@ namespace Spine {
/** @return -1 if the bone was not found. */ /** @return -1 if the bone was not found. */
public int FindBoneIndex (String boneName) { public int FindBoneIndex (String boneName) {
if (boneName == null) throw new ArgumentNullException("boneName cannot be null."); if (boneName == null) throw new ArgumentNullException("boneName cannot be null.");
List<Bone> bones = this.Bones; List<Bone> bones = this.bones;
for (int i = 0, n = bones.Count; i < n; i++) for (int i = 0, n = bones.Count; i < n; i++)
if (bones[i].Data.Name == boneName) return i; if (bones[i].data.name == boneName) return i;
return -1; return -1;
} }
/** @return May be null. */ /** @return May be null. */
public Slot FindSlot (String slotName) { public Slot FindSlot (String slotName) {
if (slotName == null) throw new ArgumentNullException("slotName cannot be null."); if (slotName == null) throw new ArgumentNullException("slotName cannot be null.");
List<Slot> slots = this.Slots; List<Slot> slots = this.slots;
for (int i = 0, n = slots.Count; i < n; i++) { for (int i = 0, n = slots.Count; i < n; i++) {
Slot slot = slots[i]; Slot slot = slots[i];
if (slot.Data.Name == slotName) return slot; if (slot.data.name == slotName) return slot;
} }
return null; return null;
} }
@ -142,16 +148,16 @@ namespace Spine {
/** @return -1 if the bone was not found. */ /** @return -1 if the bone was not found. */
public int FindSlotIndex (String slotName) { public int FindSlotIndex (String slotName) {
if (slotName == null) throw new ArgumentNullException("slotName cannot be null."); if (slotName == null) throw new ArgumentNullException("slotName cannot be null.");
List<Slot> slots = this.Slots; List<Slot> slots = this.slots;
for (int i = 0, n = slots.Count; i < n; i++) for (int i = 0, n = slots.Count; i < n; i++)
if (slots[i].Data.Name.Equals(slotName)) return i; if (slots[i].data.name.Equals(slotName)) return i;
return -1; return -1;
} }
/** Sets a skin by name. /** Sets a skin by name.
* @see #setSkin(Skin) */ * @see #setSkin(Skin) */
public void SetSkin (String skinName) { public void SetSkin (String skinName) {
Skin skin = Data.FindSkin(skinName); Skin skin = data.FindSkin(skinName);
if (skin == null) throw new ArgumentException("Skin not found: " + skinName); if (skin == null) throw new ArgumentException("Skin not found: " + skinName);
SetSkin(skin); SetSkin(skin);
} }
@ -160,33 +166,33 @@ namespace Spine {
* from the new skin are attached if the corresponding attachment from the old skin was attached. * from the new skin are attached if the corresponding attachment from the old skin was attached.
* @param newSkin May be null. */ * @param newSkin May be null. */
public void SetSkin (Skin newSkin) { public void SetSkin (Skin newSkin) {
if (Skin != null && newSkin != null) newSkin.AttachAll(this, Skin); if (skin != null && newSkin != null) newSkin.AttachAll(this, skin);
Skin = newSkin; skin = newSkin;
} }
/** @return May be null. */ /** @return May be null. */
public Attachment GetAttachment (String slotName, String attachmentName) { public Attachment GetAttachment (String slotName, String attachmentName) {
return GetAttachment(Data.FindSlotIndex(slotName), attachmentName); return GetAttachment(data.FindSlotIndex(slotName), attachmentName);
} }
/** @return May be null. */ /** @return May be null. */
public Attachment GetAttachment (int slotIndex, String attachmentName) { public Attachment GetAttachment (int slotIndex, String attachmentName) {
if (attachmentName == null) throw new ArgumentNullException("attachmentName cannot be null."); if (attachmentName == null) throw new ArgumentNullException("attachmentName cannot be null.");
if (Skin != null) { if (skin != null) {
Attachment attachment = Skin.GetAttachment(slotIndex, attachmentName); Attachment attachment = skin.GetAttachment(slotIndex, attachmentName);
if (attachment != null) return attachment; if (attachment != null) return attachment;
} }
if (Data.DefaultSkin != null) return Data.DefaultSkin.GetAttachment(slotIndex, attachmentName); if (data.defaultSkin != null) return data.defaultSkin.GetAttachment(slotIndex, attachmentName);
return null; return null;
} }
/** @param attachmentName May be null. */ /** @param attachmentName May be null. */
public void SetAttachment (String slotName, String attachmentName) { public void SetAttachment (String slotName, String attachmentName) {
if (slotName == null) throw new ArgumentNullException("slotName cannot be null."); if (slotName == null) throw new ArgumentNullException("slotName cannot be null.");
List<Slot> slots = Slots; List<Slot> slots = this.slots;
for (int i = 0, n = slots.Count; i < n; i++) { for (int i = 0, n = slots.Count; i < n; i++) {
Slot slot = slots[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) {
attachment = GetAttachment(i, attachmentName); attachment = GetAttachment(i, attachmentName);
@ -200,7 +206,7 @@ namespace Spine {
} }
public void Update (float delta) { public void Update (float delta) {
Time += delta; time += delta;
} }
} }
} }

View File

@ -110,9 +110,9 @@ namespace Spine {
List<BoundingBoxAttachment> boundingBoxes = BoundingBoxes; List<BoundingBoxAttachment> boundingBoxes = BoundingBoxes;
List<Polygon> polygons = Polygons; List<Polygon> polygons = Polygons;
List<Slot> slots = skeleton.Slots; List<Slot> slots = skeleton.slots;
int slotCount = slots.Count; int slotCount = slots.Count;
float x = skeleton.X, y = skeleton.Y; float x = skeleton.x, y = skeleton.y;
boundingBoxes.Clear(); boundingBoxes.Clear();
foreach (Polygon polygon in polygons) foreach (Polygon polygon in polygons)
@ -121,7 +121,7 @@ namespace Spine {
for (int i = 0; i < slotCount; i++) { for (int i = 0; i < slotCount; i++) {
Slot slot = slots[i]; Slot slot = slots[i];
BoundingBoxAttachment boundingBox = slot.Attachment as BoundingBoxAttachment; BoundingBoxAttachment boundingBox = slot.attachment as BoundingBoxAttachment;
if (boundingBox == null) continue; if (boundingBox == null) continue;
boundingBoxes.Add(boundingBox); boundingBoxes.Add(boundingBox);
@ -137,7 +137,7 @@ namespace Spine {
int count = boundingBox.Vertices.Length; int count = boundingBox.Vertices.Length;
polygon.Count = count; polygon.Count = count;
if (polygon.Vertices.Length < count) polygon.Vertices = new float[count]; if (polygon.Vertices.Length < count) polygon.Vertices = new float[count];
boundingBox.ComputeWorldVertices(x, y, slot.Bone, polygon.Vertices); boundingBox.ComputeWorldVertices(x, y, slot.bone, polygon.Vertices);
} }
} }

View File

@ -36,37 +36,38 @@ using System.Collections.Generic;
namespace Spine { namespace Spine {
public class SkeletonData { public class SkeletonData {
public String Name { get; set; } internal String name;
public List<BoneData> Bones { get; private set; } // Ordered parents first. internal List<BoneData> bones = new List<BoneData>();
public List<SlotData> Slots { get; private set; } // Setup pose draw order. internal List<SlotData> slots = new List<SlotData>();
public List<Skin> Skins { get; private set; } internal List<Skin> skins = new List<Skin>();
/** May be null. */ internal Skin defaultSkin;
public Skin DefaultSkin; internal List<EventData> events = new List<EventData>();
public List<EventData> Events { get; private set; } internal List<Animation> animations = new List<Animation>();
public List<Animation> Animations { get; private set; }
public SkeletonData () { public String Name { get { return name; } set { name = value; } }
Bones = new List<BoneData>(); public List<BoneData> Bones { get { return bones; } } // Ordered parents first.
Slots = new List<SlotData>(); public List<SlotData> Slots { get { return slots; } } // Setup pose draw order.
Skins = new List<Skin>(); public List<Skin> Skins { get { return skins; } set { skins = value; } }
Events = new List<EventData>(); /** May be null. */
Animations = new List<Animation>(); public Skin DefaultSkin { get { return defaultSkin; } set { defaultSkin = value; } }
} public List<EventData> Events { get { return events; } set { events = value; } }
public List<Animation> Animations { get { return animations; } set { animations = value; } }
// --- Bones. // --- Bones.
public void AddBone (BoneData bone) { public void AddBone (BoneData bone) {
if (bone == null) throw new ArgumentNullException("bone cannot be null."); if (bone == null) throw new ArgumentNullException("bone cannot be null.");
Bones.Add(bone); bones.Add(bone);
} }
/** @return May be null. */ /** @return May be null. */
public BoneData FindBone (String boneName) { public BoneData FindBone (String boneName) {
if (boneName == null) throw new ArgumentNullException("boneName cannot be null."); if (boneName == null) throw new ArgumentNullException("boneName cannot be null.");
for (int i = 0, n = Bones.Count; i < n; i++) { List<BoneData> bones = this.bones;
BoneData bone = Bones[i]; for (int i = 0, n = bones.Count; i < n; i++) {
if (bone.Name == boneName) return bone; BoneData bone = bones[i];
if (bone.name == boneName) return bone;
} }
return null; return null;
} }
@ -74,8 +75,9 @@ namespace Spine {
/** @return -1 if the bone was not found. */ /** @return -1 if the bone was not found. */
public int FindBoneIndex (String boneName) { public int FindBoneIndex (String boneName) {
if (boneName == null) throw new ArgumentNullException("boneName cannot be null."); if (boneName == null) throw new ArgumentNullException("boneName cannot be null.");
for (int i = 0, n = Bones.Count; i < n; i++) List<BoneData> bones = this.bones;
if (Bones[i].Name == boneName) return i; for (int i = 0, n = bones.Count; i < n; i++)
if (bones[i].name == boneName) return i;
return -1; return -1;
} }
@ -83,15 +85,16 @@ namespace Spine {
public void AddSlot (SlotData slot) { public void AddSlot (SlotData slot) {
if (slot == null) throw new ArgumentNullException("slot cannot be null."); if (slot == null) throw new ArgumentNullException("slot cannot be null.");
Slots.Add(slot); slots.Add(slot);
} }
/** @return May be null. */ /** @return May be null. */
public SlotData FindSlot (String slotName) { public SlotData FindSlot (String slotName) {
if (slotName == null) throw new ArgumentNullException("slotName cannot be null."); if (slotName == null) throw new ArgumentNullException("slotName cannot be null.");
for (int i = 0, n = Slots.Count; i < n; i++) { List<SlotData> slots = this.slots;
SlotData slot = Slots[i]; for (int i = 0, n = slots.Count; i < n; i++) {
if (slot.Name == slotName) return slot; SlotData slot = slots[i];
if (slot.name == slotName) return slot;
} }
return null; return null;
} }
@ -99,8 +102,9 @@ namespace Spine {
/** @return -1 if the bone was not found. */ /** @return -1 if the bone was not found. */
public int FindSlotIndex (String slotName) { public int FindSlotIndex (String slotName) {
if (slotName == null) throw new ArgumentNullException("slotName cannot be null."); if (slotName == null) throw new ArgumentNullException("slotName cannot be null.");
for (int i = 0, n = Slots.Count; i < n; i++) List<SlotData> slots = this.slots;
if (Slots[i].Name == slotName) return i; for (int i = 0, n = slots.Count; i < n; i++)
if (slots[i].name == slotName) return i;
return -1; return -1;
} }
@ -108,14 +112,14 @@ namespace Spine {
public void AddSkin (Skin skin) { public void AddSkin (Skin skin) {
if (skin == null) throw new ArgumentNullException("skin cannot be null."); if (skin == null) throw new ArgumentNullException("skin cannot be null.");
Skins.Add(skin); skins.Add(skin);
} }
/** @return May be null. */ /** @return May be null. */
public Skin FindSkin (String skinName) { public Skin FindSkin (String skinName) {
if (skinName == null) throw new ArgumentNullException("skinName cannot be null."); if (skinName == null) throw new ArgumentNullException("skinName cannot be null.");
foreach (Skin skin in Skins) foreach (Skin skin in skins)
if (skin.Name == skinName) return skin; if (skin.name == skinName) return skin;
return null; return null;
} }
@ -123,13 +127,13 @@ namespace Spine {
public void AddEvent (EventData eventData) { public void AddEvent (EventData eventData) {
if (eventData == null) throw new ArgumentNullException("eventData cannot be null."); if (eventData == null) throw new ArgumentNullException("eventData cannot be null.");
Events.Add(eventData); events.Add(eventData);
} }
/** @return May be null. */ /** @return May be null. */
public EventData findEvent (String eventDataName) { public EventData findEvent (String eventDataName) {
if (eventDataName == null) throw new ArgumentNullException("eventDataName cannot be null."); if (eventDataName == null) throw new ArgumentNullException("eventDataName cannot be null.");
foreach (EventData eventData in Events) foreach (EventData eventData in events)
if (eventData.Name == eventDataName) return eventData; if (eventData.Name == eventDataName) return eventData;
return null; return null;
} }
@ -138,14 +142,15 @@ namespace Spine {
public void AddAnimation (Animation animation) { public void AddAnimation (Animation animation) {
if (animation == null) throw new ArgumentNullException("animation cannot be null."); if (animation == null) throw new ArgumentNullException("animation cannot be null.");
Animations.Add(animation); animations.Add(animation);
} }
/** @return May be null. */ /** @return May be null. */
public Animation FindAnimation (String animationName) { public Animation FindAnimation (String animationName) {
if (animationName == null) throw new ArgumentNullException("animationName cannot be null."); if (animationName == null) throw new ArgumentNullException("animationName cannot be null.");
for (int i = 0, n = Animations.Count; i < n; i++) { List<Animation> animations = this.animations;
Animation animation = Animations[i]; for (int i = 0, n = animations.Count; i < n; i++) {
Animation animation = animations[i];
if (animation.Name == animationName) return animation; if (animation.Name == animationName) return animation;
} }
return null; return null;
@ -154,7 +159,7 @@ namespace Spine {
// --- // ---
override public String ToString () { override public String ToString () {
return Name ?? base.ToString(); return name ?? base.ToString();
} }
} }
} }

View File

@ -82,7 +82,7 @@ namespace Spine {
public SkeletonData ReadSkeletonData (String path) { public SkeletonData ReadSkeletonData (String path) {
using (StreamReader reader = new StreamReader(path)) { using (StreamReader reader = new StreamReader(path)) {
SkeletonData skeletonData = ReadSkeletonData(reader); SkeletonData skeletonData = ReadSkeletonData(reader);
skeletonData.Name = Path.GetFileNameWithoutExtension(path); skeletonData.name = Path.GetFileNameWithoutExtension(path);
return skeletonData; return skeletonData;
} }
} }
@ -105,14 +105,14 @@ namespace Spine {
throw new Exception("Parent bone not found: " + boneMap["parent"]); throw new Exception("Parent bone not found: " + boneMap["parent"]);
} }
BoneData boneData = new BoneData((String)boneMap["name"], parent); BoneData boneData = new BoneData((String)boneMap["name"], parent);
boneData.Length = GetFloat(boneMap, "length", 0) * Scale; boneData.length = GetFloat(boneMap, "length", 0) * Scale;
boneData.X = GetFloat(boneMap, "x", 0) * Scale; boneData.x = GetFloat(boneMap, "x", 0) * Scale;
boneData.Y = GetFloat(boneMap, "y", 0) * Scale; boneData.y = GetFloat(boneMap, "y", 0) * Scale;
boneData.Rotation = GetFloat(boneMap, "rotation", 0); boneData.rotation = GetFloat(boneMap, "rotation", 0);
boneData.ScaleX = GetFloat(boneMap, "scaleX", 1); boneData.scaleX = GetFloat(boneMap, "scaleX", 1);
boneData.ScaleY = GetFloat(boneMap, "scaleY", 1); boneData.scaleY = GetFloat(boneMap, "scaleY", 1);
boneData.InheritScale = GetBoolean(boneMap, "inheritScale", true); boneData.inheritScale = GetBoolean(boneMap, "inheritScale", true);
boneData.InheritRotation = GetBoolean(boneMap, "inheritRotation", true); boneData.inheritRotation = GetBoolean(boneMap, "inheritRotation", true);
skeletonData.AddBone(boneData); skeletonData.AddBone(boneData);
} }
@ -128,17 +128,17 @@ namespace Spine {
if (slotMap.ContainsKey("color")) { if (slotMap.ContainsKey("color")) {
String color = (String)slotMap["color"]; String color = (String)slotMap["color"];
slotData.R = ToColor(color, 0); slotData.r = ToColor(color, 0);
slotData.G = ToColor(color, 1); slotData.g = ToColor(color, 1);
slotData.B = ToColor(color, 2); slotData.b = ToColor(color, 2);
slotData.A = ToColor(color, 3); slotData.a = ToColor(color, 3);
} }
if (slotMap.ContainsKey("attachment")) if (slotMap.ContainsKey("attachment"))
slotData.AttachmentName = (String)slotMap["attachment"]; slotData.attachmentName = (String)slotMap["attachment"];
if (slotMap.ContainsKey("additive")) if (slotMap.ContainsKey("additive"))
slotData.AdditiveBlending = (bool)slotMap["additive"]; slotData.additiveBlending = (bool)slotMap["additive"];
skeletonData.AddSlot(slotData); skeletonData.AddSlot(slotData);
} }
@ -156,8 +156,8 @@ namespace Spine {
} }
} }
skeletonData.AddSkin(skin); skeletonData.AddSkin(skin);
if (skin.Name == "default") if (skin.name == "default")
skeletonData.DefaultSkin = skin; skeletonData.defaultSkin = skin;
} }
} }
@ -179,10 +179,10 @@ namespace Spine {
ReadAnimation(entry.Key, (Dictionary<String, Object>)entry.Value, skeletonData); ReadAnimation(entry.Key, (Dictionary<String, Object>)entry.Value, skeletonData);
} }
skeletonData.Bones.TrimExcess(); skeletonData.bones.TrimExcess();
skeletonData.Slots.TrimExcess(); skeletonData.slots.TrimExcess();
skeletonData.Skins.TrimExcess(); skeletonData.skins.TrimExcess();
skeletonData.Animations.TrimExcess(); skeletonData.animations.TrimExcess();
return skeletonData; return skeletonData;
} }
@ -197,13 +197,13 @@ namespace Spine {
RegionAttachment regionAttachment = attachment as RegionAttachment; RegionAttachment regionAttachment = attachment as RegionAttachment;
if (regionAttachment != null) { if (regionAttachment != null) {
regionAttachment.X = GetFloat(map, "x", 0) * Scale; regionAttachment.x = GetFloat(map, "x", 0) * Scale;
regionAttachment.Y = GetFloat(map, "y", 0) * Scale; regionAttachment.y = GetFloat(map, "y", 0) * Scale;
regionAttachment.ScaleX = GetFloat(map, "scaleX", 1); regionAttachment.scaleX = GetFloat(map, "scaleX", 1);
regionAttachment.ScaleY = GetFloat(map, "scaleY", 1); regionAttachment.scaleY = GetFloat(map, "scaleY", 1);
regionAttachment.Rotation = GetFloat(map, "rotation", 0); regionAttachment.rotation = GetFloat(map, "rotation", 0);
regionAttachment.Width = GetFloat(map, "width", 32) * Scale; regionAttachment.width = GetFloat(map, "width", 32) * Scale;
regionAttachment.Height = GetFloat(map, "height", 32) * Scale; regionAttachment.height = GetFloat(map, "height", 32) * Scale;
regionAttachment.UpdateOffset(); regionAttachment.UpdateOffset();
} }
@ -266,7 +266,7 @@ namespace Spine {
String timelineName = (String)timelineEntry.Key; String timelineName = (String)timelineEntry.Key;
if (timelineName.Equals(TIMELINE_ROTATE)) { if (timelineName.Equals(TIMELINE_ROTATE)) {
RotateTimeline timeline = new RotateTimeline(values.Count); RotateTimeline timeline = new RotateTimeline(values.Count);
timeline.BoneIndex = boneIndex; timeline.boneIndex = boneIndex;
int frameIndex = 0; int frameIndex = 0;
foreach (Dictionary<String, Object> valueMap in values) { foreach (Dictionary<String, Object> valueMap in values) {
@ -276,7 +276,7 @@ namespace Spine {
frameIndex++; frameIndex++;
} }
timelines.Add(timeline); timelines.Add(timeline);
duration = Math.Max(duration, timeline.Frames[timeline.FrameCount * 2 - 2]); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 2 - 2]);
} else if (timelineName.Equals(TIMELINE_TRANSLATE) || timelineName.Equals(TIMELINE_SCALE)) { } else if (timelineName.Equals(TIMELINE_TRANSLATE) || timelineName.Equals(TIMELINE_SCALE)) {
TranslateTimeline timeline; TranslateTimeline timeline;
@ -287,7 +287,7 @@ namespace Spine {
timeline = new TranslateTimeline(values.Count); timeline = new TranslateTimeline(values.Count);
timelineScale = Scale; timelineScale = Scale;
} }
timeline.BoneIndex = boneIndex; timeline.boneIndex = boneIndex;
int frameIndex = 0; int frameIndex = 0;
foreach (Dictionary<String, Object> valueMap in values) { foreach (Dictionary<String, Object> valueMap in values) {
@ -299,7 +299,7 @@ namespace Spine {
frameIndex++; frameIndex++;
} }
timelines.Add(timeline); timelines.Add(timeline);
duration = Math.Max(duration, timeline.Frames[timeline.FrameCount * 3 - 3]); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 3 - 3]);
} else } else
throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"); throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
@ -318,7 +318,7 @@ namespace Spine {
String timelineName = (String)timelineEntry.Key; String timelineName = (String)timelineEntry.Key;
if (timelineName.Equals(TIMELINE_COLOR)) { if (timelineName.Equals(TIMELINE_COLOR)) {
ColorTimeline timeline = new ColorTimeline(values.Count); ColorTimeline timeline = new ColorTimeline(values.Count);
timeline.SlotIndex = slotIndex; timeline.slotIndex = slotIndex;
int frameIndex = 0; int frameIndex = 0;
foreach (Dictionary<String, Object> valueMap in values) { foreach (Dictionary<String, Object> valueMap in values) {
@ -329,11 +329,11 @@ namespace Spine {
frameIndex++; frameIndex++;
} }
timelines.Add(timeline); timelines.Add(timeline);
duration = Math.Max(duration, timeline.Frames[timeline.FrameCount * 5 - 5]); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 5 - 5]);
} else if (timelineName.Equals(TIMELINE_ATTACHMENT)) { } else if (timelineName.Equals(TIMELINE_ATTACHMENT)) {
AttachmentTimeline timeline = new AttachmentTimeline(values.Count); AttachmentTimeline timeline = new AttachmentTimeline(values.Count);
timeline.SlotIndex = slotIndex; timeline.slotIndex = slotIndex;
int frameIndex = 0; int frameIndex = 0;
foreach (Dictionary<String, Object> valueMap in values) { foreach (Dictionary<String, Object> valueMap in values) {
@ -341,7 +341,7 @@ namespace Spine {
timeline.setFrame(frameIndex++, time, (String)valueMap["name"]); timeline.setFrame(frameIndex++, time, (String)valueMap["name"]);
} }
timelines.Add(timeline); timelines.Add(timeline);
duration = Math.Max(duration, timeline.Frames[timeline.FrameCount - 1]); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
} else } else
throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"); throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
@ -363,13 +363,13 @@ namespace Spine {
timeline.setFrame(frameIndex++, (float)eventMap["time"], e); timeline.setFrame(frameIndex++, (float)eventMap["time"], e);
} }
timelines.Add(timeline); timelines.Add(timeline);
duration = Math.Max(duration, timeline.Frames[timeline.FrameCount - 1]); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
} }
if (map.ContainsKey("draworder")) { if (map.ContainsKey("draworder")) {
var values = (List<Object>)map["draworder"]; var values = (List<Object>)map["draworder"];
DrawOrderTimeline timeline = new DrawOrderTimeline(values.Count); DrawOrderTimeline timeline = new DrawOrderTimeline(values.Count);
int slotCount = skeletonData.Slots.Count; int slotCount = skeletonData.slots.Count;
int frameIndex = 0; int frameIndex = 0;
foreach (Dictionary<String, Object> drawOrderMap in values) { foreach (Dictionary<String, Object> drawOrderMap in values) {
int[] drawOrder = new int[slotCount]; int[] drawOrder = new int[slotCount];
@ -396,7 +396,7 @@ namespace Spine {
timeline.setFrame(frameIndex++, (float)drawOrderMap["time"], drawOrder); timeline.setFrame(frameIndex++, (float)drawOrderMap["time"], drawOrder);
} }
timelines.Add(timeline); timelines.Add(timeline);
duration = Math.Max(duration, timeline.Frames[timeline.FrameCount - 1]); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
} }
timelines.TrimExcess(); timelines.TrimExcess();

View File

@ -37,12 +37,14 @@ using System.Collections.Generic;
namespace Spine { namespace Spine {
/** Stores attachments by slot index and attachment name. */ /** Stores attachments by slot index and attachment name. */
public class Skin { public class Skin {
public String Name { get; private set; } internal String name;
public String Name { get { return name; } }
private Dictionary<KeyValuePair<int, String>, Attachment> attachments = new Dictionary<KeyValuePair<int, String>, Attachment>(); private Dictionary<KeyValuePair<int, String>, Attachment> attachments = new Dictionary<KeyValuePair<int, String>, Attachment>();
public Skin (String name) { public Skin (String name) {
if (name == null) throw new ArgumentNullException("name cannot be null."); if (name == null) throw new ArgumentNullException("name cannot be null.");
Name = name; this.name = name;
} }
public void AddAttachment (int slotIndex, String name, Attachment attachment) { public void AddAttachment (int slotIndex, String name, Attachment attachment) {
@ -70,15 +72,15 @@ namespace Spine {
} }
override public String ToString () { override public String ToString () {
return Name; return name;
} }
/** Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached. */ /** Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached. */
internal void AttachAll (Skeleton skeleton, Skin oldSkin) { internal void AttachAll (Skeleton skeleton, Skin oldSkin) {
foreach (KeyValuePair<KeyValuePair<int, String>, Attachment> entry in oldSkin.attachments) { foreach (KeyValuePair<KeyValuePair<int, String>, Attachment> entry in oldSkin.attachments) {
int slotIndex = entry.Key.Key; int slotIndex = entry.Key.Key;
Slot slot = skeleton.Slots[slotIndex]; Slot slot = skeleton.slots[slotIndex];
if (slot.Attachment == entry.Value) { if (slot.attachment == entry.Value) {
Attachment attachment = GetAttachment(slotIndex, entry.Key.Value); Attachment attachment = GetAttachment(slotIndex, entry.Key.Value);
if (attachment != null) slot.Attachment = attachment; if (attachment != null) slot.Attachment = attachment;
} }

View File

@ -35,33 +35,38 @@ using System;
namespace Spine { namespace Spine {
public class Slot { public class Slot {
public SlotData Data { get; private set; } internal SlotData data;
public Bone Bone { get; private set; } internal Bone bone;
public Skeleton Skeleton { get; private set; } internal Skeleton skeleton;
public float R { get; set; } internal float r, g, b, a;
public float G { get; set; } internal float attachmentTime;
public float B { get; set; } internal Attachment attachment;
public float A { get; set; }
public SlotData Data { get { return data; } }
public Bone Bone { get { return bone; } }
public Skeleton Skeleton { get { return skeleton; } }
public float R { get { return r; } set { r = value; } }
public float G { get { return g; } set { g = value; } }
public float B { get { return b; } set { b = value; } }
public float A { get { return a; } set { a = value; } }
/** May be null. */ /** May be null. */
private Attachment attachment;
public Attachment Attachment { public Attachment Attachment {
get { get {
return attachment; return attachment;
} }
set { set {
attachment = value; attachment = value;
attachmentTime = Skeleton.Time; attachmentTime = skeleton.time;
} }
} }
private float attachmentTime;
public float AttachmentTime { public float AttachmentTime {
get { get {
return Skeleton.Time - attachmentTime; return skeleton.time - attachmentTime;
} }
set { set {
attachmentTime = Skeleton.Time - value; attachmentTime = skeleton.time - value;
} }
} }
@ -69,26 +74,26 @@ namespace Spine {
if (data == null) throw new ArgumentNullException("data cannot be null."); if (data == null) throw new ArgumentNullException("data cannot be null.");
if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null."); if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null.");
if (bone == null) throw new ArgumentNullException("bone cannot be null."); if (bone == null) throw new ArgumentNullException("bone cannot be null.");
Data = data; this.data = data;
Skeleton = skeleton; this.skeleton = skeleton;
Bone = bone; this.bone = bone;
SetToSetupPose(); SetToSetupPose();
} }
internal void SetToSetupPose (int slotIndex) { internal void SetToSetupPose (int slotIndex) {
R = Data.R; r = data.r;
G = Data.G; g = data.g;
B = Data.B; b = data.b;
A = Data.A; a = data.a;
Attachment = Data.AttachmentName == null ? null : Skeleton.GetAttachment(slotIndex, Data.AttachmentName); Attachment = data.attachmentName == null ? null : skeleton.GetAttachment(slotIndex, data.attachmentName);
} }
public void SetToSetupPose () { public void SetToSetupPose () {
SetToSetupPose(Skeleton.Data.Slots.IndexOf(Data)); SetToSetupPose(skeleton.data.slots.IndexOf(data));
} }
override public String ToString () { override public String ToString () {
return Data.Name; return data.name;
} }
} }
} }

View File

@ -35,29 +35,31 @@ using System;
namespace Spine { namespace Spine {
public class SlotData { public class SlotData {
public String Name { get; private set; } internal String name;
public BoneData BoneData { get; private set; } internal BoneData boneData;
public float R { get; set; } internal float r = 1, g = 1, b = 1, a = 1;
public float G { get; set; } internal String attachmentName;
public float B { get; set; } internal bool additiveBlending;
public float A { get; set; }
public String Name { get { return name; } }
public BoneData BoneData { get { return boneData; } }
public float R { get { return r; } set { r = value; } }
public float G { get { return g; } set { g = value; } }
public float B { get { return b; } set { b = value; } }
public float A { get { return a; } set { a = value; } }
/** @param attachmentName May be null. */ /** @param attachmentName May be null. */
public String AttachmentName { get; set; } public String AttachmentName { get { return attachmentName; } set { attachmentName = value; } }
public bool AdditiveBlending { get; set; } public bool AdditiveBlending { get { return additiveBlending; } set { additiveBlending = value; } }
public SlotData (String name, BoneData boneData) { public SlotData (String name, BoneData boneData) {
if (name == null) throw new ArgumentNullException("name cannot be null."); if (name == null) throw new ArgumentNullException("name cannot be null.");
if (boneData == null) throw new ArgumentNullException("boneData cannot be null."); if (boneData == null) throw new ArgumentNullException("boneData cannot be null.");
Name = name; this.name = name;
BoneData = boneData; this.boneData = boneData;
R = 1;
G = 1;
B = 1;
A = 1;
} }
override public String ToString () { override public String ToString () {
return Name; return name;
} }
} }
} }