Просмотр исходного кода

Merge branch '3.6-beta' of https://github.com/esotericsoftware/spine-runtimes into 3.6-beta

badlogic 8 лет назад
Родитель
Сommit
77291132df
41 измененных файлов с 423 добавлено и 482 удалено
  1. BIN
      spine-as3/spine-as3-example/lib/spine-as3.swc
  2. 2 16
      spine-as3/spine-as3/src/spine/IkConstraint.as
  3. 20 16
      spine-as3/spine-as3/src/spine/animation/AnimationState.as
  4. 11 7
      spine-as3/spine-as3/src/spine/animation/TrackEntry.as
  5. 2 2
      spine-c/spine-c/include/spine/AnimationState.h
  6. 30 22
      spine-c/spine-c/src/spine/AnimationState.c
  7. 2 14
      spine-c/spine-c/src/spine/IkConstraint.c
  8. 3 17
      spine-csharp/src/IkConstraint.cs
  9. 15 16
      spine-csharp/src/Skeleton.cs
  10. 5 3
      spine-csharp/src/Triangulator.cs
  11. 32 28
      spine-lua/AnimationState.lua
  12. 7 21
      spine-lua/IkConstraint.lua
  13. BIN
      spine-starling/spine-starling-example/lib/spine-as3.swc
  14. BIN
      spine-starling/spine-starling/lib/spine-as3.swc
  15. 3 1
      spine-ts/build/spine-all.d.ts
  16. 28 36
      spine-ts/build/spine-all.js
  17. 0 0
      spine-ts/build/spine-all.js.map
  18. 3 1
      spine-ts/build/spine-canvas.d.ts
  19. 28 36
      spine-ts/build/spine-canvas.js
  20. 0 0
      spine-ts/build/spine-canvas.js.map
  21. 3 1
      spine-ts/build/spine-core.d.ts
  22. 28 36
      spine-ts/build/spine-core.js
  23. 0 0
      spine-ts/build/spine-core.js.map
  24. 3 1
      spine-ts/build/spine-threejs.d.ts
  25. 28 36
      spine-ts/build/spine-threejs.js
  26. 0 0
      spine-ts/build/spine-threejs.js.map
  27. 3 1
      spine-ts/build/spine-webgl.d.ts
  28. 28 36
      spine-ts/build/spine-webgl.js
  29. 0 0
      spine-ts/build/spine-webgl.js.map
  30. 3 1
      spine-ts/build/spine-widget.d.ts
  31. 28 36
      spine-ts/build/spine-widget.js
  32. 0 0
      spine-ts/build/spine-widget.js.map
  33. 28 21
      spine-ts/core/src/AnimationState.ts
  34. 3 17
      spine-ts/core/src/IkConstraint.ts
  35. 9 13
      spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs
  36. 6 8
      spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs
  37. 2 2
      spine-unity/Assets/spine-unity/Mesh Generation/SpineMesh.cs
  38. 44 31
      spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs
  39. 11 1
      spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs
  40. 0 1
      spine-unity/Assets/spine-unity/SkeletonAnimation.cs
  41. 5 4
      spine-unity/Assets/spine-unity/SkeletonRenderer.cs

BIN
spine-as3/spine-as3-example/lib/spine-as3.swc


+ 2 - 16
spine-as3/spine-as3/src/spine/IkConstraint.as

@@ -174,22 +174,8 @@ package spine {
 						break outer;
 						break outer;
 					}
 					}
 				}
 				}
-				var minAngle : Number = 0, minDist : Number = Number.MAX_VALUE, minX : Number = 0, minY : Number = 0;
-				var maxAngle : Number = 0, maxDist : Number = 0, maxX : Number = 0, maxY : Number = 0;
-				x = l1 + a;
-				d = x * x;
-				if (d > maxDist) {
-					maxAngle = 0;
-					maxDist = d;
-					maxX = x;
-				}
-				x = l1 - a;
-				d = x * x;
-				if (d < minDist) {
-					minAngle = Math.PI;
-					minDist = d;
-					minX = x;
-				}
+				var minAngle : Number = Math.PI, minX : Number = l1 - a, minDist : Number = minX * minX, minY : Number = 0;
+				var maxAngle : Number = 0, maxX : Number = l1 + a, maxDist : Number = maxX * maxX, maxY : Number = 0;
 				var angle : Number = Math.acos(-a * l1 / (aa - bb));
 				var angle : Number = Math.acos(-a * l1 / (aa - bb));
 				x = a * Math.cos(angle) + l1;
 				x = a * Math.cos(angle) + l1;
 				y = b * Math.sin(angle);
 				y = b * Math.sin(angle);

+ 20 - 16
spine-as3/spine-as3/src/spine/animation/AnimationState.as

@@ -39,6 +39,7 @@ package spine.animation {
 		public static var SUBSEQUENT : int = 0;
 		public static var SUBSEQUENT : int = 0;
 		public static var FIRST : int = 1;
 		public static var FIRST : int = 1;
 		public static var DIP : int = 2;
 		public static var DIP : int = 2;
+		public static var DIP_MIX : int = 3;
 		internal static var emptyAnimation : Animation = new Animation("<empty>", new Vector.<Timeline>(), 0);
 		internal static var emptyAnimation : Animation = new Animation("<empty>", new Vector.<Timeline>(), 0);
 		public var data : AnimationStateData;
 		public var data : AnimationStateData;
 		public var tracks : Vector.<TrackEntry> = new Vector.<TrackEntry>();
 		public var tracks : Vector.<TrackEntry> = new Vector.<TrackEntry>();
@@ -107,7 +108,7 @@ package spine.animation {
 						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.
 					var from : TrackEntry = current.mixingFrom;
 					var from : TrackEntry = current.mixingFrom;
 					current.mixingFrom = null;
 					current.mixingFrom = null;
@@ -123,21 +124,18 @@ package spine.animation {
 			queue.drain();
 			queue.drain();
 		}
 		}
 
 
-		private function updateMixingFrom(entry : TrackEntry, delta : Number, animationCount : int) : Boolean {
-			var from : TrackEntry = entry.mixingFrom;
+		private function updateMixingFrom(to : TrackEntry, delta : Number) : Boolean {
+			var from : TrackEntry = to.mixingFrom;
 			if (from == null) return true;
 			if (from == null) return true;
 
 
-			var finished : Boolean = updateMixingFrom(from, delta, animationCount + 1);
+			var finished : Boolean = 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.66);
-					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;
 			}
 			}
@@ -145,7 +143,7 @@ package spine.animation {
 			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;
 		}
 		}
 
 
