Эх сурвалжийг харах

Removed mixing from limit, dispose track entries ASAP.

#899
NathanSweet 8 жил өмнө
parent
commit
a69f9d579f

+ 30 - 24
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java

@@ -49,7 +49,7 @@ import com.esotericsoftware.spine.Animation.Timeline;
  * See <a href='http://esotericsoftware.com/spine-applying-animations/'>Applying Animations</a> in the Spine Runtimes Guide. */
  * See <a href='http://esotericsoftware.com/spine-applying-animations/'>Applying Animations</a> in the Spine Runtimes Guide. */
 public class AnimationState {
 public class AnimationState {
 	static private final Animation emptyAnimation = new Animation("<empty>", new Array(0), 0);
 	static private final Animation emptyAnimation = new Animation("<empty>", new Array(0), 0);
-	static private final int SUBSEQUENT = 0, FIRST = 1, DIP = 2;
+	static private final int SUBSEQUENT = 0, FIRST = 1, DIP = 2, DIP_MIX = 3;
 
 
 	private AnimationStateData data;
 	private AnimationStateData data;
 	final Array<TrackEntry> tracks = new Array();
 	final Array<TrackEntry> tracks = new Array();
@@ -117,7 +117,7 @@ public class AnimationState {
 				disposeNext(current);
 				disposeNext(current);
 				continue;
 				continue;
 			}
 			}
-			if (current.mixingFrom != null && updateMixingFrom(current, delta, 2)) {
+			if (current.mixingFrom != null && updateMixingFrom(current, delta)) {
 				// End mixing from entries once all have completed.
 				// End mixing from entries once all have completed.
 				TrackEntry from = current.mixingFrom;
 				TrackEntry from = current.mixingFrom;
 				current.mixingFrom = null;
 				current.mixingFrom = null;
@@ -134,21 +134,18 @@ public class AnimationState {
 	}
 	}
 
 
 	/** Returns true when all mixing from entries are complete. */
 	/** Returns true when all mixing from entries are complete. */
-	private boolean updateMixingFrom (TrackEntry entry, float delta, int animationCount) {
-		TrackEntry from = entry.mixingFrom;
+	private boolean updateMixingFrom (TrackEntry to, float delta) {
+		TrackEntry from = to.mixingFrom;
 		if (from == null) return true;
 		if (from == null) return true;
 
 
-		boolean finished = updateMixingFrom(from, delta, animationCount + 1);
+		boolean finished = updateMixingFrom(from, delta);
 
 
 		// Require mixTime > 0 to ensure the mixing from entry was applied at least once.
 		// Require mixTime > 0 to ensure the mixing from entry was applied at least once.
-		if (entry.mixTime > 0 && (entry.mixTime >= entry.mixDuration || entry.timeScale == 0)) {
-			if (animationCount > 5 && from.mixingFrom == null) {
-				// Limit linked list by speeding up and removing old entries.
-				entry.interruptAlpha = Math.max(0, entry.interruptAlpha - delta * 0.66f);
-				if (entry.interruptAlpha <= 0) {
-					entry.mixingFrom = null;
-					queue.end(from);
-				}
+		if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) {
+			if (from.totalAlpha == 0) {
+				to.mixingFrom = from.mixingFrom;
+				to.interruptAlpha = from.interruptAlpha;
+				queue.end(from);
 			}
 			}
 			return finished;
 			return finished;
 		}
 		}
@@ -156,7 +153,7 @@ public class AnimationState {
 		from.animationLast = from.nextAnimationLast;
 		from.animationLast = from.nextAnimationLast;
 		from.trackLast = from.nextTrackLast;
 		from.trackLast = from.nextTrackLast;
 		from.trackTime += delta * from.timeScale;
 		from.trackTime += delta * from.timeScale;
-		entry.mixTime += delta * entry.timeScale;
+		to.mixTime += delta * to.timeScale;
 		return false;
 		return false;
 	}
 	}
 
 
@@ -196,10 +193,10 @@ public class AnimationState {
 				for (int ii = 0; ii < timelineCount; ii++) {
 				for (int ii = 0; ii < timelineCount; ii++) {
 					Timeline timeline = (Timeline)timelines[ii];
 					Timeline timeline = (Timeline)timelines[ii];
 					if (timeline instanceof RotateTimeline) {
 					if (timeline instanceof RotateTimeline) {
-						applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[ii] > 0, timelinesRotation, ii << 1,
-							firstFrame);
+						applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[ii] >= FIRST, timelinesRotation,
+							ii << 1, firstFrame);
 					} else
 					} else
-						timeline.apply(skeleton, animationLast, animationTime, events, mix, timelineData[ii] > 0, false);
+						timeline.apply(skeleton, animationLast, animationTime, events, mix, timelineData[ii] >= FIRST, false);
 				}
 				}
 			}
 			}
 			queueEvents(current, animationTime);
 			queueEvents(current, animationTime);
