浏览代码

Use lastTime for AttachmentTimeline.

closes #221
NathanSweet 11 年之前
父节点
当前提交
a35223328e
共有 1 个文件被更改,包括 29 次插入10 次删除
  1. 29 10
      spine-libgdx/src/com/esotericsoftware/spine/Animation.java

+ 29 - 10
spine-libgdx/src/com/esotericsoftware/spine/Animation.java

@@ -120,6 +120,23 @@ public class Animation {
 		}
 	}
 
+	/** @param target After the first and before the last value.
+	 * @return index of first value greater than the target. */
+	static int binarySearch (float[] values, float target) {
+		int low = 0;
+		int high = values.length - 2;
+		if (high == 0) return 1;
+		int current = high >>> 1;
+		while (true) {
+			if (values[(current + 1)] <= target)
+				low = current + 1;
+			else
+				high = current;
+			if (low == high) return (low + 1);
+			current = (low + high) >>> 1;
+		}
+	}
+
 	static int linearSearch (float[] values, float target, int step) {
 		for (int i = 0, last = values.length - step; i <= last; i += step)
 			if (values[i] > target) return i;
@@ -127,7 +144,8 @@ public class Animation {
 	}
 
 	static public interface Timeline {
-		/** Sets the value(s) for the specified time. */
+		/** Sets the value(s) for the specified time.
+		 * @param events May be null. */
 		public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha);
 	}
 
@@ -486,13 +504,14 @@ public class Animation {
 
 		public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha) {
 			float[] frames = this.frames;
-			if (time < frames[0]) return; // Time is before first frame.
+			if (time < frames[0]) {
+				if (lastTime > time) apply(skeleton, lastTime, Integer.MAX_VALUE, null, 0);
+				return;
+			} else if (lastTime > time) //
+				lastTime = -1;
 
-			int frameIndex;
-			if (time >= frames[frames.length - 1]) // Time is after last frame.
-				frameIndex = frames.length - 1;
-			else
-				frameIndex = binarySearch(frames, time, 1) - 1;
+			int frameIndex = time >= frames[frames.length - 1] ? frames.length - 1 : binarySearch(frames, time, 1) - 1;
+			if (frames[frameIndex] <= lastTime) return;
 
 			String attachmentName = attachmentNames[frameIndex];
 			skeleton.slots.get(slotIndex).setAttachment(
@@ -544,7 +563,7 @@ public class Animation {
 			if (lastTime < frames[0])
 				frameIndex = 0;
 			else {
-				frameIndex = binarySearch(frames, lastTime, 1);
+				frameIndex = binarySearch(frames, lastTime);
 				float frame = frames[frameIndex];
 				while (frameIndex > 0) { // Fire multiple events with the same frame.
 					if (frames[frameIndex - 1] != frame) break;
@@ -592,7 +611,7 @@ public class Animation {
 			if (time >= frames[frames.length - 1]) // Time is after last frame.
 				frameIndex = frames.length - 1;
 			else
-				frameIndex = binarySearch(frames, time, 1) - 1;
+				frameIndex = binarySearch(frames, time) - 1;
 
 			Array<Slot> drawOrder = skeleton.drawOrder;
 			Array<Slot> slots = skeleton.slots;
@@ -676,7 +695,7 @@ public class Animation {
 			}
 
 			// Interpolate between the previous frame and the current frame.
-			int frameIndex = binarySearch(frames, time, 1);
+			int frameIndex = binarySearch(frames, time);
 			float frameTime = frames[frameIndex];
 			float percent = MathUtils.clamp(1 - (time - frameTime) / (frames[frameIndex - 1] - frameTime), 0, 1);
 			percent = getCurvePercent(frameIndex - 1, percent);