Browse Source

Keyable draw order for spine-csharp.

NathanSweet 12 years ago
parent
commit
a511e267d2

+ 38 - 0
spine-csharp/src/Animation.cs

@@ -412,4 +412,42 @@ namespace Spine {
 				 attachmentName == null ? null : skeleton.GetAttachment(SlotIndex, attachmentName);
 		}
 	}
+
+	public class DrawOrderTimeline : Timeline {
+		public float[] Frames { get; private set; } // time, ...
+		public int[][] DrawOrders { get; private set; }
+		public int FrameCount {
+			get {
+				return Frames.Length;
+			}
+		}
+
+		public DrawOrderTimeline (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;
+		}
+
+		public void Apply (Skeleton skeleton, float time, float alpha) {
+			float[] frames = Frames;
+			if (time < frames[0]) return; // Time is before first frame.
+
+			int frameIndex;
+			if (time >= frames[frames.Length - 1]) // Time is after last frame.
+				frameIndex = frames.Length - 1;
+			else
+				frameIndex = Animation.binarySearch(frames, time, 1) - 1;
+
+			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]];
+		}
+	}
 }

+ 34 - 1
spine-csharp/src/SkeletonJson.cs

@@ -110,7 +110,7 @@ namespace Spine {
 			// Slots.
 			if (root.ContainsKey("slots")) {
 				var slots = (List<Object>)root["slots"];
-				foreach (Dictionary<String, Object> slotMap in (List<Object>)slots) {
+				foreach (Dictionary<String, Object> slotMap in slots) {
 					String slotName = (String)slotMap["name"];
 					String boneName = (String)slotMap["bone"];
 					BoneData boneData = skeletonData.FindBone(boneName);
@@ -308,6 +308,39 @@ namespace Spine {
 							throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
 					}
 				}
+			}
+
+			if (map.ContainsKey("draworder")) {
+				var values = (List<Object>)map["draworder"];
+				DrawOrderTimeline timeline = new DrawOrderTimeline(values.Count);
+				int slotCount = skeletonData.Slots.Count;
+				int frameIndex = 0;
+				foreach (Dictionary<String, Object> drawOrderMap in values) {
+					int[] drawOrder = new int[slotCount];
+					for (int i = slotCount - 1; i >= 0; i--)
+						drawOrder[i] = -1;
+					List<Object> offsets = (List<Object>)drawOrderMap["offsets"];
+					int[] unchanged = new int[slotCount - offsets.Count];
+					int originalIndex = 0, unchangedIndex = 0;
+					foreach (Dictionary<String, Object> offsetMap in offsets) {
+						int slotIndex = skeletonData.FindSlotIndex((String)offsetMap["slot"]);
+						if (slotIndex == -1) throw new Exception("Slot not found: " + offsetMap["slot"]);
+						// Collect unchanged items.
+						while (originalIndex != slotIndex)
+							unchanged[unchangedIndex++] = originalIndex++;
+						// Set changed items.
+						drawOrder[originalIndex + (int)(float)offsetMap["offset"]] = originalIndex++;
+					}
+					// Collect remaining unchanged items.
+					while (originalIndex < slotCount)
+						unchanged[unchangedIndex++] = originalIndex++;
+					// Fill in unchanged items.
+					for (int i = slotCount - 1; i >= 0; i--)
+						if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex];
+					timeline.setFrame(frameIndex++, (float)drawOrderMap["time"], drawOrder);
+				}
+				timelines.Add(timeline);
+				duration = Math.Max(duration, timeline.Frames[timeline.FrameCount - 1]);
 			}
 
 			timelines.TrimExcess();

File diff suppressed because it is too large
+ 0 - 787
spine-xna/example/data/spineboy.json


+ 4 - 3
spine-xna/example/src/ExampleGame.cs

@@ -74,9 +74,10 @@ namespace Spine {
 			}
 
 			state = new AnimationState(stateData);
-			state.SetAnimation("walk", false);
-			state.AddAnimation("jump", false);
-			state.AddAnimation("walk", true);
+			state.SetAnimation("drawOrder", true);
+			//state.SetAnimation("walk", false);
+			//state.AddAnimation("jump", false);
+			//state.AddAnimation("walk", true);
 
 			skeleton.X = 320;
 			skeleton.Y = 440;

Some files were not shown because too many files changed in this diff