Jelajahi Sumber

Mix from closest animation if setting an animation during a mix.

NathanSweet 11 tahun lalu
induk
melakukan
71956544ba

+ 7 - 1
spine-as3/spine-as3/src/spine/animation/AnimationState.as

@@ -146,6 +146,7 @@ public class AnimationState {
 	private function setCurrent (index:int, entry:TrackEntry) : void {
 		var current:TrackEntry = expandToIndex(index);
 		if (current) {
+			var previous:TrackEntry = current.previous;
 			current.previous = null;
 
 			if (current.onEnd != null) current.onEnd(index);
@@ -154,7 +155,12 @@ public class AnimationState {
 			entry.mixDuration = _data.getMix(current.animation, entry.animation);
 			if (entry.mixDuration > 0) {
 				entry.mixTime = 0;
-				entry.previous = current;
+				// If a mix is in progress, mix from the closest animation.
+				if (previous != null && current.mixTime / current.mixDuration < 0.5) {
+					entry.previous = previous;
+					previous = current;
+				} else
+					entry.previous = current;
 			}
 		}
 		

+ 11 - 6
spine-c/src/spine/AnimationState.c

@@ -153,7 +153,7 @@ void spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
 		}
 
 		/* Check if completed the animation or a loop iteration. */
-		if (current->loop ? (FMOD(current->lastTime, current->endTime) > FMOD(time, current->endTime)) //
+		if (current->loop ? (FMOD(current->lastTime, current->endTime) > FMOD(time, current->endTime))
 				: (current->lastTime < current->endTime && time >= current->endTime)) {
 			int count = (int)(time / current->endTime);
 			if (current->listener) current->listener(self, i, ANIMATION_COMPLETE, 0, count);
@@ -201,10 +201,8 @@ spTrackEntry* _spAnimationState_expandToIndex (spAnimationState* self, int index
 void _spAnimationState_setCurrent (spAnimationState* self, int index, spTrackEntry* entry) {
 	spTrackEntry* current = _spAnimationState_expandToIndex(self, index);
 	if (current) {
-		if (current->previous) {
-			_spTrackEntry_dispose(current->previous);
-			current->previous = 0;
-		}
+		spTrackEntry* previous = current->previous;
+		current->previous = 0;
 
 		if (current->listener) current->listener(self, index, ANIMATION_END, 0, 0);
 		if (self->listener) self->listener(self, index, ANIMATION_END, 0, 0);
@@ -212,9 +210,16 @@ void _spAnimationState_setCurrent (spAnimationState* self, int index, spTrackEnt
 		entry->mixDuration = spAnimationStateData_getMix(self->data, current->animation, entry->animation);
 		if (entry->mixDuration > 0) {
 			entry->mixTime = 0;
-			entry->previous = current;
+			/* If a mix is in progress, mix from the closest animation. */
+			if (previous && current->mixTime / current->mixDuration < 0.5f) {
+				entry->previous = previous;
+				previous = current;
+			} else
+				entry->previous = current;
 		} else
 			_spTrackEntry_dispose(current);
+
+		if (previous) _spTrackEntry_dispose(previous);
 	}
 
 	self->tracks[index] = entry;

+ 6 - 1
spine-csharp/src/AnimationState.cs

@@ -154,6 +154,7 @@ namespace Spine {
 		private void SetCurrent (int index, TrackEntry entry) {
 			TrackEntry current = ExpandToIndex(index);
 			if (current != null) {
+				TrackEntry previous = current.previous;
 				current.previous = null;
 
 				current.OnEnd(this, index);
@@ -162,7 +163,11 @@ namespace Spine {
 				entry.mixDuration = data.GetMix(current.animation, entry.animation);
 				if (entry.mixDuration > 0) {
 					entry.mixTime = 0;
-					entry.previous = current;
+					// If a mix is in progress, mix from the closest animation.
+					if (previous != null && current.mixTime / current.mixDuration < 0.5f)
+						entry.previous = previous;
+					else
+						entry.previous = current;
 				}
 			}
 

+ 6 - 1
spine-js/spine.js

@@ -1057,6 +1057,7 @@ spine.AnimationState.prototype = {
 	setCurrent: function (index, entry) {
 		var current = this._expandToIndex(index);
 		if (current) {
+			var previous = current.previous;
 			current.previous = null;
 
 			if (current.onEnd != null) current.onEnd(index);
@@ -1065,7 +1066,11 @@ spine.AnimationState.prototype = {
 			entry.mixDuration = this.data.getMix(current.animation, entry.animation);
 			if (entry.mixDuration > 0) {
 				entry.mixTime = 0;
-				entry.previous = current;
+				// If a mix is in progress, mix from the closest animation.
+				if (previous && current.mixTime / current.mixDuration < 0.5)
+					entry.previous = previous;
+				else
+					entry.previous = current;
 			}
 		}
 

+ 10 - 5
spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java

@@ -169,10 +169,8 @@ public class AnimationState {
 	private void setCurrent (int index, TrackEntry entry) {
 		TrackEntry current = expandToIndex(index);
 		if (current != null) {
-			if (current.previous != null) {
-				trackEntryPool.free(current.previous);
-				current.previous = null;
-			}
+			TrackEntry previous = current.previous;
+			current.previous = null;
 
 			if (current.listener != null) current.listener.end(index);
 			for (int i = 0, n = listeners.size; i < n; i++)
@@ -181,9 +179,16 @@ public class AnimationState {
 			entry.mixDuration = data.getMix(current.animation, entry.animation);
 			if (entry.mixDuration > 0) {
 				entry.mixTime = 0;
-				entry.previous = current;
+				// If a mix is in progress, mix from the closest animation.
+				if (previous != null && current.mixTime / current.mixDuration < 0.5f) {
+					entry.previous = previous;
+					previous = current;
+				} else
+					entry.previous = current;
 			} else
 				trackEntryPool.free(current);
+
+			if (previous != null) trackEntryPool.free(previous);
 		}
 
 		tracks.set(index, entry);

+ 7 - 1
spine-lua/AnimationState.lua

@@ -48,6 +48,7 @@ function AnimationState.new (data)
 	local function setCurrent (index, entry)
 		local current = self.tracks[index]
 		if current then
+			local previous = current.previous
 			current.previous = nil
 
 			if current.onEnd then current.onEnd(index) end
@@ -56,7 +57,12 @@ function AnimationState.new (data)
 			entry.mixDuration = self.data:getMix(current.animation.name, entry.animation.name)
 			if entry.mixDuration > 0 then
 				entry.mixTime = 0
-				entry.previous = current
+				-- If a mix is in progress, mix from the closest animation.
+				if previous and current.mixTime / current.mixDuration < 0.5 then
+					entry.previous = previous
+				else
+					entry.previous = current
+				end
 			end
 		end