@@ -184,9 +182,9 @@ package spine.animation {
 					for (ii = 0; ii < timelineCount; ii++) {
 					for (ii = 0; ii < timelineCount; ii++) {
 						var timeline : Timeline = timelines[ii];
 						var timeline : Timeline = timelines[ii];
 						if (timeline is RotateTimeline) {
 						if (timeline is 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);
@@ -226,6 +224,7 @@ package spine.animation {
 			var alphaDip : Number = from.alpha * to.interruptAlpha;
 			var alphaDip : Number = from.alpha * to.interruptAlpha;
 			var alphaMix : Number = alphaDip * (1 - mix);
 			var alphaMix : Number = alphaDip * (1 - mix);
 			var alpha : Number = 0;
 			var alpha : Number = 0;
+			from.totalAlpha = 0;
 			for (var i : int = 0; i < timelineCount; i++) {
 			for (var i : int = 0; i < timelineCount; i++) {
 				var timeline : Timeline = timelines[i];
 				var timeline : Timeline = timelines[i];
 				switch (timelineData[i]) {
 				switch (timelineData[i]) {
@@ -237,13 +236,18 @@ package spine.animation {
 					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;
 					var dipMix : TrackEntry = timelineDipMix[i];
 					var 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 is RotateTimeline)
 				if (timeline is RotateTimeline)
 					applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 					applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 				else {
 				else {

+ 11 - 7
spine-as3/spine-as3/src/spine/animation/TrackEntry.as

@@ -46,7 +46,7 @@ package spine.animation {
 		public var eventThreshold : Number, attachmentThreshold : Number, drawOrderThreshold : Number;
 		public var eventThreshold : Number, attachmentThreshold : Number, drawOrderThreshold : Number;
 		public var animationStart : Number, animationEnd : Number, animationLast : Number, nextAnimationLast : Number;
 		public var animationStart : Number, animationEnd : Number, animationLast : Number, nextAnimationLast : Number;
 		public var delay : Number, trackTime : Number, trackLast : Number, nextTrackLast : Number, trackEnd : Number, timeScale : Number;
 		public var delay : Number, trackTime : Number, trackLast : Number, nextTrackLast : Number, trackEnd : Number, timeScale : Number;
-		public var alpha : Number, mixTime : Number, mixDuration : Number, interruptAlpha : Number;
+		public var alpha : Number, mixTime : Number, mixDuration : Number, interruptAlpha : Number, totalAlpha : Number;
 		public var timelineData : Vector.<int> = new Vector.<int>();
 		public var timelineData : Vector.<int> = new Vector.<int>();
 		public var timelineDipMix : Vector.<TrackEntry> = new Vector.<TrackEntry>();
 		public var timelineDipMix : Vector.<TrackEntry> = new Vector.<TrackEntry>();
 		public var timelinesRotation : Vector.<Number> = new Vector.<Number>();
 		public var timelinesRotation : Vector.<Number> = new Vector.<Number>();
@@ -89,6 +89,7 @@ package spine.animation {
 			var timelinesCount : int = animation.timelines.length;
 			var timelinesCount : int = animation.timelines.length;
 			var timelineData : Vector.<int> = this.timelineData;
 			var timelineData : Vector.<int> = this.timelineData;
 			timelineData.length = timelinesCount;
 			timelineData.length = timelinesCount;
+			this.timelineDipMix.length = 0;
 			var timelineDipMix : Vector.<TrackEntry> = this.timelineDipMix;
 			var timelineDipMix : Vector.<TrackEntry> = this.timelineDipMix;
 			timelineDipMix.length = timelinesCount;
 			timelineDipMix.length = timelinesCount;
 
 
@@ -101,16 +102,19 @@ package spine.animation {
 					timelineData[i] = AnimationState.SUBSEQUENT;
 					timelineData[i] = AnimationState.SUBSEQUENT;
 				} else if (to == null || !to.hasTimeline(intId))
 				} else if (to == null || !to.hasTimeline(intId))
 					timelineData[i] = AnimationState.FIRST;
 					timelineData[i] = AnimationState.FIRST;
-				else {
-					timelineData[i] = AnimationState.DIP;
+				else {					
 					for (var ii : int = mixingToLast; ii >= 0; ii--) {
 					for (var ii : int = mixingToLast; ii >= 0; ii--) {
 						var entry : TrackEntry = mixingTo[ii];
 						var entry : TrackEntry = mixingTo[ii];
 						if (!entry.hasTimeline(intId)) {
 						if (!entry.hasTimeline(intId)) {
-							if (entry.mixDuration > 0) timelineDipMix[i] = entry;
-							continue outer;
-						}
+							if (entry.mixDuration > 0) {
+								timelineData[i] = AnimationState.DIP_MIX;							
+								timelineDipMix[i] = entry;
+								continue outer;
+							}
+							break;
+						}						
 					}
 					}
-					timelineDipMix[i] = null;
+					timelineData[i] = AnimationState.DIP;
 				}
 				}
 			}
 			}
 			return lastEntry;
 			return lastEntry;

+ 2 - 2
spine-c/spine-c/include/spine/AnimationState.h

@@ -61,7 +61,7 @@ struct spTrackEntry {
 	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;
 	spIntArray* timelineData;
 	spIntArray* timelineData;
 	spTrackEntryArray* timelineDipMix;
 	spTrackEntryArray* timelineDipMix;
 	float* timelinesRotation;
 	float* timelinesRotation;
@@ -79,7 +79,7 @@ struct spTrackEntry {
 		eventThreshold(0), attachmentThreshold(0), drawOrderThreshold(0),
 		eventThreshold(0), attachmentThreshold(0), drawOrderThreshold(0),
 		animationStart(0), animationEnd(0), animationLast(0), nextAnimationLast(0),
 		animationStart(0), animationEnd(0), animationLast(0), nextAnimationLast(0),
 		delay(0), trackTime(0), trackLast(0), nextTrackLast(0), trackEnd(0), timeScale(0),
 		delay(0), trackTime(0), trackLast(0), nextTrackLast(0), trackEnd(0), timeScale(0),
-		alpha(0), mixTime(0), mixDuration(0), interruptAlpha(0),
+		alpha(0), mixTime(0), mixDuration(0), interruptAlpha(0), totalAlpha(0),
 		timelineData(0),
 		timelineData(0),
 		timelineDipMix(0),
 		timelineDipMix(0),
 		timelinesRotation(0),
 		timelinesRotation(0),

+ 30 - 22
spine-c/spine-c/src/spine/AnimationState.c

@@ -35,6 +35,7 @@
 #define SUBSEQUENT 0
 #define SUBSEQUENT 0
 #define FIRST 1
 #define FIRST 1
 #define DIP 2
 #define DIP 2
+#define DIP_MIX 3
 
 
 _SP_ARRAY_IMPLEMENT_TYPE(spTrackEntryArray, spTrackEntry*)
 _SP_ARRAY_IMPLEMENT_TYPE(spTrackEntryArray, spTrackEntry*)
 
 
@@ -48,7 +49,7 @@ void spAnimationState_disposeStatics () {
    the same function order in C as we have method order in Java */
    the same function order in C as we have method order in Java */
 void _spAnimationState_disposeTrackEntry (spTrackEntry* entry);
 void _spAnimationState_disposeTrackEntry (spTrackEntry* entry);
 void _spAnimationState_disposeTrackEntries (spAnimationState* state, spTrackEntry* entry);
 void _spAnimationState_disposeTrackEntries (spAnimationState* state, spTrackEntry* entry);
-int /*boolean*/ _spAnimationState_updateMixingFrom (spAnimationState* self, spTrackEntry* entry, float delta, int animationCount);
+int /*boolean*/ _spAnimationState_updateMixingFrom (spAnimationState* self, spTrackEntry* entry, float delta);
 float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* entry, spSkeleton* skeleton);
 float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* entry, spSkeleton* skeleton);
 void _spAnimationState_applyRotateTimeline (spAnimationState* self, spTimeline* timeline, spSkeleton* skeleton, float time, float alpha, int /*boolean*/ setupPose, float* timelinesRotation, int i, int /*boolean*/ firstFrame);
 void _spAnimationState_applyRotateTimeline (spAnimationState* self, spTimeline* timeline, spSkeleton* skeleton, float time, float alpha, int /*boolean*/ setupPose, float* timelinesRotation, int i, int /*boolean*/ firstFrame);
 void _spAnimationState_queueEvents (spAnimationState* self, spTrackEntry* entry, float animationTime);
 void _spAnimationState_queueEvents (spAnimationState* self, spTrackEntry* entry, float animationTime);
@@ -285,7 +286,7 @@ void spAnimationState_update (spAnimationState* self, float delta) {
 				continue;
 				continue;
 			}
 			}
 		}
 		}
-		if (current->mixingFrom != 0 && _spAnimationState_updateMixingFrom(self, current, delta, 2)) {
+		if (current->mixingFrom != 0 && _spAnimationState_updateMixingFrom(self, current, delta)) {
 			/* End mixing from entries once all have completed. */
 			/* End mixing from entries once all have completed. */
 			spTrackEntry* from = current->mixingFrom;
 			spTrackEntry* from = current->mixingFrom;
 			current->mixingFrom = 0;
 			current->mixingFrom = 0;
@@ -301,23 +302,20 @@ void spAnimationState_update (spAnimationState* self, float delta) {
 	_spEventQueue_drain(internal->queue);
 	_spEventQueue_drain(internal->queue);
 }
 }
 
 
-int /*boolean*/ _spAnimationState_updateMixingFrom (spAnimationState* self, spTrackEntry* entry, float delta, int animationCount) {
-	spTrackEntry* from = entry->mixingFrom;
+int /*boolean*/ _spAnimationState_updateMixingFrom (spAnimationState* self, spTrackEntry* to, float delta) {
+	spTrackEntry* from = to->mixingFrom;
 	int finished;
 	int finished;
 	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
 	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
 	if (!from) return -1;
 	if (!from) return -1;
 
 
-	finished = _spAnimationState_updateMixingFrom(self, from, delta, animationCount + 1);
+	finished = _spAnimationState_updateMixingFrom(self, 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 == 0) {
-			/* Limit linked list by speeding up and removing old entries. */
-			entry->interruptAlpha = MAX(0, entry->interruptAlpha - delta * 0.66f);
-			if (entry->interruptAlpha <= 0) {
-				entry->mixingFrom = 0;
-				_spEventQueue_end(internal->queue, from);
-			}
+	if (to->mixTime > 0 && (to->mixTime >= to->mixDuration || to->timeScale == 0)) {
+		if (from->totalAlpha == 0) {
+			to->mixingFrom = from->mixingFrom;
+			to->interruptAlpha = from->interruptAlpha;
+			_spEventQueue_end(internal->queue, from);
 		}
 		}
 		return finished;
 		return finished;
 	}
 	}
@@ -325,7 +323,7 @@ int /*boolean*/ _spAnimationState_updateMixingFrom (spAnimationState* self, spTr
 	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 0;
 	return 0;
 }
 }
 
 
@@ -371,9 +369,9 @@ void spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
 			for (ii = 0; ii < timelineCount; ii++) {
 			for (ii = 0; ii < timelineCount; ii++) {
 				timeline = timelines[ii];
 				timeline = timelines[ii];
 				if (timeline->type == SP_TIMELINE_ROTATE)
 				if (timeline->type == SP_TIMELINE_ROTATE)
-					_spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, mix, timelineData->items[ii] > 0, timelinesRotation, ii << 1, firstFrame);
+					_spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, mix, timelineData->items[ii] >= FIRST, timelinesRotation, ii << 1, firstFrame);
 				else
 				else
-					spTimeline_apply(timeline, skeleton, animationLast, animationTime, internal->events, &internal->eventsCount, mix, timelineData->items[ii] > 0, 0);
+					spTimeline_apply(timeline, skeleton, animationLast, animationTime, internal->events, &internal->eventsCount, mix, timelineData->items[ii] >= FIRST, 0);
 			}
 			}
 		}
 		}
 		_spAnimationState_queueEvents(self, current, animationTime);
 		_spAnimationState_queueEvents(self, current, animationTime);
@@ -432,6 +430,7 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
 
 
 	first = 0;
 	first = 0;
 	alphaDip = from->alpha * to->interruptAlpha; alphaMix = alphaDip * (1 - mix);
 	alphaDip = from->alpha * to->interruptAlpha; alphaMix = alphaDip * (1 - mix);
+	from->totalAlpha = 0;
 	for (i = 0; i < timelineCount; i++) {
 	for (i = 0; i < timelineCount; i++) {
 		spTimeline* timeline = timelines[i];
 		spTimeline* timeline = timelines[i];
 		switch (timelineData->items[i]) {
 		switch (timelineData->items[i]) {
@@ -443,13 +442,18 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
 				first = 1;
 				first = 1;
 				alpha = alphaMix;
 				alpha = alphaMix;
 				break;
 				break;
+			case DIP:
+				first = 1;
+				alpha = alphaDip;
+				break;
 			default:
 			default:
 				first = 1;
 				first = 1;
 				alpha = alphaDip;
 				alpha = alphaDip;
 				dipMix = timelineDipMix->items[i];
 				dipMix = timelineDipMix->items[i];
-				if (dipMix != 0) alpha *= MAX(0, 1 - dipMix->mixTime / dipMix->mixDuration);
+				alpha *= MAX(0, 1 - dipMix->mixTime / dipMix->mixDuration);
 				break;
 				break;
 		}
 		}
+		from->totalAlpha += alpha;
 		if (timeline->type == SP_TIMELINE_ROTATE)
 		if (timeline->type == SP_TIMELINE_ROTATE)
 			_spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 			_spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 		else {
 		else {
@@ -892,6 +896,7 @@ spTrackEntry* _spTrackEntry_setTimelineData(spTrackEntry* self, spTrackEntry* to
 	timelines = self->animation->timelines;
 	timelines = self->animation->timelines;
 	timelinesCount = self->animation->timelinesCount;
 	timelinesCount = self->animation->timelinesCount;
 	timelineData = spIntArray_setSize(self->timelineData, timelinesCount)->items;
 	timelineData = spIntArray_setSize(self->timelineData, timelinesCount)->items;
+	spTrackEntryArray_clear(self->timelineDipMix);
 	timelineDipMix = spTrackEntryArray_setSize(self->timelineDipMix, timelinesCount)->items;
 	timelineDipMix = spTrackEntryArray_setSize(self->timelineDipMix, timelinesCount)->items;
 
 
 	outer:
 	outer:
@@ -902,16 +907,19 @@ spTrackEntry* _spTrackEntry_setTimelineData(spTrackEntry* self, spTrackEntry* to
 		else if (to == 0 || !_spTrackEntry_hasTimeline(to, id))
 		else if (to == 0 || !_spTrackEntry_hasTimeline(to, id))
 			timelineData[i] = FIRST;
 			timelineData[i] = FIRST;
 		else {
 		else {
-			timelineData[i] = DIP;
 			for (ii = mixingToLast; ii >= 0; ii--) {
 			for (ii = mixingToLast; ii >= 0; ii--) {
 				spTrackEntry* entry = mixingTo[ii];
 				spTrackEntry* entry = mixingTo[ii];
 				if (!_spTrackEntry_hasTimeline(entry, id)) {
 				if (!_spTrackEntry_hasTimeline(entry, id)) {
-					if (entry->mixDuration > 0) timelineDipMix[i] = entry;
-					i++;
-					goto outer;
+					if (entry->mixDuration > 0) {
+						timelineData[i] = DIP_MIX;
+						timelineDipMix[i] = entry;
+						i++;
+						goto outer;
+					}
 				}
 				}
+				break;
 			}
 			}
-			timelineDipMix[i] = 0;
+			timelineData[i] = DIP;
 		}
 		}
 	}
 	}
 	return lastEntry;
 	return lastEntry;

+ 2 - 14
spine-c/spine-c/src/spine/IkConstraint.c

@@ -150,8 +150,8 @@ void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float
 		float aa = a * a, bb = b * b, ll = l1 * l1, dd = tx * tx + ty * ty, ta = ATAN2(ty, tx);
 		float aa = a * a, bb = b * b, ll = l1 * l1, dd = tx * tx + ty * ty, ta = ATAN2(ty, tx);
 		float c0 = bb * ll + aa * dd - aa * bb, c1 = -2 * bb * l1, c2 = bb - aa;
 		float c0 = bb * ll + aa * dd - aa * bb, c1 = -2 * bb * l1, c2 = bb - aa;
 		float d = c1 * c1 - 4 * c2 * c0;
 		float d = c1 * c1 - 4 * c2 * c0;
-		float minAngle = 0, minDist = FLT_MAX, minX = 0, minY = 0;
-		float maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0;
+		float minAngle = PI, minX = l1 - a, minDist = minX * minX, minY = 0;
+		float maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;
 		float x = l1 + a, dist = x * x, angle, y;
 		float x = l1 + a, dist = x * x, angle, y;
 		if (d >= 0) {
 		if (d >= 0) {
 			float q = SQRT(d), r0, r1;
 			float q = SQRT(d), r0, r1;
@@ -166,18 +166,6 @@ void spIkConstraint_apply2 (spBone* parent, spBone* child, float targetX, float
 				goto outer;
 				goto outer;
 			}
 			}
 		}
 		}
-		if (dist > maxDist) {
-			maxAngle = 0;
-			maxDist = dist;
-			maxX = x;
-		}
-		x = l1 - a;
-		dist = x * x;
-		if (dist < minDist) {
-			minAngle = PI;
-			minDist = dist;
-			minX = x;
-		}
 		angle = ACOS(-a * l1 / (aa - bb));
 		angle = ACOS(-a * l1 / (aa - bb));
 		x = a * COS(angle) + l1;
 		x = a * COS(angle) + l1;
 		y = b * SIN(angle);
 		y = b * SIN(angle);

+ 3 - 17
spine-csharp/src/IkConstraint.cs

@@ -176,25 +176,11 @@ namespace Spine {
 						y = (float)Math.Sqrt(dd - r * r) * bendDir;
 						y = (float)Math.Sqrt(dd - r * r) * bendDir;
 						a1 = ta - (float)Math.Atan2(y, r);
 						a1 = ta - (float)Math.Atan2(y, r);
 						a2 = (float)Math.Atan2(y / psy, (r - l1) / psx);
 						a2 = (float)Math.Atan2(y / psy, (r - l1) / psx);
-						goto outer;
+						goto outer; // break outer;
 					}
 					}
 				}
 				}
-				float minAngle = 0, minDist = float.MaxValue, minX = 0, minY = 0;
-				float maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0;
-				x = l1 + a;
-				d = x * x;
-				if (d > maxDist) {
-					maxAngle = 0;
-					maxDist = d;
-					maxX = x;
-				}
-				x = l1 - a;
-				d = x * x;
-				if (d < minDist) {
-					minAngle = (float)Math.PI;
-					minDist = d;
-					minX = x;
-				}
+				float minAngle = MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0;
+				float maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;
 				float angle = (float)Math.Acos(-a * l1 / (aa - bb));
 				float angle = (float)Math.Acos(-a * l1 / (aa - bb));
 				x = a * (float)Math.Cos(angle) + l1;
 				x = a * (float)Math.Cos(angle) + l1;
 				y = b * (float)Math.Sin(angle);
 				y = b * (float)Math.Sin(angle);

+ 15 - 16
spine-csharp/src/Skeleton.cs

@@ -258,7 +258,7 @@ namespace Spine {
 			updateCache.Add(bone);
 			updateCache.Add(bone);
 		}
 		}
 
 
-		private void SortReset (ExposedList<Bone> bones) {
+		private static void SortReset (ExposedList<Bone> bones) {
 			var bonesItems = bones.Items;
 			var bonesItems = bones.Items;
 			for (int i = 0, n = bones.Count; i < n; i++) {
 			for (int i = 0, n = bones.Count; i < n; i++) {
 				Bone bone = bonesItems[i];
 				Bone bone = bonesItems[i];
@@ -309,21 +309,21 @@ namespace Spine {
 			var transformConstraintsItems = this.transformConstraints.Items;
 			var transformConstraintsItems = this.transformConstraints.Items;
 			for (int i = 0, n = transformConstraints.Count; i < n; i++) {
 			for (int i = 0, n = transformConstraints.Count; i < n; i++) {
 				TransformConstraint constraint = transformConstraintsItems[i];
 				TransformConstraint constraint = transformConstraintsItems[i];
-				TransformConstraintData data = constraint.data;
-				constraint.rotateMix = data.rotateMix;
-				constraint.translateMix = data.translateMix;
-				constraint.scaleMix = data.scaleMix;
-				constraint.shearMix = data.shearMix;
+				TransformConstraintData constraintData = constraint.data;
+				constraint.rotateMix = constraintData.rotateMix;
+				constraint.translateMix = constraintData.translateMix;
+				constraint.scaleMix = constraintData.scaleMix;
+				constraint.shearMix = constraintData.shearMix;
 			}
 			}
 
 
 			var pathConstraintItems = this.pathConstraints.Items;
 			var pathConstraintItems = this.pathConstraints.Items;
 			for (int i = 0, n = pathConstraints.Count; i < n; i++) {
 			for (int i = 0, n = pathConstraints.Count; i < n; i++) {
 				PathConstraint constraint = pathConstraintItems[i];
 				PathConstraint constraint = pathConstraintItems[i];
-				PathConstraintData data = constraint.data;
-				constraint.position = data.position;
-				constraint.spacing = data.spacing;
-				constraint.rotateMix = data.rotateMix;
-				constraint.translateMix = data.translateMix;
+				PathConstraintData constraintData = constraint.data;
+				constraint.position = constraintData.position;
+				constraint.spacing = constraintData.spacing;
+				constraint.rotateMix = constraintData.rotateMix;
+				constraint.translateMix = constraintData.translateMix;
 			}
 			}
 		}
 		}
 
 
@@ -384,9 +384,9 @@ namespace Spine {
 
 
 		/// <summary>Sets a skin by name (see SetSkin).</summary>
 		/// <summary>Sets a skin by name (see SetSkin).</summary>
 		public void SetSkin (string skinName) {
 		public void SetSkin (string skinName) {
-			Skin skin = data.FindSkin(skinName);
-			if (skin == null) throw new ArgumentException("Skin not found: " + skinName, "skinName");
-			SetSkin(skin);
+			Skin foundSkin = data.FindSkin(skinName);
+			if (foundSkin == null) throw new ArgumentException("Skin not found: " + skinName, "skinName");
+			SetSkin(foundSkin);
 		}
 		}
 
 
 		/// <summary>Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default 
 		/// <summary>Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default 
@@ -424,8 +424,7 @@ namespace Spine {
 				Attachment attachment = skin.GetAttachment(slotIndex, attachmentName);
 				Attachment attachment = skin.GetAttachment(slotIndex, attachmentName);
 				if (attachment != null) return attachment;
 				if (attachment != null) return attachment;
 			}
 			}
-			if (data.defaultSkin != null) return data.defaultSkin.GetAttachment(slotIndex, attachmentName);
-			return null;
+			return data.defaultSkin != null ? data.defaultSkin.GetAttachment(slotIndex, attachmentName) : null;
 		}
 		}
 
 
 		/// <param name="attachmentName">May be null.</param>
 		/// <param name="attachmentName">May be null.</param>

+ 5 - 3
spine-csharp/src/Triangulator.cs

@@ -1,4 +1,4 @@
-/******************************************************************************
+/******************************************************************************
  * Spine Runtimes Software License v2.5
  * Spine Runtimes Software License v2.5
  *
  *
  * Copyright (c) 2013-2016, Esoteric Software
  * Copyright (c) 2013-2016, Esoteric Software
@@ -64,8 +64,9 @@ namespace Spine {
 			while (vertexCount > 3) {
 			while (vertexCount > 3) {
 				// Find ear tip.
 				// Find ear tip.
 				int previous = vertexCount - 1, i = 0, next = 1;
 				int previous = vertexCount - 1, i = 0, next = 1;
+
+				// outer:
 				while (true) {
 				while (true) {
-				outer:
 					if (!isConcave[i]) {
 					if (!isConcave[i]) {
 						int p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1;
 						int p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1;
 						float p1x = vertices[p1], p1y = vertices[p1 + 1];
 						float p1x = vertices[p1], p1y = vertices[p1 + 1];
@@ -77,7 +78,7 @@ namespace Spine {
 							float vx = vertices[v], vy = vertices[v + 1];
 							float vx = vertices[v], vy = vertices[v + 1];
 							if (PositiveArea(p3x, p3y, p1x, p1y, vx, vy)) {
 							if (PositiveArea(p3x, p3y, p1x, p1y, vx, vy)) {
 								if (PositiveArea(p1x, p1y, p2x, p2y, vx, vy)) {
 								if (PositiveArea(p1x, p1y, p2x, p2y, vx, vy)) {
-									if (PositiveArea(p2x, p2y, p3x, p3y, vx, vy)) goto outer;
+									if (PositiveArea(p2x, p2y, p3x, p3y, vx, vy)) goto outer; // break outer;
 								}
 								}
 							}
 							}
 						}
 						}
@@ -96,6 +97,7 @@ namespace Spine {
 					i = next;
 					i = next;
 					next = (next + 1) % vertexCount;
 					next = (next + 1) % vertexCount;
 				}
 				}
+				outer:
 
 
 				// Cut ear tip.
 				// Cut ear tip.
 				triangles.Add(indices[(vertexCount + i - 1) % vertexCount]);
 				triangles.Add(indices[(vertexCount + i - 1) % vertexCount]);

+ 32 - 28
spine-lua/AnimationState.lua

@@ -49,6 +49,7 @@ local EMPTY_ANIMATION = Animation.new("<empty>", {}, 0)
 local SUBSEQUENT = 0
 local SUBSEQUENT = 0
 local FIRST = 1
 local FIRST = 1
 local DIP = 2
 local DIP = 2
+local DIP_MIX = 3;
 
 
 local EventType = {
 local EventType = {
 	start = 0,
 	start = 0,
@@ -171,7 +172,7 @@ function TrackEntry.new ()
 		eventThreshold = 0, attachmentThreshold = 0, drawOrderThreshold = 0,
 		eventThreshold = 0, attachmentThreshold = 0, drawOrderThreshold = 0,
 		animationStart = 0, animationEnd = 0, animationLast = 0, nextAnimationLast = 0,
 		animationStart = 0, animationEnd = 0, animationLast = 0, nextAnimationLast = 0,
 		delay = 0, trackTime = 0, trackLast = 0, nextTrackLast = 0, trackEnd = 0, timeScale = 0,
 		delay = 0, trackTime = 0, trackLast = 0, nextTrackLast = 0, trackEnd = 0, timeScale = 0,
-		alpha = 0, mixTime = 0, mixDuration = 0, interruptAlpha = 0,
+		alpha = 0, mixTime = 0, mixDuration = 0, interruptAlpha = 0, totalAlpha = 0,
 		timelineData = {},
 		timelineData = {},
 		timelineDipMix = {},
 		timelineDipMix = {},
 		timelinesRotation = {}
 		timelinesRotation = {}
@@ -201,19 +202,22 @@ function TrackEntry:setTimelineData(to, mixingToArray, propertyIDs)
 		elseif (to == nil or not to:hasTimeline(id)) then
 		elseif (to == nil or not to:hasTimeline(id)) then
 			timelineData[i] = FIRST
 			timelineData[i] = FIRST
 		else
 		else
-			timelineData[i] = DIP
 			local ii = mixingToLast
 			local ii = mixingToLast
 			while ii > 0 do
 			while ii > 0 do
 				local entry = mixingTo[ii]
 				local entry = mixingTo[ii]
 				local skip = false
 				local skip = false
 				if not entry:hasTimeline(id) then
 				if not entry:hasTimeline(id) then
-					if entry.mixDuration > 0 then timelineDipMix[i] = entry end
-					skip = true
-					break
+					if entry.mixDuration > 0 then 
+						timelineData[i] = DIP_MIX
+						timelineDipMix[i] = entry 
+						skip = true
+						break
+					end
+					break;
 				end
 				end
 				ii = ii - 1
 				ii = ii - 1
 			end
 			end
-			if not skip then timelineDipMix[i] = nil end
+			if not skip then 	timelineData[i] = DIP end
 		end
 		end
 		i = i + 1
 		i = i + 1
 	end
 	end
@@ -313,7 +317,7 @@ function AnimationState:update (delta)
 				end
 				end
 
 
 				if not skip then
 				if not skip then
-					if current.mixingFrom and self:updateMixingFrom(current, delta, 2) then
+					if current.mixingFrom and self:updateMixingFrom(current, delta) then
 						-- End mixing from entries once all have completed.
 						-- End mixing from entries once all have completed.
 						local from = current.mixingFrom
 						local from = current.mixingFrom
 						current.mixingFrom = nil
 						current.mixingFrom = nil
@@ -332,21 +336,18 @@ function AnimationState:update (delta)
 	queue:drain()
 	queue:drain()
 end
 end
 
 
-function AnimationState:updateMixingFrom (entry, delta, animationCount)
-	local from = entry.mixingFrom
+function AnimationState:updateMixingFrom (to, delta)
+	local from = to.mixingFrom
 	if from == nil then return true end
 	if from == nil then return true end
 
 
- 	local finished = self:updateMixingFrom(from, delta, animationCount + 1)
+ 	local finished = self: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 and (entry.mixTime >= entry.mixDuration or entry.timeScale == 0)) then
-		if (animationCount > 5 and from.mixingFrom == nil) then
-			-- Limit linked list by speeding up and removing old entries.
-			entry.interruptAlpha = math_max(0, entry.interruptAlpha - delta * 0.66)
-			if entry.interruptAlpha <= 0 then
-				entry.mixingFrom = nil
-				queue._end(from)
-			end
+	if (to.mixTime > 0 and (to.mixTime >= to.mixDuration or to.timeScale == 0)) then
+		if (from.totalAlpha == 0) then
+			to.mixingFrom = from.mixingFrom
+			to.interruptAlpha = from.interruptAlpha
+			self.queue:_end(from)
 		end
 		end
 		return finished
 		return finished
 	end
 	end
@@ -354,7 +355,7 @@ function AnimationState:updateMixingFrom (entry, delta, animationCount)
 	from.animationLast = from.nextAnimationLast
 	from.animationLast = from.nextAnimationLast
 	from.trackLast = from.nextTrackLast
 	from.trackLast = from.nextTrackLast
 	from.trackTime = from.trackTime + delta * from.timeScale
 	from.trackTime = from.trackTime + delta * from.timeScale
-	entry.mixTime = entry.mixTime + delta * entry.timeScale
+	to.mixTime = to.mixTime + delta * to.timeScale
 	return false;
 	return false;
 end
 end
 
 
@@ -371,10 +372,10 @@ function AnimationState:apply (skeleton)
 			-- Apply mixing from entries first.
 			-- Apply mixing from entries first.
 			local mix = current.alpha
 			local mix = current.alpha
 			if current.mixingFrom then 
 			if current.mixingFrom then 
-              mix = mix * self:applyMixingFrom(current, skeleton)
-            elseif current.trackTime >= current.trackEnd and current.next == nil then
-              mix = 0
-            end
+				mix = mix * self:applyMixingFrom(current, skeleton)
+			elseif current.trackTime >= current.trackEnd and current.next == nil then
+				mix = 0
+			end
 
 
 			-- Apply current entry.
 			-- Apply current entry.
 			local animationLast = current.animationLast
 			local animationLast = current.animationLast
@@ -391,10 +392,10 @@ function AnimationState:apply (skeleton)
 
 
 				for i,timeline in ipairs(timelines) do
 				for i,timeline in ipairs(timelines) do
 					if timeline.type == Animation.TimelineType.rotate then
 					if timeline.type == Animation.TimelineType.rotate then
-						self:applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[i] > 0, timelinesRotation, i * 2,
+						self:applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[i] >= FIRST, timelinesRotation, i * 2,
 							firstFrame) -- FIXME passing ii * 2, indexing correct?
 							firstFrame) -- FIXME passing ii * 2, indexing correct?
 					else
 					else
-						timeline:apply(skeleton, animationLast, animationTime, events, mix, timelineData[i] > 0, false)
+						timeline:apply(skeleton, animationLast, animationTime, events, mix, timelineData[i] >= FIRST, false)
 					end
 					end
 				end
 				end
 			end
 			end
@@ -437,7 +438,7 @@ function AnimationState:applyMixingFrom (to, skeleton)
 	local alphaDip = from.alpha * to.interruptAlpha
 	local alphaDip = from.alpha * to.interruptAlpha
 	local alphaMix = alphaDip * (1 - mix)
 	local alphaMix = alphaDip * (1 - mix)
 	local alpha = 0
 	local alpha = 0
-	
+	from.totalAlpha = 0;
 	local skip = false
 	local skip = false
 	for i,timeline in ipairs(timelines) do
 	for i,timeline in ipairs(timelines) do
 		
 		
@@ -447,13 +448,16 @@ function AnimationState:applyMixingFrom (to, skeleton)
 		elseif timelineData[i] == FIRST then
 		elseif timelineData[i] == FIRST then
 			first = true
 			first = true
 			alpha = alphaMix
 			alpha = alphaMix
+		elseif timelineData[i] == DIP then
+			first = true
+			alpha = alphaDip
 		else
 		else
 			first = true
 			first = true
 			alpha = alphaDip
 			alpha = alphaDip
 			local dipMix = timelineDipMix[i]
 			local dipMix = timelineDipMix[i]
-			if dipMix then alpha = alpha * math_max(0, 1 - dipMix.mixtime / dipMix.mixDuration) end
+			alpha = alpha * math_max(0, 1 - dipMix.mixtime / dipMix.mixDuration)
 		end
 		end
-	
+		from.totalAlpha = from.totalAlpha + alpha
 		if timeline.type == Animation.TimelineType.rotate then
 		if timeline.type == Animation.TimelineType.rotate then
 			self:applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i * 2, firstFrame)
 			self:applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i * 2, firstFrame)
 		else
 		else

+ 7 - 21
spine-lua/IkConstraint.lua

@@ -208,28 +208,14 @@ function IkConstraint:apply2 (parent, child, targetX, targetY, bendDir, alpha)
 			end
 			end
 		end
 		end
 		if not skip then
 		if not skip then
-			local minAngle = 0
-			local minDist = 9999999999
-			local minX = 0
-			local minY = 0
+			local minAngle = math_pi
+			local minX = l1 - a
+			local minDist = minX * minX
+			local minY = 0;
 			local maxAngle = 0
 			local maxAngle = 0
-			local maxDist = 0
-			local maxX = 0
-			local maxY = 0
-			x = l1 + a
-			d = x * x
-			if d > maxDist then
-				maxAngle = 0
-				maxDist = d
-				maxX = x
-			end
-			x = l1 - a
-			d = x * x
-			if d < minDist then
-				minAngle = math_pi
-				minDist = d
-				minX = x
-			end
+			local maxX = l1 + a
+			local maxDist = maxX * maxX
+			local maxY = 0			
 			local angle = math_acos(-a * l1 / (aa - bb))
 			local angle = math_acos(-a * l1 / (aa - bb))
 			x = a * math_cos(angle) + l1
 			x = a * math_cos(angle) + l1
 			y = b * math_sin(angle)
 			y = b * math_sin(angle)

BIN
spine-starling/spine-starling-example/lib/spine-as3.swc


BIN
spine-starling/spine-starling/lib/spine-as3.swc


+ 3 - 1
spine-ts/build/spine-all.d.ts

@@ -231,6 +231,7 @@ declare module spine {
 		static SUBSEQUENT: number;
 		static SUBSEQUENT: number;
 		static FIRST: number;
 		static FIRST: number;
 		static DIP: number;
 		static DIP: number;
+		static DIP_MIX: number;
 		data: AnimationStateData;
 		data: AnimationStateData;
 		tracks: TrackEntry[];
 		tracks: TrackEntry[];
 		events: Event[];
 		events: Event[];
@@ -243,7 +244,7 @@ declare module spine {
 		trackEntryPool: Pool<TrackEntry>;
 		trackEntryPool: Pool<TrackEntry>;
 		constructor(data: AnimationStateData);
 		constructor(data: AnimationStateData);
 		update(delta: number): void;
 		update(delta: number): void;
-		updateMixingFrom(entry: TrackEntry, delta: number, animationCount: number): boolean;
+		updateMixingFrom(to: TrackEntry, delta: number): boolean;
 		apply(skeleton: Skeleton): void;
 		apply(skeleton: Skeleton): void;
 		applyMixingFrom(to: TrackEntry, skeleton: Skeleton): number;
 		applyMixingFrom(to: TrackEntry, skeleton: Skeleton): number;
 		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
 		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
@@ -292,6 +293,7 @@ declare module spine {
 		mixTime: number;
 		mixTime: number;
 		mixDuration: number;
 		mixDuration: number;
 		interruptAlpha: number;
 		interruptAlpha: number;
+		totalAlpha: number;
 		timelineData: number[];
 		timelineData: number[];
 		timelineDipMix: TrackEntry[];
 		timelineDipMix: TrackEntry[];
 		timelinesRotation: number[];
 		timelinesRotation: number[];

+ 28 - 36
spine-ts/build/spine-all.js

@@ -1100,7 +1100,7 @@ var spine;
 					this.disposeNext(current);
 					this.disposeNext(current);
 					continue;
 					continue;
 				}
 				}
-				if (current.mixingFrom != null && this.updateMixingFrom(current, delta, 2)) {
+				if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
 					var from = current.mixingFrom;
 					var from = current.mixingFrom;
 					current.mixingFrom = null;
 					current.mixingFrom = null;
 					while (from != null) {
 					while (from != null) {
@@ -1112,25 +1112,23 @@ var spine;
 			}
 			}
 			this.queue.drain();
 			this.queue.drain();
 		};
 		};
-		AnimationState.prototype.updateMixingFrom = function (entry, delta, animationCount) {
-			var from = entry.mixingFrom;
+		AnimationState.prototype.updateMixingFrom = function (to, delta) {
+			var from = to.mixingFrom;
 			if (from == null)
 			if (from == null)
 				return true;
 				return true;
-			var finished = this.updateMixingFrom(from, delta, animationCount + 1);
-			if (entry.mixTime > 0 && (entry.mixTime >= entry.mixDuration || entry.timeScale == 0)) {
-				if (animationCount > 5 && from.mixingFrom == null) {
-					entry.interruptAlpha = Math.max(0, entry.interruptAlpha - delta * 0.66);
-					if (entry.interruptAlpha <= 0) {
-						entry.mixingFrom = null;
-						this.queue.end(from);
-					}
+			var finished = this.updateMixingFrom(from, delta);
+			if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) {
+				if (from.totalAlpha == 0) {
+					to.mixingFrom = from.mixingFrom;
+					to.interruptAlpha = from.interruptAlpha;
+					this.queue.end(from);
 				}
 				}
 				return finished;
 				return finished;
 			}
 			}
 			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;
 		};
 		};
 		AnimationState.prototype.apply = function (skeleton) {
 		AnimationState.prototype.apply = function (skeleton) {
@@ -1165,10 +1163,10 @@ var spine;
 					for (var ii = 0; ii < timelineCount; ii++) {
 					for (var ii = 0; ii < timelineCount; ii++) {
 						var timeline = timelines[ii];
 						var timeline = timelines[ii];
 						if (timeline instanceof spine.RotateTimeline) {
 						if (timeline instanceof spine.RotateTimeline) {
-							this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[ii] > 0, timelinesRotation, ii << 1, firstFrame);
+							this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[ii] >= AnimationState.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] >= AnimationState.FIRST, false);
 					}
 					}
 				}
 				}
 				this.queueEvents(current, animationTime);
 				this.queueEvents(current, animationTime);
@@ -1203,6 +1201,7 @@ var spine;
 			var timelinesRotation = from.timelinesRotation;
 			var timelinesRotation = from.timelinesRotation;
 			var first = false;
 			var first = false;
 			var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha;
 			var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha;
+			from.totalAlpha = 0;
 			for (var i = 0; i < timelineCount; i++) {
 			for (var i = 0; i < timelineCount; i++) {
 				var timeline = timelines[i];
 				var timeline = timelines[i];
 				switch (timelineData[i]) {
 				switch (timelineData[i]) {
@@ -1214,14 +1213,18 @@ var spine;
 						first = true;
 						first = true;
 						alpha = alphaMix;
 						alpha = alphaMix;
 						break;
 						break;
+					case AnimationState.DIP:
+						first = true;
+						alpha = alphaDip;
+						break;
 					default:
 					default:
 						first = true;
 						first = true;
 						alpha = alphaDip;
 						alpha = alphaDip;
 						var dipMix = timelineDipMix[i];
 						var dipMix = 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 spine.RotateTimeline)
 				if (timeline instanceof spine.RotateTimeline)
 					this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 					this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 				else {
 				else {
@@ -1533,6 +1536,7 @@ var spine;
 	AnimationState.SUBSEQUENT = 0;
 	AnimationState.SUBSEQUENT = 0;
 	AnimationState.FIRST = 1;
 	AnimationState.FIRST = 1;
 	AnimationState.DIP = 2;
 	AnimationState.DIP = 2;
+	AnimationState.DIP_MIX = 3;
 	spine.AnimationState = AnimationState;
 	spine.AnimationState = AnimationState;
 	var TrackEntry = (function () {
 	var TrackEntry = (function () {
 		function TrackEntry() {
 		function TrackEntry() {
@@ -1560,6 +1564,7 @@ var spine;
 			var timelines = this.animation.timelines;
 			var timelines = this.animation.timelines;
 			var timelinesCount = this.animation.timelines.length;
 			var timelinesCount = this.animation.timelines.length;
 			var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
 			var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
+			this.timelineDipMix.length = 0;
 			var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
 			var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
 			outer: for (var i = 0; i < timelinesCount; i++) {
 			outer: for (var i = 0; i < timelinesCount; i++) {
 				var id = timelines[i].getPropertyId();
 				var id = timelines[i].getPropertyId();
@@ -1568,16 +1573,17 @@ var spine;
 				else if (to == null || !to.hasTimeline(id))
 				else if (to == null || !to.hasTimeline(id))
 					timelineData[i] = AnimationState.FIRST;
 					timelineData[i] = AnimationState.FIRST;
 				else {
 				else {
-					timelineData[i] = AnimationState.DIP;
 					for (var ii = mixingToLast; ii >= 0; ii--) {
 					for (var ii = mixingToLast; ii >= 0; ii--) {
 						var entry = mixingTo[ii];
 						var entry = mixingTo[ii];
 						if (!entry.hasTimeline(id)) {
 						if (!entry.hasTimeline(id)) {
-							if (entry.mixDuration > 0)
+							if (entry.mixDuration > 0) {
+								timelineData[i] = AnimationState.DIP_MIX;
 								timelineDipMix[i] = entry;
 								timelineDipMix[i] = entry;
-							continue outer;
+								continue outer;
+							}
 						}
 						}
 					}
 					}
-					timelineDipMix[i] = null;
+					timelineData[i] = AnimationState.DIP;
 				}
 				}
 			}
 			}
 			return lastEntry;
 			return lastEntry;
@@ -2407,22 +2413,8 @@ var spine;
 						break outer;
 						break outer;
 					}
 					}
 				}
 				}
-				var minAngle = 0, minDist = Number.MAX_VALUE, minX = 0, minY = 0;
-				var maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0;
-				x = l1 + a;
-				d = x * x;
-				if (d > maxDist) {
-					maxAngle = 0;
-					maxDist = d;
-					maxX = x;
-				}
-				x = l1 - a;
-				d = x * x;
-				if (d < minDist) {
-					minAngle = spine.MathUtils.PI;
-					minDist = d;
-					minX = x;
-				}
+				var minAngle = spine.MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0;
+				var maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;
 				var angle = Math.acos(-a * l1 / (aa - bb));
 				var angle = Math.acos(-a * l1 / (aa - bb));
 				x = a * Math.cos(angle) + l1;
 				x = a * Math.cos(angle) + l1;
 				y = b * Math.sin(angle);
 				y = b * Math.sin(angle);

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
spine-ts/build/spine-all.js.map


+ 3 - 1
spine-ts/build/spine-canvas.d.ts

@@ -231,6 +231,7 @@ declare module spine {
 		static SUBSEQUENT: number;
 		static SUBSEQUENT: number;
 		static FIRST: number;
 		static FIRST: number;
 		static DIP: number;
 		static DIP: number;
+		static DIP_MIX: number;
 		data: AnimationStateData;
 		data: AnimationStateData;
 		tracks: TrackEntry[];
 		tracks: TrackEntry[];
 		events: Event[];
 		events: Event[];
@@ -243,7 +244,7 @@ declare module spine {
 		trackEntryPool: Pool<TrackEntry>;
 		trackEntryPool: Pool<TrackEntry>;
 		constructor(data: AnimationStateData);
 		constructor(data: AnimationStateData);
 		update(delta: number): void;
 		update(delta: number): void;
-		updateMixingFrom(entry: TrackEntry, delta: number, animationCount: number): boolean;
+		updateMixingFrom(to: TrackEntry, delta: number): boolean;
 		apply(skeleton: Skeleton): void;
 		apply(skeleton: Skeleton): void;
 		applyMixingFrom(to: TrackEntry, skeleton: Skeleton): number;
 		applyMixingFrom(to: TrackEntry, skeleton: Skeleton): number;
 		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
 		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
@@ -292,6 +293,7 @@ declare module spine {
 		mixTime: number;
 		mixTime: number;
 		mixDuration: number;
 		mixDuration: number;
 		interruptAlpha: number;
 		interruptAlpha: number;
+		totalAlpha: number;
 		timelineData: number[];
 		timelineData: number[];
 		timelineDipMix: TrackEntry[];
 		timelineDipMix: TrackEntry[];
 		timelinesRotation: number[];
 		timelinesRotation: number[];

+ 28 - 36
spine-ts/build/spine-canvas.js

@@ -1100,7 +1100,7 @@ var spine;
 					this.disposeNext(current);
 					this.disposeNext(current);
 					continue;
 					continue;
 				}
 				}
-				if (current.mixingFrom != null && this.updateMixingFrom(current, delta, 2)) {
+				if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
 					var from = current.mixingFrom;
 					var from = current.mixingFrom;
 					current.mixingFrom = null;
 					current.mixingFrom = null;
 					while (from != null) {
 					while (from != null) {
@@ -1112,25 +1112,23 @@ var spine;
 			}
 			}
 			this.queue.drain();
 			this.queue.drain();
 		};
 		};
-		AnimationState.prototype.updateMixingFrom = function (entry, delta, animationCount) {
-			var from = entry.mixingFrom;
+		AnimationState.prototype.updateMixingFrom = function (to, delta) {
+			var from = to.mixingFrom;
 			if (from == null)
 			if (from == null)
 				return true;
 				return true;
-			var finished = this.updateMixingFrom(from, delta, animationCount + 1);
-			if (entry.mixTime > 0 && (entry.mixTime >= entry.mixDuration || entry.timeScale == 0)) {
-				if (animationCount > 5 && from.mixingFrom == null) {
-					entry.interruptAlpha = Math.max(0, entry.interruptAlpha - delta * 0.66);
-					if (entry.interruptAlpha <= 0) {
-						entry.mixingFrom = null;
-						this.queue.end(from);
-					}
+			var finished = this.updateMixingFrom(from, delta);
+			if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) {
+				if (from.totalAlpha == 0) {
+					to.mixingFrom = from.mixingFrom;
+					to.interruptAlpha = from.interruptAlpha;
+					this.queue.end(from);
 				}
 				}
 				return finished;
 				return finished;
 			}
 			}
 			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;
 		};
 		};
 		AnimationState.prototype.apply = function (skeleton) {
 		AnimationState.prototype.apply = function (skeleton) {
@@ -1165,10 +1163,10 @@ var spine;
 					for (var ii = 0; ii < timelineCount; ii++) {
 					for (var ii = 0; ii < timelineCount; ii++) {
 						var timeline = timelines[ii];
 						var timeline = timelines[ii];
 						if (timeline instanceof spine.RotateTimeline) {
 						if (timeline instanceof spine.RotateTimeline) {
-							this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[ii] > 0, timelinesRotation, ii << 1, firstFrame);
+							this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[ii] >= AnimationState.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] >= AnimationState.FIRST, false);
 					}
 					}
 				}
 				}
 				this.queueEvents(current, animationTime);
 				this.queueEvents(current, animationTime);
@@ -1203,6 +1201,7 @@ var spine;
 			var timelinesRotation = from.timelinesRotation;
 			var timelinesRotation = from.timelinesRotation;
 			var first = false;
 			var first = false;
 			var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha;
 			var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha;
+			from.totalAlpha = 0;
 			for (var i = 0; i < timelineCount; i++) {
 			for (var i = 0; i < timelineCount; i++) {
 				var timeline = timelines[i];
 				var timeline = timelines[i];
 				switch (timelineData[i]) {
 				switch (timelineData[i]) {
@@ -1214,14 +1213,18 @@ var spine;
 						first = true;
 						first = true;
 						alpha = alphaMix;
 						alpha = alphaMix;
 						break;
 						break;
+					case AnimationState.DIP:
+						first = true;
+						alpha = alphaDip;
+						break;
 					default:
 					default:
 						first = true;
 						first = true;
 						alpha = alphaDip;
 						alpha = alphaDip;
 						var dipMix = timelineDipMix[i];
 						var dipMix = 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 spine.RotateTimeline)
 				if (timeline instanceof spine.RotateTimeline)
 					this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 					this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 				else {
 				else {
@@ -1533,6 +1536,7 @@ var spine;
 	AnimationState.SUBSEQUENT = 0;
 	AnimationState.SUBSEQUENT = 0;
 	AnimationState.FIRST = 1;
 	AnimationState.FIRST = 1;
 	AnimationState.DIP = 2;
 	AnimationState.DIP = 2;
+	AnimationState.DIP_MIX = 3;
 	spine.AnimationState = AnimationState;
 	spine.AnimationState = AnimationState;
 	var TrackEntry = (function () {
 	var TrackEntry = (function () {
 		function TrackEntry() {
 		function TrackEntry() {
@@ -1560,6 +1564,7 @@ var spine;
 			var timelines = this.animation.timelines;
 			var timelines = this.animation.timelines;
 			var timelinesCount = this.animation.timelines.length;
 			var timelinesCount = this.animation.timelines.length;
 			var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
 			var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
+			this.timelineDipMix.length = 0;
 			var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
 			var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
 			outer: for (var i = 0; i < timelinesCount; i++) {
 			outer: for (var i = 0; i < timelinesCount; i++) {
 				var id = timelines[i].getPropertyId();
 				var id = timelines[i].getPropertyId();
@@ -1568,16 +1573,17 @@ var spine;
 				else if (to == null || !to.hasTimeline(id))
 				else if (to == null || !to.hasTimeline(id))
 					timelineData[i] = AnimationState.FIRST;
 					timelineData[i] = AnimationState.FIRST;
 				else {
 				else {
-					timelineData[i] = AnimationState.DIP;
 					for (var ii = mixingToLast; ii >= 0; ii--) {
 					for (var ii = mixingToLast; ii >= 0; ii--) {
 						var entry = mixingTo[ii];
 						var entry = mixingTo[ii];
 						if (!entry.hasTimeline(id)) {
 						if (!entry.hasTimeline(id)) {
-							if (entry.mixDuration > 0)
+							if (entry.mixDuration > 0) {
+								timelineData[i] = AnimationState.DIP_MIX;
 								timelineDipMix[i] = entry;
 								timelineDipMix[i] = entry;
-							continue outer;
+								continue outer;
+							}
 						}
 						}
 					}
 					}
-					timelineDipMix[i] = null;
+					timelineData[i] = AnimationState.DIP;
 				}
 				}
 			}
 			}
 			return lastEntry;
 			return lastEntry;
@@ -2407,22 +2413,8 @@ var spine;
 						break outer;
 						break outer;
 					}
 					}
 				}
 				}
-				var minAngle = 0, minDist = Number.MAX_VALUE, minX = 0, minY = 0;
-				var maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0;
-				x = l1 + a;
-				d = x * x;
-				if (d > maxDist) {
-					maxAngle = 0;
-					maxDist = d;
-					maxX = x;
-				}
-				x = l1 - a;
-				d = x * x;
-				if (d < minDist) {
-					minAngle = spine.MathUtils.PI;
-					minDist = d;
-					minX = x;
-				}
+				var minAngle = spine.MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0;
+				var maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;
 				var angle = Math.acos(-a * l1 / (aa - bb));
 				var angle = Math.acos(-a * l1 / (aa - bb));
 				x = a * Math.cos(angle) + l1;
 				x = a * Math.cos(angle) + l1;
 				y = b * Math.sin(angle);
 				y = b * Math.sin(angle);

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
spine-ts/build/spine-canvas.js.map


+ 3 - 1
spine-ts/build/spine-core.d.ts

@@ -231,6 +231,7 @@ declare module spine {
 		static SUBSEQUENT: number;
 		static SUBSEQUENT: number;
 		static FIRST: number;
 		static FIRST: number;
 		static DIP: number;
 		static DIP: number;
+		static DIP_MIX: number;
 		data: AnimationStateData;
 		data: AnimationStateData;
 		tracks: TrackEntry[];
 		tracks: TrackEntry[];
 		events: Event[];
 		events: Event[];
@@ -243,7 +244,7 @@ declare module spine {
 		trackEntryPool: Pool<TrackEntry>;
 		trackEntryPool: Pool<TrackEntry>;
 		constructor(data: AnimationStateData);
 		constructor(data: AnimationStateData);
 		update(delta: number): void;
 		update(delta: number): void;
-		updateMixingFrom(entry: TrackEntry, delta: number, animationCount: number): boolean;
+		updateMixingFrom(to: TrackEntry, delta: number): boolean;
 		apply(skeleton: Skeleton): void;
 		apply(skeleton: Skeleton): void;
 		applyMixingFrom(to: TrackEntry, skeleton: Skeleton): number;
 		applyMixingFrom(to: TrackEntry, skeleton: Skeleton): number;
 		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
 		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
@@ -292,6 +293,7 @@ declare module spine {
 		mixTime: number;
 		mixTime: number;
 		mixDuration: number;
 		mixDuration: number;
 		interruptAlpha: number;
 		interruptAlpha: number;
+		totalAlpha: number;
 		timelineData: number[];
 		timelineData: number[];
 		timelineDipMix: TrackEntry[];
 		timelineDipMix: TrackEntry[];
 		timelinesRotation: number[];
 		timelinesRotation: number[];

+ 28 - 36
spine-ts/build/spine-core.js

@@ -1100,7 +1100,7 @@ var spine;
 					this.disposeNext(current);
 					this.disposeNext(current);
 					continue;
 					continue;
 				}
 				}
-				if (current.mixingFrom != null && this.updateMixingFrom(current, delta, 2)) {
+				if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
 					var from = current.mixingFrom;
 					var from = current.mixingFrom;
 					current.mixingFrom = null;
 					current.mixingFrom = null;
 					while (from != null) {
 					while (from != null) {
@@ -1112,25 +1112,23 @@ var spine;
 			}
 			}
 			this.queue.drain();
 			this.queue.drain();
 		};
 		};
-		AnimationState.prototype.updateMixingFrom = function (entry, delta, animationCount) {
-			var from = entry.mixingFrom;
+		AnimationState.prototype.updateMixingFrom = function (to, delta) {
+			var from = to.mixingFrom;
 			if (from == null)
 			if (from == null)
 				return true;
 				return true;
-			var finished = this.updateMixingFrom(from, delta, animationCount + 1);
-			if (entry.mixTime > 0 && (entry.mixTime >= entry.mixDuration || entry.timeScale == 0)) {
-				if (animationCount > 5 && from.mixingFrom == null) {
-					entry.interruptAlpha = Math.max(0, entry.interruptAlpha - delta * 0.66);
-					if (entry.interruptAlpha <= 0) {
-						entry.mixingFrom = null;
-						this.queue.end(from);
-					}
+			var finished = this.updateMixingFrom(from, delta);
+			if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) {
+				if (from.totalAlpha == 0) {
+					to.mixingFrom = from.mixingFrom;
+					to.interruptAlpha = from.interruptAlpha;
+					this.queue.end(from);
 				}
 				}
 				return finished;
 				return finished;
 			}
 			}
 			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;
 		};
 		};
 		AnimationState.prototype.apply = function (skeleton) {
 		AnimationState.prototype.apply = function (skeleton) {
@@ -1165,10 +1163,10 @@ var spine;
 					for (var ii = 0; ii < timelineCount; ii++) {
 					for (var ii = 0; ii < timelineCount; ii++) {
 						var timeline = timelines[ii];
 						var timeline = timelines[ii];
 						if (timeline instanceof spine.RotateTimeline) {
 						if (timeline instanceof spine.RotateTimeline) {
-							this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[ii] > 0, timelinesRotation, ii << 1, firstFrame);
+							this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[ii] >= AnimationState.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] >= AnimationState.FIRST, false);
 					}
 					}
 				}
 				}
 				this.queueEvents(current, animationTime);
 				this.queueEvents(current, animationTime);
@@ -1203,6 +1201,7 @@ var spine;
 			var timelinesRotation = from.timelinesRotation;
 			var timelinesRotation = from.timelinesRotation;
 			var first = false;
 			var first = false;
 			var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha;
 			var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha;
+			from.totalAlpha = 0;
 			for (var i = 0; i < timelineCount; i++) {
 			for (var i = 0; i < timelineCount; i++) {
 				var timeline = timelines[i];
 				var timeline = timelines[i];
 				switch (timelineData[i]) {
 				switch (timelineData[i]) {
@@ -1214,14 +1213,18 @@ var spine;
 						first = true;
 						first = true;
 						alpha = alphaMix;
 						alpha = alphaMix;
 						break;
 						break;
+					case AnimationState.DIP:
+						first = true;
+						alpha = alphaDip;
+						break;
 					default:
 					default:
 						first = true;
 						first = true;
 						alpha = alphaDip;
 						alpha = alphaDip;
 						var dipMix = timelineDipMix[i];
 						var dipMix = 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 spine.RotateTimeline)
 				if (timeline instanceof spine.RotateTimeline)
 					this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 					this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 				else {
 				else {
@@ -1533,6 +1536,7 @@ var spine;
 	AnimationState.SUBSEQUENT = 0;
 	AnimationState.SUBSEQUENT = 0;
 	AnimationState.FIRST = 1;
 	AnimationState.FIRST = 1;
 	AnimationState.DIP = 2;
 	AnimationState.DIP = 2;
+	AnimationState.DIP_MIX = 3;
 	spine.AnimationState = AnimationState;
 	spine.AnimationState = AnimationState;
 	var TrackEntry = (function () {
 	var TrackEntry = (function () {
 		function TrackEntry() {
 		function TrackEntry() {
@@ -1560,6 +1564,7 @@ var spine;
 			var timelines = this.animation.timelines;
 			var timelines = this.animation.timelines;
 			var timelinesCount = this.animation.timelines.length;
 			var timelinesCount = this.animation.timelines.length;
 			var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
 			var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
+			this.timelineDipMix.length = 0;
 			var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
 			var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
 			outer: for (var i = 0; i < timelinesCount; i++) {
 			outer: for (var i = 0; i < timelinesCount; i++) {
 				var id = timelines[i].getPropertyId();
 				var id = timelines[i].getPropertyId();
@@ -1568,16 +1573,17 @@ var spine;
 				else if (to == null || !to.hasTimeline(id))
 				else if (to == null || !to.hasTimeline(id))
 					timelineData[i] = AnimationState.FIRST;
 					timelineData[i] = AnimationState.FIRST;
 				else {
 				else {
-					timelineData[i] = AnimationState.DIP;
 					for (var ii = mixingToLast; ii >= 0; ii--) {
 					for (var ii = mixingToLast; ii >= 0; ii--) {
 						var entry = mixingTo[ii];
 						var entry = mixingTo[ii];
 						if (!entry.hasTimeline(id)) {
 						if (!entry.hasTimeline(id)) {
-							if (entry.mixDuration > 0)
+							if (entry.mixDuration > 0) {
+								timelineData[i] = AnimationState.DIP_MIX;
 								timelineDipMix[i] = entry;
 								timelineDipMix[i] = entry;
-							continue outer;
+								continue outer;
+							}
 						}
 						}
 					}
 					}
-					timelineDipMix[i] = null;
+					timelineData[i] = AnimationState.DIP;
 				}
 				}
 			}
 			}
 			return lastEntry;
 			return lastEntry;
@@ -2407,22 +2413,8 @@ var spine;
 						break outer;
 						break outer;
 					}
 					}
 				}
 				}
-				var minAngle = 0, minDist = Number.MAX_VALUE, minX = 0, minY = 0;
-				var maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0;
-				x = l1 + a;
-				d = x * x;
-				if (d > maxDist) {
-					maxAngle = 0;
-					maxDist = d;
-					maxX = x;
-				}
-				x = l1 - a;
-				d = x * x;
-				if (d < minDist) {
-					minAngle = spine.MathUtils.PI;
-					minDist = d;
-					minX = x;
-				}
+				var minAngle = spine.MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0;
+				var maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;
 				var angle = Math.acos(-a * l1 / (aa - bb));
 				var angle = Math.acos(-a * l1 / (aa - bb));
 				x = a * Math.cos(angle) + l1;
 				x = a * Math.cos(angle) + l1;
 				y = b * Math.sin(angle);
 				y = b * Math.sin(angle);

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
spine-ts/build/spine-core.js.map


+ 3 - 1
spine-ts/build/spine-threejs.d.ts

@@ -231,6 +231,7 @@ declare module spine {
 		static SUBSEQUENT: number;
 		static SUBSEQUENT: number;
 		static FIRST: number;
 		static FIRST: number;
 		static DIP: number;
 		static DIP: number;
+		static DIP_MIX: number;
 		data: AnimationStateData;
 		data: AnimationStateData;
 		tracks: TrackEntry[];
 		tracks: TrackEntry[];
 		events: Event[];
 		events: Event[];
@@ -243,7 +244,7 @@ declare module spine {
 		trackEntryPool: Pool<TrackEntry>;
 		trackEntryPool: Pool<TrackEntry>;
 		constructor(data: AnimationStateData);
 		constructor(data: AnimationStateData);
 		update(delta: number): void;
 		update(delta: number): void;
-		updateMixingFrom(entry: TrackEntry, delta: number, animationCount: number): boolean;
+		updateMixingFrom(to: TrackEntry, delta: number): boolean;
 		apply(skeleton: Skeleton): void;
 		apply(skeleton: Skeleton): void;
 		applyMixingFrom(to: TrackEntry, skeleton: Skeleton): number;
 		applyMixingFrom(to: TrackEntry, skeleton: Skeleton): number;
 		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
 		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
@@ -292,6 +293,7 @@ declare module spine {
 		mixTime: number;
 		mixTime: number;
 		mixDuration: number;
 		mixDuration: number;
 		interruptAlpha: number;
 		interruptAlpha: number;
+		totalAlpha: number;
 		timelineData: number[];
 		timelineData: number[];
 		timelineDipMix: TrackEntry[];
 		timelineDipMix: TrackEntry[];
 		timelinesRotation: number[];
 		timelinesRotation: number[];

+ 28 - 36
spine-ts/build/spine-threejs.js

@@ -1100,7 +1100,7 @@ var spine;
 					this.disposeNext(current);
 					this.disposeNext(current);
 					continue;
 					continue;
 				}
 				}
-				if (current.mixingFrom != null && this.updateMixingFrom(current, delta, 2)) {
+				if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
 					var from = current.mixingFrom;
 					var from = current.mixingFrom;
 					current.mixingFrom = null;
 					current.mixingFrom = null;
 					while (from != null) {
 					while (from != null) {
@@ -1112,25 +1112,23 @@ var spine;
 			}
 			}
 			this.queue.drain();
 			this.queue.drain();
 		};
 		};
-		AnimationState.prototype.updateMixingFrom = function (entry, delta, animationCount) {
-			var from = entry.mixingFrom;
+		AnimationState.prototype.updateMixingFrom = function (to, delta) {
+			var from = to.mixingFrom;
 			if (from == null)
 			if (from == null)
 				return true;
 				return true;
-			var finished = this.updateMixingFrom(from, delta, animationCount + 1);
-			if (entry.mixTime > 0 && (entry.mixTime >= entry.mixDuration || entry.timeScale == 0)) {
-				if (animationCount > 5 && from.mixingFrom == null) {
-					entry.interruptAlpha = Math.max(0, entry.interruptAlpha - delta * 0.66);
-					if (entry.interruptAlpha <= 0) {
-						entry.mixingFrom = null;
-						this.queue.end(from);
-					}
+			var finished = this.updateMixingFrom(from, delta);
+			if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) {
+				if (from.totalAlpha == 0) {
+					to.mixingFrom = from.mixingFrom;
+					to.interruptAlpha = from.interruptAlpha;
+					this.queue.end(from);
 				}
 				}
 				return finished;
 				return finished;
 			}
 			}
 			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;
 		};
 		};
 		AnimationState.prototype.apply = function (skeleton) {
 		AnimationState.prototype.apply = function (skeleton) {
@@ -1165,10 +1163,10 @@ var spine;
 					for (var ii = 0; ii < timelineCount; ii++) {
 					for (var ii = 0; ii < timelineCount; ii++) {
 						var timeline = timelines[ii];
 						var timeline = timelines[ii];
 						if (timeline instanceof spine.RotateTimeline) {
 						if (timeline instanceof spine.RotateTimeline) {
-							this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[ii] > 0, timelinesRotation, ii << 1, firstFrame);
+							this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[ii] >= AnimationState.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] >= AnimationState.FIRST, false);
 					}
 					}
 				}
 				}
 				this.queueEvents(current, animationTime);
 				this.queueEvents(current, animationTime);
@@ -1203,6 +1201,7 @@ var spine;
 			var timelinesRotation = from.timelinesRotation;
 			var timelinesRotation = from.timelinesRotation;
 			var first = false;
 			var first = false;
 			var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha;
 			var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha;
+			from.totalAlpha = 0;
 			for (var i = 0; i < timelineCount; i++) {
 			for (var i = 0; i < timelineCount; i++) {
 				var timeline = timelines[i];
 				var timeline = timelines[i];
 				switch (timelineData[i]) {
 				switch (timelineData[i]) {
@@ -1214,14 +1213,18 @@ var spine;
 						first = true;
 						first = true;
 						alpha = alphaMix;
 						alpha = alphaMix;
 						break;
 						break;
+					case AnimationState.DIP:
+						first = true;
+						alpha = alphaDip;
+						break;
 					default:
 					default:
 						first = true;
 						first = true;
 						alpha = alphaDip;
 						alpha = alphaDip;
 						var dipMix = timelineDipMix[i];
 						var dipMix = 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 spine.RotateTimeline)
 				if (timeline instanceof spine.RotateTimeline)
 					this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 					this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 				else {
 				else {
@@ -1533,6 +1536,7 @@ var spine;
 	AnimationState.SUBSEQUENT = 0;
 	AnimationState.SUBSEQUENT = 0;
 	AnimationState.FIRST = 1;
 	AnimationState.FIRST = 1;
 	AnimationState.DIP = 2;
 	AnimationState.DIP = 2;
+	AnimationState.DIP_MIX = 3;
 	spine.AnimationState = AnimationState;
 	spine.AnimationState = AnimationState;
 	var TrackEntry = (function () {
 	var TrackEntry = (function () {
 		function TrackEntry() {
 		function TrackEntry() {
@@ -1560,6 +1564,7 @@ var spine;
 			var timelines = this.animation.timelines;
 			var timelines = this.animation.timelines;
 			var timelinesCount = this.animation.timelines.length;
 			var timelinesCount = this.animation.timelines.length;
 			var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
 			var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
+			this.timelineDipMix.length = 0;
 			var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
 			var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
 			outer: for (var i = 0; i < timelinesCount; i++) {
 			outer: for (var i = 0; i < timelinesCount; i++) {
 				var id = timelines[i].getPropertyId();
 				var id = timelines[i].getPropertyId();
@@ -1568,16 +1573,17 @@ var spine;
 				else if (to == null || !to.hasTimeline(id))
 				else if (to == null || !to.hasTimeline(id))
 					timelineData[i] = AnimationState.FIRST;
 					timelineData[i] = AnimationState.FIRST;
 				else {
 				else {
-					timelineData[i] = AnimationState.DIP;
 					for (var ii = mixingToLast; ii >= 0; ii--) {
 					for (var ii = mixingToLast; ii >= 0; ii--) {
 						var entry = mixingTo[ii];
 						var entry = mixingTo[ii];
 						if (!entry.hasTimeline(id)) {
 						if (!entry.hasTimeline(id)) {
-							if (entry.mixDuration > 0)
+							if (entry.mixDuration > 0) {
+								timelineData[i] = AnimationState.DIP_MIX;
 								timelineDipMix[i] = entry;
 								timelineDipMix[i] = entry;
-							continue outer;
+								continue outer;
+							}
 						}
 						}
 					}
 					}
-					timelineDipMix[i] = null;
+					timelineData[i] = AnimationState.DIP;
 				}
 				}
 			}
 			}
 			return lastEntry;
 			return lastEntry;
@@ -2407,22 +2413,8 @@ var spine;
 						break outer;
 						break outer;
 					}
 					}
 				}
 				}
-				var minAngle = 0, minDist = Number.MAX_VALUE, minX = 0, minY = 0;
-				var maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0;
-				x = l1 + a;
-				d = x * x;
-				if (d > maxDist) {
-					maxAngle = 0;
-					maxDist = d;
-					maxX = x;
-				}
-				x = l1 - a;
-				d = x * x;
-				if (d < minDist) {
-					minAngle = spine.MathUtils.PI;
-					minDist = d;
-					minX = x;
-				}
+				var minAngle = spine.MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0;
+				var maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;
 				var angle = Math.acos(-a * l1 / (aa - bb));
 				var angle = Math.acos(-a * l1 / (aa - bb));
 				x = a * Math.cos(angle) + l1;
 				x = a * Math.cos(angle) + l1;
 				y = b * Math.sin(angle);
 				y = b * Math.sin(angle);

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
spine-ts/build/spine-threejs.js.map


+ 3 - 1
spine-ts/build/spine-webgl.d.ts

@@ -231,6 +231,7 @@ declare module spine {
 		static SUBSEQUENT: number;
 		static SUBSEQUENT: number;
 		static FIRST: number;
 		static FIRST: number;
 		static DIP: number;
 		static DIP: number;
+		static DIP_MIX: number;
 		data: AnimationStateData;
 		data: AnimationStateData;
 		tracks: TrackEntry[];
 		tracks: TrackEntry[];
 		events: Event[];
 		events: Event[];
@@ -243,7 +244,7 @@ declare module spine {
 		trackEntryPool: Pool<TrackEntry>;
 		trackEntryPool: Pool<TrackEntry>;
 		constructor(data: AnimationStateData);
 		constructor(data: AnimationStateData);
 		update(delta: number): void;
 		update(delta: number): void;
-		updateMixingFrom(entry: TrackEntry, delta: number, animationCount: number): boolean;
+		updateMixingFrom(to: TrackEntry, delta: number): boolean;
 		apply(skeleton: Skeleton): void;
 		apply(skeleton: Skeleton): void;
 		applyMixingFrom(to: TrackEntry, skeleton: Skeleton): number;
 		applyMixingFrom(to: TrackEntry, skeleton: Skeleton): number;
 		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
 		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
@@ -292,6 +293,7 @@ declare module spine {
 		mixTime: number;
 		mixTime: number;
 		mixDuration: number;
 		mixDuration: number;
 		interruptAlpha: number;
 		interruptAlpha: number;
+		totalAlpha: number;
 		timelineData: number[];
 		timelineData: number[];
 		timelineDipMix: TrackEntry[];
 		timelineDipMix: TrackEntry[];
 		timelinesRotation: number[];
 		timelinesRotation: number[];

+ 28 - 36
spine-ts/build/spine-webgl.js

@@ -1100,7 +1100,7 @@ var spine;
 					this.disposeNext(current);
 					this.disposeNext(current);
 					continue;
 					continue;
 				}
 				}
-				if (current.mixingFrom != null && this.updateMixingFrom(current, delta, 2)) {
+				if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
 					var from = current.mixingFrom;
 					var from = current.mixingFrom;
 					current.mixingFrom = null;
 					current.mixingFrom = null;
 					while (from != null) {
 					while (from != null) {
@@ -1112,25 +1112,23 @@ var spine;
 			}
 			}
 			this.queue.drain();
 			this.queue.drain();
 		};
 		};
-		AnimationState.prototype.updateMixingFrom = function (entry, delta, animationCount) {
-			var from = entry.mixingFrom;
+		AnimationState.prototype.updateMixingFrom = function (to, delta) {
+			var from = to.mixingFrom;
 			if (from == null)
 			if (from == null)
 				return true;
 				return true;
-			var finished = this.updateMixingFrom(from, delta, animationCount + 1);
-			if (entry.mixTime > 0 && (entry.mixTime >= entry.mixDuration || entry.timeScale == 0)) {
-				if (animationCount > 5 && from.mixingFrom == null) {
-					entry.interruptAlpha = Math.max(0, entry.interruptAlpha - delta * 0.66);
-					if (entry.interruptAlpha <= 0) {
-						entry.mixingFrom = null;
-						this.queue.end(from);
-					}
+			var finished = this.updateMixingFrom(from, delta);
+			if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) {
+				if (from.totalAlpha == 0) {
+					to.mixingFrom = from.mixingFrom;
+					to.interruptAlpha = from.interruptAlpha;
+					this.queue.end(from);
 				}
 				}
 				return finished;
 				return finished;
 			}
 			}
 			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;
 		};
 		};
 		AnimationState.prototype.apply = function (skeleton) {
 		AnimationState.prototype.apply = function (skeleton) {
@@ -1165,10 +1163,10 @@ var spine;
 					for (var ii = 0; ii < timelineCount; ii++) {
 					for (var ii = 0; ii < timelineCount; ii++) {
 						var timeline = timelines[ii];
 						var timeline = timelines[ii];
 						if (timeline instanceof spine.RotateTimeline) {
 						if (timeline instanceof spine.RotateTimeline) {
-							this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[ii] > 0, timelinesRotation, ii << 1, firstFrame);
+							this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[ii] >= AnimationState.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] >= AnimationState.FIRST, false);
 					}
 					}
 				}
 				}
 				this.queueEvents(current, animationTime);
 				this.queueEvents(current, animationTime);
@@ -1203,6 +1201,7 @@ var spine;
 			var timelinesRotation = from.timelinesRotation;
 			var timelinesRotation = from.timelinesRotation;
 			var first = false;
 			var first = false;
 			var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha;
 			var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha;
+			from.totalAlpha = 0;
 			for (var i = 0; i < timelineCount; i++) {
 			for (var i = 0; i < timelineCount; i++) {
 				var timeline = timelines[i];
 				var timeline = timelines[i];
 				switch (timelineData[i]) {
 				switch (timelineData[i]) {
@@ -1214,14 +1213,18 @@ var spine;
 						first = true;
 						first = true;
 						alpha = alphaMix;
 						alpha = alphaMix;
 						break;
 						break;
+					case AnimationState.DIP:
+						first = true;
+						alpha = alphaDip;
+						break;
 					default:
 					default:
 						first = true;
 						first = true;
 						alpha = alphaDip;
 						alpha = alphaDip;
 						var dipMix = timelineDipMix[i];
 						var dipMix = 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 spine.RotateTimeline)
 				if (timeline instanceof spine.RotateTimeline)
 					this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 					this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 				else {
 				else {
@@ -1533,6 +1536,7 @@ var spine;
 	AnimationState.SUBSEQUENT = 0;
 	AnimationState.SUBSEQUENT = 0;
 	AnimationState.FIRST = 1;
 	AnimationState.FIRST = 1;
 	AnimationState.DIP = 2;
 	AnimationState.DIP = 2;
+	AnimationState.DIP_MIX = 3;
 	spine.AnimationState = AnimationState;
 	spine.AnimationState = AnimationState;
 	var TrackEntry = (function () {
 	var TrackEntry = (function () {
 		function TrackEntry() {
 		function TrackEntry() {
@@ -1560,6 +1564,7 @@ var spine;
 			var timelines = this.animation.timelines;
 			var timelines = this.animation.timelines;
 			var timelinesCount = this.animation.timelines.length;
 			var timelinesCount = this.animation.timelines.length;
 			var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
 			var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
+			this.timelineDipMix.length = 0;
 			var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
 			var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
 			outer: for (var i = 0; i < timelinesCount; i++) {
 			outer: for (var i = 0; i < timelinesCount; i++) {
 				var id = timelines[i].getPropertyId();
 				var id = timelines[i].getPropertyId();
@@ -1568,16 +1573,17 @@ var spine;
 				else if (to == null || !to.hasTimeline(id))
 				else if (to == null || !to.hasTimeline(id))
 					timelineData[i] = AnimationState.FIRST;
 					timelineData[i] = AnimationState.FIRST;
 				else {
 				else {
-					timelineData[i] = AnimationState.DIP;
 					for (var ii = mixingToLast; ii >= 0; ii--) {
 					for (var ii = mixingToLast; ii >= 0; ii--) {
 						var entry = mixingTo[ii];
 						var entry = mixingTo[ii];
 						if (!entry.hasTimeline(id)) {
 						if (!entry.hasTimeline(id)) {
-							if (entry.mixDuration > 0)
+							if (entry.mixDuration > 0) {
+								timelineData[i] = AnimationState.DIP_MIX;
 								timelineDipMix[i] = entry;
 								timelineDipMix[i] = entry;
-							continue outer;
+								continue outer;
+							}
 						}
 						}
 					}
 					}
-					timelineDipMix[i] = null;
+					timelineData[i] = AnimationState.DIP;
 				}
 				}
 			}
 			}
 			return lastEntry;
 			return lastEntry;
@@ -2407,22 +2413,8 @@ var spine;
 						break outer;
 						break outer;
 					}
 					}
 				}
 				}
-				var minAngle = 0, minDist = Number.MAX_VALUE, minX = 0, minY = 0;
-				var maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0;
-				x = l1 + a;
-				d = x * x;
-				if (d > maxDist) {
-					maxAngle = 0;
-					maxDist = d;
-					maxX = x;
-				}
-				x = l1 - a;
-				d = x * x;
-				if (d < minDist) {
-					minAngle = spine.MathUtils.PI;
-					minDist = d;
-					minX = x;
-				}
+				var minAngle = spine.MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0;
+				var maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;
 				var angle = Math.acos(-a * l1 / (aa - bb));
 				var angle = Math.acos(-a * l1 / (aa - bb));
 				x = a * Math.cos(angle) + l1;
 				x = a * Math.cos(angle) + l1;
 				y = b * Math.sin(angle);
 				y = b * Math.sin(angle);

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
spine-ts/build/spine-webgl.js.map


+ 3 - 1
spine-ts/build/spine-widget.d.ts

@@ -231,6 +231,7 @@ declare module spine {
 		static SUBSEQUENT: number;
 		static SUBSEQUENT: number;
 		static FIRST: number;
 		static FIRST: number;
 		static DIP: number;
 		static DIP: number;
+		static DIP_MIX: number;
 		data: AnimationStateData;
 		data: AnimationStateData;
 		tracks: TrackEntry[];
 		tracks: TrackEntry[];
 		events: Event[];
 		events: Event[];
@@ -243,7 +244,7 @@ declare module spine {
 		trackEntryPool: Pool<TrackEntry>;
 		trackEntryPool: Pool<TrackEntry>;
 		constructor(data: AnimationStateData);
 		constructor(data: AnimationStateData);
 		update(delta: number): void;
 		update(delta: number): void;
-		updateMixingFrom(entry: TrackEntry, delta: number, animationCount: number): boolean;
+		updateMixingFrom(to: TrackEntry, delta: number): boolean;
 		apply(skeleton: Skeleton): void;
 		apply(skeleton: Skeleton): void;
 		applyMixingFrom(to: TrackEntry, skeleton: Skeleton): number;
 		applyMixingFrom(to: TrackEntry, skeleton: Skeleton): number;
 		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
 		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
@@ -292,6 +293,7 @@ declare module spine {
 		mixTime: number;
 		mixTime: number;
 		mixDuration: number;
 		mixDuration: number;
 		interruptAlpha: number;
 		interruptAlpha: number;
+		totalAlpha: number;
 		timelineData: number[];
 		timelineData: number[];
 		timelineDipMix: TrackEntry[];
 		timelineDipMix: TrackEntry[];
 		timelinesRotation: number[];
 		timelinesRotation: number[];

+ 28 - 36
spine-ts/build/spine-widget.js

@@ -1100,7 +1100,7 @@ var spine;
 					this.disposeNext(current);
 					this.disposeNext(current);
 					continue;
 					continue;
 				}
 				}
-				if (current.mixingFrom != null && this.updateMixingFrom(current, delta, 2)) {
+				if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
 					var from = current.mixingFrom;
 					var from = current.mixingFrom;
 					current.mixingFrom = null;
 					current.mixingFrom = null;
 					while (from != null) {
 					while (from != null) {
@@ -1112,25 +1112,23 @@ var spine;
 			}
 			}
 			this.queue.drain();
 			this.queue.drain();
 		};
 		};
-		AnimationState.prototype.updateMixingFrom = function (entry, delta, animationCount) {
-			var from = entry.mixingFrom;
+		AnimationState.prototype.updateMixingFrom = function (to, delta) {
+			var from = to.mixingFrom;
 			if (from == null)
 			if (from == null)
 				return true;
 				return true;
-			var finished = this.updateMixingFrom(from, delta, animationCount + 1);
-			if (entry.mixTime > 0 && (entry.mixTime >= entry.mixDuration || entry.timeScale == 0)) {
-				if (animationCount > 5 && from.mixingFrom == null) {
-					entry.interruptAlpha = Math.max(0, entry.interruptAlpha - delta * 0.66);
-					if (entry.interruptAlpha <= 0) {
-						entry.mixingFrom = null;
-						this.queue.end(from);
-					}
+			var finished = this.updateMixingFrom(from, delta);
+			if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) {
+				if (from.totalAlpha == 0) {
+					to.mixingFrom = from.mixingFrom;
+					to.interruptAlpha = from.interruptAlpha;
+					this.queue.end(from);
 				}
 				}
 				return finished;
 				return finished;
 			}
 			}
 			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;
 		};
 		};
 		AnimationState.prototype.apply = function (skeleton) {
 		AnimationState.prototype.apply = function (skeleton) {
@@ -1165,10 +1163,10 @@ var spine;
 					for (var ii = 0; ii < timelineCount; ii++) {
 					for (var ii = 0; ii < timelineCount; ii++) {
 						var timeline = timelines[ii];
 						var timeline = timelines[ii];
 						if (timeline instanceof spine.RotateTimeline) {
 						if (timeline instanceof spine.RotateTimeline) {
-							this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[ii] > 0, timelinesRotation, ii << 1, firstFrame);
+							this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[ii] >= AnimationState.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] >= AnimationState.FIRST, false);
 					}
 					}
 				}
 				}
 				this.queueEvents(current, animationTime);
 				this.queueEvents(current, animationTime);
@@ -1203,6 +1201,7 @@ var spine;
 			var timelinesRotation = from.timelinesRotation;
 			var timelinesRotation = from.timelinesRotation;
 			var first = false;
 			var first = false;
 			var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha;
 			var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha;
+			from.totalAlpha = 0;
 			for (var i = 0; i < timelineCount; i++) {
 			for (var i = 0; i < timelineCount; i++) {
 				var timeline = timelines[i];
 				var timeline = timelines[i];
 				switch (timelineData[i]) {
 				switch (timelineData[i]) {
@@ -1214,14 +1213,18 @@ var spine;
 						first = true;
 						first = true;
 						alpha = alphaMix;
 						alpha = alphaMix;
 						break;
 						break;
+					case AnimationState.DIP:
+						first = true;
+						alpha = alphaDip;
+						break;
 					default:
 					default:
 						first = true;
 						first = true;
 						alpha = alphaDip;
 						alpha = alphaDip;
 						var dipMix = timelineDipMix[i];
 						var dipMix = 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 spine.RotateTimeline)
 				if (timeline instanceof spine.RotateTimeline)
 					this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 					this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 				else {
 				else {
@@ -1533,6 +1536,7 @@ var spine;
 	AnimationState.SUBSEQUENT = 0;
 	AnimationState.SUBSEQUENT = 0;
 	AnimationState.FIRST = 1;
 	AnimationState.FIRST = 1;
 	AnimationState.DIP = 2;
 	AnimationState.DIP = 2;
+	AnimationState.DIP_MIX = 3;
 	spine.AnimationState = AnimationState;
 	spine.AnimationState = AnimationState;
 	var TrackEntry = (function () {
 	var TrackEntry = (function () {
 		function TrackEntry() {
 		function TrackEntry() {
@@ -1560,6 +1564,7 @@ var spine;
 			var timelines = this.animation.timelines;
 			var timelines = this.animation.timelines;
 			var timelinesCount = this.animation.timelines.length;
 			var timelinesCount = this.animation.timelines.length;
 			var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
 			var timelineData = spine.Utils.setArraySize(this.timelineData, timelinesCount);
+			this.timelineDipMix.length = 0;
 			var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
 			var timelineDipMix = spine.Utils.setArraySize(this.timelineDipMix, timelinesCount);
 			outer: for (var i = 0; i < timelinesCount; i++) {
 			outer: for (var i = 0; i < timelinesCount; i++) {
 				var id = timelines[i].getPropertyId();
 				var id = timelines[i].getPropertyId();
@@ -1568,16 +1573,17 @@ var spine;
 				else if (to == null || !to.hasTimeline(id))
 				else if (to == null || !to.hasTimeline(id))
 					timelineData[i] = AnimationState.FIRST;
 					timelineData[i] = AnimationState.FIRST;
 				else {
 				else {
-					timelineData[i] = AnimationState.DIP;
 					for (var ii = mixingToLast; ii >= 0; ii--) {
 					for (var ii = mixingToLast; ii >= 0; ii--) {
 						var entry = mixingTo[ii];
 						var entry = mixingTo[ii];
 						if (!entry.hasTimeline(id)) {
 						if (!entry.hasTimeline(id)) {
-							if (entry.mixDuration > 0)
+							if (entry.mixDuration > 0) {
+								timelineData[i] = AnimationState.DIP_MIX;
 								timelineDipMix[i] = entry;
 								timelineDipMix[i] = entry;
-							continue outer;
+								continue outer;
+							}
 						}
 						}
 					}
 					}
-					timelineDipMix[i] = null;
+					timelineData[i] = AnimationState.DIP;
 				}
 				}
 			}
 			}
 			return lastEntry;
 			return lastEntry;
@@ -2407,22 +2413,8 @@ var spine;
 						break outer;
 						break outer;
 					}
 					}
 				}
 				}
-				var minAngle = 0, minDist = Number.MAX_VALUE, minX = 0, minY = 0;
-				var maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0;
-				x = l1 + a;
-				d = x * x;
-				if (d > maxDist) {
-					maxAngle = 0;
-					maxDist = d;
-					maxX = x;
-				}
-				x = l1 - a;
-				d = x * x;
-				if (d < minDist) {
-					minAngle = spine.MathUtils.PI;
-					minDist = d;
-					minX = x;
-				}
+				var minAngle = spine.MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0;
+				var maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;
 				var angle = Math.acos(-a * l1 / (aa - bb));
 				var angle = Math.acos(-a * l1 / (aa - bb));
 				x = a * Math.cos(angle) + l1;
 				x = a * Math.cos(angle) + l1;
 				y = b * Math.sin(angle);
 				y = b * Math.sin(angle);

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
spine-ts/build/spine-widget.js.map


+ 28 - 21
spine-ts/core/src/AnimationState.ts

@@ -34,6 +34,7 @@ module spine {
 		static SUBSEQUENT = 0;
 		static SUBSEQUENT = 0;
 		static FIRST = 1;
 		static FIRST = 1;
 		static DIP = 2;
 		static DIP = 2;
+		static DIP_MIX = 3;
 
 
 		data: AnimationStateData;
 		data: AnimationStateData;
 		tracks = new Array<TrackEntry>();
 		tracks = new Array<TrackEntry>();
@@ -91,7 +92,7 @@ module spine {
 					this.disposeNext(current);
 					this.disposeNext(current);
 					continue;
 					continue;
 				}
 				}
-				if (current.mixingFrom != null && this.updateMixingFrom(current, delta, 2)) {
+				if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
 					// End mixing from entries once all have completed.
 					// End mixing from entries once all have completed.
 					let from = current.mixingFrom;
 					let from = current.mixingFrom;
 					current.mixingFrom = null;
 					current.mixingFrom = null;
@@ -107,21 +108,18 @@ module spine {
 			this.queue.drain();
 			this.queue.drain();
 		}
 		}
 
 
-		updateMixingFrom (entry: TrackEntry, delta: number, animationCount: number): boolean {
-			let from = entry.mixingFrom;
+		updateMixingFrom (to: TrackEntry, delta: number): boolean {
+			let from = to.mixingFrom;
 			if (from == null) return true;
 			if (from == null) return true;
 
 
-			let finished = this.updateMixingFrom(from, delta, animationCount + 1);
+			let finished = this.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.66);
-					if (entry.interruptAlpha <= 0) {
-						entry.mixingFrom = null;
-						this.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;
+					this.queue.end(from);
 				}
 				}
 				return finished;
 				return finished;
 			}
 			}
@@ -129,7 +127,7 @@ module spine {
 			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;
 		}
 		}
 
 
@@ -168,10 +166,10 @@ module spine {
 					for (let ii = 0; ii < timelineCount; ii++) {
 					for (let ii = 0; ii < timelineCount; ii++) {
 						let timeline = timelines[ii];
 						let timeline = timelines[ii];
 						if (timeline instanceof RotateTimeline) {
 						if (timeline instanceof RotateTimeline) {
-							this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[ii] > 0, timelinesRotation, ii << 1,
+							this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineData[ii] >= AnimationState.FIRST, timelinesRotation, ii << 1,
 								firstFrame);
 								firstFrame);
 						} else
 						} else
-							timeline.apply(skeleton, animationLast, animationTime, events, mix, timelineData[ii] > 0, false);
+							timeline.apply(skeleton, animationLast, animationTime, events, mix, timelineData[ii] >= AnimationState.FIRST, false);
 					}
 					}
 				}
 				}
 				this.queueEvents(current, animationTime);
 				this.queueEvents(current, animationTime);
@@ -209,6 +207,7 @@ module spine {
 
 
 			let first = false;
 			let first = false;
 			let alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha;
 			let alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha;
+			from.totalAlpha = 0;
 			for (var i = 0; i < timelineCount; i++) {
 			for (var i = 0; i < timelineCount; i++) {
 				let timeline = timelines[i];
 				let timeline = timelines[i];
 				switch (timelineData[i]) {
 				switch (timelineData[i]) {
@@ -220,13 +219,18 @@ module spine {
 					first = true;
 					first = true;
 					alpha = alphaMix;
 					alpha = alphaMix;
 					break;
 					break;
+				case AnimationState.DIP:
+					first = true;
+					alpha = alphaDip;
+					break;
 				default:
 				default:
 					first = true;
 					first = true;
 					alpha = alphaDip;
 					alpha = alphaDip;
 					let dipMix = timelineDipMix[i];
 					let dipMix = 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)
 					this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 					this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
 				else {
 				else {
@@ -578,7 +582,7 @@ module spine {
 		eventThreshold: number; attachmentThreshold: number; drawOrderThreshold: number;
 		eventThreshold: number; attachmentThreshold: number; drawOrderThreshold: number;
 		animationStart: number; animationEnd: number; animationLast: number; nextAnimationLast: number;
 		animationStart: number; animationEnd: number; animationLast: number; nextAnimationLast: number;
 		delay: number; trackTime: number; trackLast: number; nextTrackLast: number; trackEnd: number; timeScale: number;
 		delay: number; trackTime: number; trackLast: number; nextTrackLast: number; trackEnd: number; timeScale: number;
-		alpha: number; mixTime: number; mixDuration: number; interruptAlpha: number;
+		alpha: number; mixTime: number; mixDuration: number; interruptAlpha: number; totalAlpha: number;
 		timelineData = new Array<number>();
 		timelineData = new Array<number>();
 		timelineDipMix = new Array<TrackEntry>();
 		timelineDipMix = new Array<TrackEntry>();
 		timelinesRotation = new Array<number>();
 		timelinesRotation = new Array<number>();
@@ -603,6 +607,7 @@ module spine {
 			let timelines = this.animation.timelines;
 			let timelines = this.animation.timelines;
 			let timelinesCount = this.animation.timelines.length;
 			let timelinesCount = this.animation.timelines.length;
 			let timelineData = Utils.setArraySize(this.timelineData, timelinesCount);
 			let timelineData = Utils.setArraySize(this.timelineData, timelinesCount);
+			this.timelineDipMix.length = 0;
 			let timelineDipMix = Utils.setArraySize(this.timelineDipMix, timelinesCount);
 			let timelineDipMix = Utils.setArraySize(this.timelineDipMix, timelinesCount);
 
 
 			outer:
 			outer:
@@ -613,15 +618,17 @@ module spine {
 				else if (to == null || !to.hasTimeline(id))
 				else if (to == null || !to.hasTimeline(id))
 					timelineData[i] = AnimationState.FIRST;
 					timelineData[i] = AnimationState.FIRST;
 				else {
 				else {
-					timelineData[i] = AnimationState.DIP;
 					for (var ii = mixingToLast; ii >= 0; ii--) {
 					for (var ii = mixingToLast; ii >= 0; ii--) {
 						let entry = mixingTo[ii];
 						let entry = 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] = AnimationState.DIP_MIX;
+								timelineDipMix[i] = entry;
+								continue outer;
+							}
 						}
 						}
 					}
 					}
-					timelineDipMix[i] = null;
+					timelineData[i] = AnimationState.DIP;
 				}
 				}
 			}
 			}
 			return lastEntry;
 			return lastEntry;

+ 3 - 17
spine-ts/core/src/IkConstraint.ts

@@ -34,7 +34,7 @@ module spine {
 		bones: Array<Bone>;
 		bones: Array<Bone>;
 		target: Bone;
 		target: Bone;
 		mix = 1;
 		mix = 1;
-		bendDirection = 0;		
+		bendDirection = 0;
 
 
 		constructor (data: IkConstraintData, skeleton: Skeleton) {
 		constructor (data: IkConstraintData, skeleton: Skeleton) {
 			if (data == null) throw new Error("data cannot be null.");
 			if (data == null) throw new Error("data cannot be null.");
@@ -169,22 +169,8 @@ module spine {
 						break outer;
 						break outer;
 					}
 					}
 				}
 				}
-				let minAngle = 0, minDist = Number.MAX_VALUE, minX = 0, minY = 0;
-				let maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0;
-				x = l1 + a;
-				d = x * x;
-				if (d > maxDist) {
-					maxAngle = 0;
-					maxDist = d;
-					maxX = x;
-				}
-				x = l1 - a;
-				d = x * x;
-				if (d < minDist) {
-					minAngle = MathUtils.PI;
-					minDist = d;
-					minX = x;
-				}
+				let minAngle = spine.MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0;
+				let maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0;
 				let angle = Math.acos(-a * l1 / (aa - bb));
 				let angle = Math.acos(-a * l1 / (aa - bb));
 				x = a * Math.cos(angle) + l1;
 				x = a * Math.cos(angle) + l1;
 				y = b * Math.sin(angle);
 				y = b * Math.sin(angle);

+ 9 - 13
spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs

@@ -31,7 +31,6 @@
 // Contributed by: Mitch Thompson
 // Contributed by: Mitch Thompson
 
 
 #define SPINE_SKELETON_ANIMATOR
 #define SPINE_SKELETON_ANIMATOR
-//#define SPINE_BAKING
 
 
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
@@ -50,14 +49,6 @@ namespace Spine.Unity.Editor {
 		static bool showSlotList = false;
 		static bool showSlotList = false;
 		static bool showAttachments = false;
 		static bool showAttachments = false;
 
 
-		#if SPINE_BAKING
-		static bool isBakingExpanded = false;
-		static bool bakeAnimations = true;
-		static bool bakeIK = true;
-		static SendMessageOptions bakeEventOptions = SendMessageOptions.DontRequireReceiver;
-		const string ShowBakingPrefsKey = "SkeletonDataAssetInspector_showUnity";
-		#endif
-
 		SerializedProperty atlasAssets, skeletonJSON, scale, fromAnimation, toAnimation, duration, defaultMix;
 		SerializedProperty atlasAssets, skeletonJSON, scale, fromAnimation, toAnimation, duration, defaultMix;
 		#if SPINE_TK2D
 		#if SPINE_TK2D
 		SerializedProperty spriteCollection;
 		SerializedProperty spriteCollection;
@@ -102,13 +93,17 @@ namespace Spine.Unity.Editor {
 			atlasAssets.isExpanded = true;
 			atlasAssets.isExpanded = true;
 			#endif
 			#endif
 
 
-			#if SPINE_BAKING
-			isBakingExpanded = EditorPrefs.GetBool(ShowBakingPrefsKey, false);
-			#endif
-
 			m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset));
 			m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset));
+
+			EditorApplication.update -= EditorUpdate;
 			EditorApplication.update += EditorUpdate;
 			EditorApplication.update += EditorUpdate;
+
 			RepopulateWarnings();
 			RepopulateWarnings();
+			if (m_skeletonDataAsset.skeletonJSON == null) {
+				m_skeletonData = null;
+				return;	
+			}
+
 			m_skeletonData = warnings.Count == 0 ? m_skeletonDataAsset.GetSkeletonData(false) : null;
 			m_skeletonData = warnings.Count == 0 ? m_skeletonDataAsset.GetSkeletonData(false) : null;
 		}
 		}
 
 
@@ -220,6 +215,7 @@ namespace Spine.Unity.Editor {
 			// Some code depends on the existence of m_skeletonAnimation instance.
 			// Some code depends on the existence of m_skeletonAnimation instance.
 			// If m_skeletonAnimation is lazy-instantiated elsewhere, this can cause contents to change between Layout and Repaint events, causing GUILayout control count errors.
 			// If m_skeletonAnimation is lazy-instantiated elsewhere, this can cause contents to change between Layout and Repaint events, causing GUILayout control count errors.
 			InitPreview();
 			InitPreview();
+
 			if (m_skeletonData != null) {
 			if (m_skeletonData != null) {
 				GUILayout.Space(20f);
 				GUILayout.Space(20f);
 
 

+ 6 - 8
spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs

@@ -1169,14 +1169,12 @@ namespace Spine.Unity.Editor {
 			if (spineJson != null && atlasAssets != null) {
 			if (spineJson != null && atlasAssets != null) {
 				SkeletonDataAsset skeletonDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset));
 				SkeletonDataAsset skeletonDataAsset = (SkeletonDataAsset)AssetDatabase.LoadAssetAtPath(filePath, typeof(SkeletonDataAsset));
 				if (skeletonDataAsset == null) {
 				if (skeletonDataAsset == null) {
-					skeletonDataAsset = SkeletonDataAsset.CreateInstance<SkeletonDataAsset>();
-					skeletonDataAsset.atlasAssets = atlasAssets;
-					skeletonDataAsset.skeletonJSON = spineJson;
-					skeletonDataAsset.fromAnimation = new string[0];
-					skeletonDataAsset.toAnimation = new string[0];
-					skeletonDataAsset.duration = new float[0];
-					skeletonDataAsset.defaultMix = defaultMix;
-					skeletonDataAsset.scale = defaultScale;
+					skeletonDataAsset = ScriptableObject.CreateInstance<SkeletonDataAsset>(); {
+						skeletonDataAsset.atlasAssets = atlasAssets;
+						skeletonDataAsset.skeletonJSON = spineJson;
+						skeletonDataAsset.defaultMix = defaultMix;
+						skeletonDataAsset.scale = defaultScale;
+					}
 
 
 					AssetDatabase.CreateAsset(skeletonDataAsset, filePath);
 					AssetDatabase.CreateAsset(skeletonDataAsset, filePath);
 					AssetDatabase.SaveAssets();
 					AssetDatabase.SaveAssets();

+ 2 - 2
spine-unity/Assets/spine-unity/Mesh Generation/SpineMesh.cs

@@ -446,7 +446,7 @@ namespace Spine.Unity {
 					clipper.ClipStart(slot, slot.attachment as ClippingAttachment);
 					clipper.ClipStart(slot, slot.attachment as ClippingAttachment);
 				}	
 				}	
 			}
 			}
-				
+
 			for (int slotIndex = instruction.startSlot; slotIndex < instruction.endSlot; slotIndex++) {
 			for (int slotIndex = instruction.startSlot; slotIndex < instruction.endSlot; slotIndex++) {
 				var slot = drawOrderItems[slotIndex];
 				var slot = drawOrderItems[slotIndex];
 				var attachment = slot.attachment;
 				var attachment = slot.attachment;
@@ -507,7 +507,7 @@ namespace Spine.Unity {
 					color.b = (byte)(skeletonB * slot.b * c.b * 255);
 					color.b = (byte)(skeletonB * slot.b * c.b * 255);
 				}
 				}
 
 
-				if (useClipping && clipper.IsClipping()) {					
+				if (useClipping && clipper.IsClipping()) {
 					clipper.ClipTriangles(workingVerts, attachmentVertexCount << 1, attachmentTriangleIndices, attachmentIndexCount, uvs);
 					clipper.ClipTriangles(workingVerts, attachmentVertexCount << 1, attachmentTriangleIndices, attachmentIndexCount, uvs);
 					workingVerts = clipper.clippedVertices.Items;
 					workingVerts = clipper.clippedVertices.Items;
 					attachmentVertexCount = clipper.clippedVertices.Count >> 1;
 					attachmentVertexCount = clipper.clippedVertices.Count >> 1;

+ 44 - 31
spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Editor/SkeletonGraphicInspector.cs

@@ -38,11 +38,12 @@ namespace Spine.Unity.Editor {
 	[CustomEditor(typeof(SkeletonGraphic))]
 	[CustomEditor(typeof(SkeletonGraphic))]
 	[CanEditMultipleObjects]
 	[CanEditMultipleObjects]
 	public class SkeletonGraphicInspector : UnityEditor.Editor {
 	public class SkeletonGraphicInspector : UnityEditor.Editor {
-		SerializedProperty material_, color_;
-		SerializedProperty skeletonDataAsset_, initialSkinName_;
-		SerializedProperty startingAnimation_, startingLoop_, timeScale_, freeze_, unscaledTime_, tintBlack_;
-		SerializedProperty meshGeneratorSettings_;
-		SerializedProperty raycastTarget_;
+		SerializedProperty material, color;
+		SerializedProperty skeletonDataAsset, initialSkinName;
+		SerializedProperty startingAnimation, startingLoop, timeScale, freeze, unscaledTime, tintBlack;
+		SerializedProperty initialFlipX, initialFlipY;
+		SerializedProperty meshGeneratorSettings;
+		SerializedProperty raycastTarget;
 
 
 		SkeletonGraphic thisSkeletonGraphic;
 		SkeletonGraphic thisSkeletonGraphic;
 
 
@@ -51,32 +52,34 @@ namespace Spine.Unity.Editor {
 			thisSkeletonGraphic = target as SkeletonGraphic;
 			thisSkeletonGraphic = target as SkeletonGraphic;
 
 
 			// MaskableGraphic
 			// MaskableGraphic
-			material_ = so.FindProperty("m_Material");
-			color_ = so.FindProperty("m_Color");
-			raycastTarget_ = so.FindProperty("m_RaycastTarget");
+			material = so.FindProperty("m_Material");
+			color = so.FindProperty("m_Color");
+			raycastTarget = so.FindProperty("m_RaycastTarget");
 
 
 			// SkeletonRenderer
 			// SkeletonRenderer
-			skeletonDataAsset_ = so.FindProperty("skeletonDataAsset");
-			initialSkinName_ = so.FindProperty("initialSkinName");
-			//tintBlack_ = so.FindProperty("tintBlack");
+			skeletonDataAsset = so.FindProperty("skeletonDataAsset");
+			initialSkinName = so.FindProperty("initialSkinName");
+
+			initialFlipX = so.FindProperty("initialFlipX");
+			initialFlipY = so.FindProperty("initialFlipY");
 
 
 			// SkeletonAnimation
 			// SkeletonAnimation
-			startingAnimation_ = so.FindProperty("startingAnimation");
-			startingLoop_ = so.FindProperty("startingLoop");
-			timeScale_ = so.FindProperty("timeScale");
-			unscaledTime_ = so.FindProperty("unscaledTime");
-			freeze_ = so.FindProperty("freeze");
-
-			meshGeneratorSettings_ = so.FindProperty("meshGenerator").FindPropertyRelative("settings");
-			meshGeneratorSettings_.isExpanded = SkeletonRendererInspector.advancedFoldout;
+			startingAnimation = so.FindProperty("startingAnimation");
+			startingLoop = so.FindProperty("startingLoop");
+			timeScale = so.FindProperty("timeScale");
+			unscaledTime = so.FindProperty("unscaledTime");
+			freeze = so.FindProperty("freeze");
+
+			meshGeneratorSettings = so.FindProperty("meshGenerator").FindPropertyRelative("settings");
+			meshGeneratorSettings.isExpanded = SkeletonRendererInspector.advancedFoldout;
 		}
 		}
 
 
 		public override void OnInspectorGUI () {
 		public override void OnInspectorGUI () {
 			EditorGUI.BeginChangeCheck();
 			EditorGUI.BeginChangeCheck();
 
 
-			EditorGUILayout.PropertyField(skeletonDataAsset_);
-			EditorGUILayout.PropertyField(material_);
-			EditorGUILayout.PropertyField(color_);
+			EditorGUILayout.PropertyField(skeletonDataAsset);
+			EditorGUILayout.PropertyField(material);
+			EditorGUILayout.PropertyField(color);
 
 
 			if (thisSkeletonGraphic.skeletonDataAsset == null) {
 			if (thisSkeletonGraphic.skeletonDataAsset == null) {
 				EditorGUILayout.HelpBox("You need to assign a SkeletonDataAsset first.", MessageType.Info);
 				EditorGUILayout.HelpBox("You need to assign a SkeletonDataAsset first.", MessageType.Info);
@@ -85,23 +88,33 @@ namespace Spine.Unity.Editor {
 				return;
 				return;
 			}
 			}
 			using (new SpineInspectorUtility.BoxScope()) {
 			using (new SpineInspectorUtility.BoxScope()) {
-				EditorGUILayout.PropertyField(meshGeneratorSettings_, SpineInspectorUtility.TempContent("Advanced..."), includeChildren: true);
-				SkeletonRendererInspector.advancedFoldout = meshGeneratorSettings_.isExpanded;
+				EditorGUILayout.PropertyField(meshGeneratorSettings, SpineInspectorUtility.TempContent("Advanced..."), includeChildren: true);
+				SkeletonRendererInspector.advancedFoldout = meshGeneratorSettings.isExpanded;
 			}
 			}
 
 
 			EditorGUILayout.Space();
 			EditorGUILayout.Space();
-			EditorGUILayout.PropertyField(initialSkinName_);
+			EditorGUILayout.PropertyField(initialSkinName);
+			{
+				var rect = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, EditorGUIUtility.singleLineHeight);
+				EditorGUI.PrefixLabel(rect, SpineInspectorUtility.TempContent("Initial Flip"));
+				rect.x += EditorGUIUtility.labelWidth;
+				rect.width = 30f;
+				initialFlipX.boolValue = EditorGUI.ToggleLeft(rect, SpineInspectorUtility.TempContent("X", tooltip:"initialFlipX"), initialFlipX.boolValue);
+				rect.x += 35f;
+				initialFlipY.boolValue = EditorGUI.ToggleLeft(rect, SpineInspectorUtility.TempContent("Y", tooltip:"initialFlipY"), initialFlipY.boolValue);
+			}
+
 			EditorGUILayout.Space();
 			EditorGUILayout.Space();
 			EditorGUILayout.LabelField("Animation", EditorStyles.boldLabel);
 			EditorGUILayout.LabelField("Animation", EditorStyles.boldLabel);
-			EditorGUILayout.PropertyField(startingAnimation_);
-			EditorGUILayout.PropertyField(startingLoop_);
-			EditorGUILayout.PropertyField(timeScale_);
-			EditorGUILayout.PropertyField(unscaledTime_, SpineInspectorUtility.TempContent(unscaledTime_.displayName, tooltip: "If checked, this will use Time.unscaledDeltaTime to make this update independent of game Time.timeScale. Instance SkeletonGraphic.timeScale will still be applied."));
+			EditorGUILayout.PropertyField(startingAnimation);
+			EditorGUILayout.PropertyField(startingLoop);
+			EditorGUILayout.PropertyField(timeScale);
+			EditorGUILayout.PropertyField(unscaledTime, SpineInspectorUtility.TempContent(unscaledTime.displayName, tooltip: "If checked, this will use Time.unscaledDeltaTime to make this update independent of game Time.timeScale. Instance SkeletonGraphic.timeScale will still be applied."));
 			EditorGUILayout.Space();
 			EditorGUILayout.Space();
-			EditorGUILayout.PropertyField(freeze_);
+			EditorGUILayout.PropertyField(freeze);
 			EditorGUILayout.Space();
 			EditorGUILayout.Space();
 			EditorGUILayout.LabelField("UI", EditorStyles.boldLabel);
 			EditorGUILayout.LabelField("UI", EditorStyles.boldLabel);
-			EditorGUILayout.PropertyField(raycastTarget_);
+			EditorGUILayout.PropertyField(raycastTarget);
 
 
 			bool wasChanged = EditorGUI.EndChangeCheck();
 			bool wasChanged = EditorGUI.EndChangeCheck();
 
 

+ 11 - 1
spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/SkeletonGraphic.cs

@@ -43,6 +43,7 @@ namespace Spine.Unity {
 
 
 		[SpineSkin(dataField:"skeletonDataAsset")]
 		[SpineSkin(dataField:"skeletonDataAsset")]
 		public string initialSkinName = "default";
 		public string initialSkinName = "default";
+		public bool initialFlipX, initialFlipY;
 
 
 		[SpineAnimation(dataField:"skeletonDataAsset")]
 		[SpineAnimation(dataField:"skeletonDataAsset")]
 		public string startingAnimation;
 		public string startingAnimation;
@@ -79,6 +80,11 @@ namespace Spine.Unity {
 							
 							
 					}
 					}
 
 
+					if (!Application.isPlaying) {
+						skeleton.flipX = this.initialFlipX;
+						skeleton.flipY = this.initialFlipY;
+					}
+
 					skeleton.SetToSetupPose();
 					skeleton.SetToSetupPose();
 					if (!string.IsNullOrEmpty(startingAnimation))
 					if (!string.IsNullOrEmpty(startingAnimation))
 						skeleton.PoseWithAnimation(startingAnimation, 0f, false);
 						skeleton.PoseWithAnimation(startingAnimation, 0f, false);
@@ -212,7 +218,11 @@ namespace Spine.Unity {
 				return;
 				return;
 			}
 			}
 
 
-			this.skeleton = new Skeleton(skeletonData);
+			this.skeleton = new Skeleton(skeletonData) {
+				flipX = this.initialFlipX,
+				flipY = this.initialFlipY
+			};
+
 			meshBuffers = new DoubleBuffered<MeshRendererBuffers.SmartMesh>();
 			meshBuffers = new DoubleBuffered<MeshRendererBuffers.SmartMesh>();
 
 
 			// Set the initial Skin and Animation
 			// Set the initial Skin and Animation

+ 0 - 1
spine-unity/Assets/spine-unity/SkeletonAnimation.cs

@@ -28,7 +28,6 @@
  * POSSIBILITY OF SUCH DAMAGE.
  * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
  *****************************************************************************/
 
 
-using System;
 using UnityEngine;
 using UnityEngine;
 
 
 namespace Spine.Unity {
 namespace Spine.Unity {

+ 5 - 4
spine-unity/Assets/spine-unity/SkeletonRenderer.cs

@@ -184,13 +184,14 @@ namespace Spine.Unity {
 			meshRenderer = GetComponent<MeshRenderer>();
 			meshRenderer = GetComponent<MeshRenderer>();
 			rendererBuffers.Initialize();
 			rendererBuffers.Initialize();
 
 
-			skeleton = new Skeleton(skeletonData);
+			skeleton = new Skeleton(skeletonData) {
+				flipX = initialFlipX,
+				flipY = initialFlipY
+			};
+
 			if (!string.IsNullOrEmpty(initialSkinName) && !string.Equals(initialSkinName, "default", System.StringComparison.Ordinal))
 			if (!string.IsNullOrEmpty(initialSkinName) && !string.Equals(initialSkinName, "default", System.StringComparison.Ordinal))
 				skeleton.SetSkin(initialSkinName);
 				skeleton.SetSkin(initialSkinName);
 
 
-			skeleton.flipX = initialFlipX;
-			skeleton.flipY = initialFlipY;
-
 			separatorSlots.Clear();
 			separatorSlots.Clear();
 			for (int i = 0; i < separatorSlotNames.Length; i++)
 			for (int i = 0; i < separatorSlotNames.Length; i++)
 				separatorSlots.Add(skeleton.FindSlot(separatorSlotNames[i]));
 				separatorSlots.Add(skeleton.FindSlot(separatorSlotNames[i]));

Некоторые файлы не были показаны из-за большого количества измененных файлов