@@ -237,6 +234,7 @@ public class AnimationState {
 
 
 		boolean first;
 		boolean first;
 		float alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha;
 		float alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha;
+		from.totalAlpha = 0;
 		for (int i = 0; i < timelineCount; i++) {
 		for (int i = 0; i < timelineCount; i++) {
 			Timeline timeline = (Timeline)timelines[i];
 			Timeline timeline = (Timeline)timelines[i];
 			switch (timelineData[i]) {
 			switch (timelineData[i]) {
@@ -248,13 +246,18 @@ public class AnimationState {
 				first = true;
 				first = true;
 				alpha = alphaMix;
 				alpha = alphaMix;
 				break;
 				break;
+			case DIP:
+				first = true;
+				alpha = alphaDip;
+				break;
 			default:
 			default:
 				first = true;
 				first = true;
 				alpha = alphaDip;
 				alpha = alphaDip;
 				TrackEntry dipMix = (TrackEntry)timelineDipMix[i];
 				TrackEntry dipMix = (TrackEntry)timelineDipMix[i];
-				if (dipMix != null) alpha *= Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration);
+				alpha *= Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration);
 				break;
 				break;
 			}
 			}
+			from.totalAlpha += alpha;
 			if (timeline instanceof RotateTimeline)
 			if (timeline instanceof RotateTimeline)
 				applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 				applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 			else {
 			else {
@@ -694,7 +697,7 @@ public class AnimationState {
 		float eventThreshold, attachmentThreshold, drawOrderThreshold;
 		float eventThreshold, attachmentThreshold, drawOrderThreshold;
 		float animationStart, animationEnd, animationLast, nextAnimationLast;
 		float animationStart, animationEnd, animationLast, nextAnimationLast;
 		float delay, trackTime, trackLast, nextTrackLast, trackEnd, timeScale;
 		float delay, trackTime, trackLast, nextTrackLast, trackEnd, timeScale;
-		float alpha, mixTime, mixDuration, interruptAlpha;
+		float alpha, mixTime, mixDuration, interruptAlpha, totalAlpha;
 		final IntArray timelineData = new IntArray();
 		final IntArray timelineData = new IntArray();
 		final Array<TrackEntry> timelineDipMix = new Array();
 		final Array<TrackEntry> timelineDipMix = new Array();
 		final FloatArray timelinesRotation = new FloatArray();
 		final FloatArray timelinesRotation = new FloatArray();
@@ -720,8 +723,8 @@ public class AnimationState {
 			Object[] timelines = animation.timelines.items;
 			Object[] timelines = animation.timelines.items;
 			int timelinesCount = animation.timelines.size;
 			int timelinesCount = animation.timelines.size;
 			int[] timelineData = this.timelineData.setSize(timelinesCount);
 			int[] timelineData = this.timelineData.setSize(timelinesCount);
+			timelineDipMix.clear();
 			Object[] timelineDipMix = this.timelineDipMix.setSize(timelinesCount);
 			Object[] timelineDipMix = this.timelineDipMix.setSize(timelinesCount);
-
 			outer:
 			outer:
 			for (int i = 0; i < timelinesCount; i++) {
 			for (int i = 0; i < timelinesCount; i++) {
 				int id = ((Timeline)timelines[i]).getPropertyId();
 				int id = ((Timeline)timelines[i]).getPropertyId();
@@ -730,15 +733,18 @@ public class AnimationState {
 				else if (to == null || !to.hasTimeline(id))
 				else if (to == null || !to.hasTimeline(id))
 					timelineData[i] = FIRST;
 					timelineData[i] = FIRST;
 				else {
 				else {
-					timelineData[i] = DIP;
 					for (int ii = mixingToLast; ii >= 0; ii--) {
 					for (int ii = mixingToLast; ii >= 0; ii--) {
 						TrackEntry entry = (TrackEntry)mixingTo[ii];
 						TrackEntry entry = (TrackEntry)mixingTo[ii];
 						if (!entry.hasTimeline(id)) {
 						if (!entry.hasTimeline(id)) {
-							if (entry.mixDuration > 0) timelineDipMix[i] = entry;
-							continue outer;
+							if (entry.mixDuration > 0) {
+								timelineData[i] = DIP_MIX;
+								timelineDipMix[i] = entry;
+								continue outer;
+							}
+							break;
 						}
 						}
 					}
 					}
-					timelineDipMix[i] = null;
+					timelineData[i] = DIP;
 				}
 				}
 			}
 			}
 			return lastEntry;
 			return lastEntry;