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

View File

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

View File

@ -50,12 +50,12 @@ namespace Spine {
RegionAttachment attachment = new RegionAttachment(name);
attachment.RendererObject = region;
attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.rotate);
attachment.RegionOffsetX = region.offsetX;
attachment.RegionOffsetY = region.offsetY;
attachment.RegionWidth = region.width;
attachment.RegionHeight = region.height;
attachment.RegionOriginalWidth = region.originalWidth;
attachment.RegionOriginalHeight = region.originalHeight;
attachment.regionOffsetX = region.offsetX;
attachment.regionOffsetY = region.offsetY;
attachment.regionWidth = region.width;
attachment.regionHeight = region.height;
attachment.regionOriginalWidth = region.originalWidth;
attachment.regionOriginalHeight = region.originalHeight;
return attachment;
case AttachmentType.boundingbox:
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. */
public void ComputeWorldVertices (float x, float y, Bone bone, float[] worldVertices) {
x += bone.WorldX;
y += bone.WorldY;
float m00 = bone.M00;
float m01 = bone.M01;
float m10 = bone.M10;
float m11 = bone.M11;
x += bone.worldX;
y += bone.worldY;
float m00 = bone.m00;
float m01 = bone.m01;
float m10 = bone.m10;
float m11 = bone.m11;
float[] vertices = Vertices;
for (int i = 0, n = vertices.Length; i < n; i += 2) {
float px = vertices[i];

View File

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

View File

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

View File

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

View File

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

View File

@ -110,9 +110,9 @@ namespace Spine {
List<BoundingBoxAttachment> boundingBoxes = BoundingBoxes;
List<Polygon> polygons = Polygons;
List<Slot> slots = skeleton.Slots;
List<Slot> slots = skeleton.slots;
int slotCount = slots.Count;
float x = skeleton.X, y = skeleton.Y;
float x = skeleton.x, y = skeleton.y;
boundingBoxes.Clear();
foreach (Polygon polygon in polygons)
@ -121,7 +121,7 @@ namespace Spine {
for (int i = 0; i < slotCount; i++) {
Slot slot = slots[i];
BoundingBoxAttachment boundingBox = slot.Attachment as BoundingBoxAttachment;
BoundingBoxAttachment boundingBox = slot.attachment as BoundingBoxAttachment;
if (boundingBox == null) continue;
boundingBoxes.Add(boundingBox);
@ -137,7 +137,7 @@ namespace Spine {
int count = boundingBox.Vertices.Length;
polygon.Count = 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 {
public class SkeletonData {
public String Name { get; set; }
public List<BoneData> Bones { get; private set; } // Ordered parents first.
public List<SlotData> Slots { get; private set; } // Setup pose draw order.
public List<Skin> Skins { get; private set; }
/** May be null. */
public Skin DefaultSkin;
public List<EventData> Events { get; private set; }
public List<Animation> Animations { get; private set; }
internal String name;
internal List<BoneData> bones = new List<BoneData>();
internal List<SlotData> slots = new List<SlotData>();
internal List<Skin> skins = new List<Skin>();
internal Skin defaultSkin;
internal List<EventData> events = new List<EventData>();
internal List<Animation> animations = new List<Animation>();
public SkeletonData () {
Bones = new List<BoneData>();
Slots = new List<SlotData>();
Skins = new List<Skin>();
Events = new List<EventData>();
Animations = new List<Animation>();
}
public String Name { get { return name; } set { name = value; } }
public List<BoneData> Bones { get { return bones; } } // Ordered parents first.
public List<SlotData> Slots { get { return slots; } } // Setup pose draw order.
public List<Skin> Skins { get { return skins; } set { skins = value; } }
/** May be null. */
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.
public void AddBone (BoneData bone) {
if (bone == null) throw new ArgumentNullException("bone cannot be null.");
Bones.Add(bone);
bones.Add(bone);
}
/** @return May be null. */
public BoneData FindBone (String boneName) {
if (boneName == null) throw new ArgumentNullException("boneName cannot be null.");
for (int i = 0, n = Bones.Count; i < n; i++) {
BoneData bone = Bones[i];
if (bone.Name == boneName) return bone;
List<BoneData> bones = this.bones;
for (int i = 0, n = bones.Count; i < n; i++) {
BoneData bone = bones[i];
if (bone.name == boneName) return bone;
}
return null;
}
@ -74,8 +75,9 @@ namespace Spine {
/** @return -1 if the bone was not found. */
public int FindBoneIndex (String boneName) {
if (boneName == null) throw new ArgumentNullException("boneName cannot be null.");
for (int i = 0, n = Bones.Count; i < n; i++)
if (Bones[i].Name == boneName) return i;
List<BoneData> bones = this.bones;
for (int i = 0, n = bones.Count; i < n; i++)
if (bones[i].name == boneName) return i;
return -1;
}
@ -83,15 +85,16 @@ namespace Spine {
public void AddSlot (SlotData slot) {
if (slot == null) throw new ArgumentNullException("slot cannot be null.");
Slots.Add(slot);
slots.Add(slot);
}
/** @return May be null. */
public SlotData FindSlot (String slotName) {
if (slotName == null) throw new ArgumentNullException("slotName cannot be null.");
for (int i = 0, n = Slots.Count; i < n; i++) {
SlotData slot = Slots[i];
if (slot.Name == slotName) return slot;
List<SlotData> slots = this.slots;
for (int i = 0, n = slots.Count; i < n; i++) {
SlotData slot = slots[i];
if (slot.name == slotName) return slot;
}
return null;
}
@ -99,8 +102,9 @@ namespace Spine {
/** @return -1 if the bone was not found. */
public int FindSlotIndex (String slotName) {
if (slotName == null) throw new ArgumentNullException("slotName cannot be null.");
for (int i = 0, n = Slots.Count; i < n; i++)
if (Slots[i].Name == slotName) return i;
List<SlotData> slots = this.slots;
for (int i = 0, n = slots.Count; i < n; i++)
if (slots[i].name == slotName) return i;
return -1;
}
@ -108,14 +112,14 @@ namespace Spine {
public void AddSkin (Skin skin) {
if (skin == null) throw new ArgumentNullException("skin cannot be null.");
Skins.Add(skin);
skins.Add(skin);
}
/** @return May be null. */
public Skin FindSkin (String skinName) {
if (skinName == null) throw new ArgumentNullException("skinName cannot be null.");
foreach (Skin skin in Skins)
if (skin.Name == skinName) return skin;
foreach (Skin skin in skins)
if (skin.name == skinName) return skin;
return null;
}
@ -123,13 +127,13 @@ namespace Spine {
public void AddEvent (EventData eventData) {
if (eventData == null) throw new ArgumentNullException("eventData cannot be null.");
Events.Add(eventData);
events.Add(eventData);
}
/** @return May be null. */
public EventData findEvent (String eventDataName) {
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;
return null;
}
@ -138,14 +142,15 @@ namespace Spine {
public void AddAnimation (Animation animation) {
if (animation == null) throw new ArgumentNullException("animation cannot be null.");
Animations.Add(animation);
animations.Add(animation);
}
/** @return May be null. */
public Animation FindAnimation (String animationName) {
if (animationName == null) throw new ArgumentNullException("animationName cannot be null.");
for (int i = 0, n = Animations.Count; i < n; i++) {
Animation animation = Animations[i];
List<Animation> animations = this.animations;
for (int i = 0, n = animations.Count; i < n; i++) {
Animation animation = animations[i];
if (animation.Name == animationName) return animation;
}
return null;
@ -154,7 +159,7 @@ namespace Spine {
// ---
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) {
using (StreamReader reader = new StreamReader(path)) {
SkeletonData skeletonData = ReadSkeletonData(reader);
skeletonData.Name = Path.GetFileNameWithoutExtension(path);
skeletonData.name = Path.GetFileNameWithoutExtension(path);
return skeletonData;
}
}
@ -105,14 +105,14 @@ namespace Spine {
throw new Exception("Parent bone not found: " + boneMap["parent"]);
}
BoneData boneData = new BoneData((String)boneMap["name"], parent);
boneData.Length = GetFloat(boneMap, "length", 0) * Scale;
boneData.X = GetFloat(boneMap, "x", 0) * Scale;
boneData.Y = GetFloat(boneMap, "y", 0) * Scale;
boneData.Rotation = GetFloat(boneMap, "rotation", 0);
boneData.ScaleX = GetFloat(boneMap, "scaleX", 1);
boneData.ScaleY = GetFloat(boneMap, "scaleY", 1);
boneData.InheritScale = GetBoolean(boneMap, "inheritScale", true);
boneData.InheritRotation = GetBoolean(boneMap, "inheritRotation", true);
boneData.length = GetFloat(boneMap, "length", 0) * Scale;
boneData.x = GetFloat(boneMap, "x", 0) * Scale;
boneData.y = GetFloat(boneMap, "y", 0) * Scale;
boneData.rotation = GetFloat(boneMap, "rotation", 0);
boneData.scaleX = GetFloat(boneMap, "scaleX", 1);
boneData.scaleY = GetFloat(boneMap, "scaleY", 1);
boneData.inheritScale = GetBoolean(boneMap, "inheritScale", true);
boneData.inheritRotation = GetBoolean(boneMap, "inheritRotation", true);
skeletonData.AddBone(boneData);
}
@ -128,17 +128,17 @@ namespace Spine {
if (slotMap.ContainsKey("color")) {
String color = (String)slotMap["color"];
slotData.R = ToColor(color, 0);
slotData.G = ToColor(color, 1);
slotData.B = ToColor(color, 2);
slotData.A = ToColor(color, 3);
slotData.r = ToColor(color, 0);
slotData.g = ToColor(color, 1);
slotData.b = ToColor(color, 2);
slotData.a = ToColor(color, 3);
}
if (slotMap.ContainsKey("attachment"))
slotData.AttachmentName = (String)slotMap["attachment"];
slotData.attachmentName = (String)slotMap["attachment"];
if (slotMap.ContainsKey("additive"))
slotData.AdditiveBlending = (bool)slotMap["additive"];
slotData.additiveBlending = (bool)slotMap["additive"];
skeletonData.AddSlot(slotData);
}
@ -156,8 +156,8 @@ namespace Spine {
}
}
skeletonData.AddSkin(skin);
if (skin.Name == "default")
skeletonData.DefaultSkin = skin;
if (skin.name == "default")
skeletonData.defaultSkin = skin;
}
}
@ -179,10 +179,10 @@ namespace Spine {
ReadAnimation(entry.Key, (Dictionary<String, Object>)entry.Value, skeletonData);
}
skeletonData.Bones.TrimExcess();
skeletonData.Slots.TrimExcess();
skeletonData.Skins.TrimExcess();
skeletonData.Animations.TrimExcess();
skeletonData.bones.TrimExcess();
skeletonData.slots.TrimExcess();
skeletonData.skins.TrimExcess();
skeletonData.animations.TrimExcess();
return skeletonData;
}
@ -197,13 +197,13 @@ namespace Spine {
RegionAttachment regionAttachment = attachment as RegionAttachment;
if (regionAttachment != null) {
regionAttachment.X = GetFloat(map, "x", 0) * Scale;
regionAttachment.Y = GetFloat(map, "y", 0) * Scale;
regionAttachment.ScaleX = GetFloat(map, "scaleX", 1);
regionAttachment.ScaleY = GetFloat(map, "scaleY", 1);
regionAttachment.Rotation = GetFloat(map, "rotation", 0);
regionAttachment.Width = GetFloat(map, "width", 32) * Scale;
regionAttachment.Height = GetFloat(map, "height", 32) * Scale;
regionAttachment.x = GetFloat(map, "x", 0) * Scale;
regionAttachment.y = GetFloat(map, "y", 0) * Scale;
regionAttachment.scaleX = GetFloat(map, "scaleX", 1);
regionAttachment.scaleY = GetFloat(map, "scaleY", 1);
regionAttachment.rotation = GetFloat(map, "rotation", 0);
regionAttachment.width = GetFloat(map, "width", 32) * Scale;
regionAttachment.height = GetFloat(map, "height", 32) * Scale;
regionAttachment.UpdateOffset();
}
@ -266,7 +266,7 @@ namespace Spine {
String timelineName = (String)timelineEntry.Key;
if (timelineName.Equals(TIMELINE_ROTATE)) {
RotateTimeline timeline = new RotateTimeline(values.Count);
timeline.BoneIndex = boneIndex;
timeline.boneIndex = boneIndex;
int frameIndex = 0;
foreach (Dictionary<String, Object> valueMap in values) {
@ -276,7 +276,7 @@ namespace Spine {
frameIndex++;
}
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)) {
TranslateTimeline timeline;
@ -287,7 +287,7 @@ namespace Spine {
timeline = new TranslateTimeline(values.Count);
timelineScale = Scale;
}
timeline.BoneIndex = boneIndex;
timeline.boneIndex = boneIndex;
int frameIndex = 0;
foreach (Dictionary<String, Object> valueMap in values) {
@ -299,7 +299,7 @@ namespace Spine {
frameIndex++;
}
timelines.Add(timeline);
duration = Math.Max(duration, timeline.Frames[timeline.FrameCount * 3 - 3]);
duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 3 - 3]);
} else
throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
@ -318,7 +318,7 @@ namespace Spine {
String timelineName = (String)timelineEntry.Key;
if (timelineName.Equals(TIMELINE_COLOR)) {
ColorTimeline timeline = new ColorTimeline(values.Count);
timeline.SlotIndex = slotIndex;
timeline.slotIndex = slotIndex;
int frameIndex = 0;
foreach (Dictionary<String, Object> valueMap in values) {
@ -329,11 +329,11 @@ namespace Spine {
frameIndex++;
}
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)) {
AttachmentTimeline timeline = new AttachmentTimeline(values.Count);
timeline.SlotIndex = slotIndex;
timeline.slotIndex = slotIndex;
int frameIndex = 0;
foreach (Dictionary<String, Object> valueMap in values) {
@ -341,7 +341,7 @@ namespace Spine {
timeline.setFrame(frameIndex++, time, (String)valueMap["name"]);
}
timelines.Add(timeline);
duration = Math.Max(duration, timeline.Frames[timeline.FrameCount - 1]);
duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
} else
throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
@ -363,13 +363,13 @@ namespace Spine {
timeline.setFrame(frameIndex++, (float)eventMap["time"], e);
}
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")) {
var values = (List<Object>)map["draworder"];
DrawOrderTimeline timeline = new DrawOrderTimeline(values.Count);
int slotCount = skeletonData.Slots.Count;
int slotCount = skeletonData.slots.Count;
int frameIndex = 0;
foreach (Dictionary<String, Object> drawOrderMap in values) {
int[] drawOrder = new int[slotCount];
@ -396,7 +396,7 @@ namespace Spine {
timeline.setFrame(frameIndex++, (float)drawOrderMap["time"], drawOrder);
}
timelines.Add(timeline);
duration = Math.Max(duration, timeline.Frames[timeline.FrameCount - 1]);
duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
}
timelines.TrimExcess();

View File

@ -37,12 +37,14 @@ using System.Collections.Generic;
namespace Spine {
/** Stores attachments by slot index and attachment name. */
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>();
public Skin (String name) {
if (name == null) throw new ArgumentNullException("name cannot be null.");
Name = name;
this.name = name;
}
public void AddAttachment (int slotIndex, String name, Attachment attachment) {
@ -70,15 +72,15 @@ namespace Spine {
}
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. */
internal void AttachAll (Skeleton skeleton, Skin oldSkin) {
foreach (KeyValuePair<KeyValuePair<int, String>, Attachment> entry in oldSkin.attachments) {
int slotIndex = entry.Key.Key;
Slot slot = skeleton.Slots[slotIndex];
if (slot.Attachment == entry.Value) {
Slot slot = skeleton.slots[slotIndex];
if (slot.attachment == entry.Value) {
Attachment attachment = GetAttachment(slotIndex, entry.Key.Value);
if (attachment != null) slot.Attachment = attachment;
}

View File

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

View File

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