From 472392190f09e17e41d3db2f3915d1c37999a08c Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Mon, 23 Oct 2017 18:15:49 +0200 Subject: [PATCH 1/3] [libgdx] Documented track entry timeline mix types. #1024 --- .../spine/AnimationState.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java index 257809d9a..376f613ae 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java @@ -51,7 +51,31 @@ import com.esotericsoftware.spine.Animation.Timeline; * See Applying Animations in the Spine Runtimes Guide. */ public class AnimationState { static private final Animation emptyAnimation = new Animation("", new Array(0), 0); - static private final int SUBSEQUENT = 0, FIRST = 1, DIP = 2, DIP_MIX = 3; + + /** 1) A previously applied timeline has set this property.
+ * Result: Mix from the current pose to the timeline pose. */ + static private final int SUBSEQUENT = 0; + /** 1) This is the first timeline to set this property.
+ * 2) The next track entry applied after this one does not have a timeline to set this property.
+ * Result: Mix from the setup pose to the timeline pose. */ + static private final int FIRST = 1; + /** 1) This is the first timeline to set this property.
+ * 2) The next track entry to be applied does have a timeline to set this property.
+ * 3) The next track entry after that one does not have a timeline to set this property.
+ * Result: Mix from the setup pose to the timeline pose, but avoid the "dipping" problem by not using the mix percentage. This + * means the timeline pose won't mix out toward the setup pose. A subsequent timeline will set this property using a mix. */ + static private final int DIP = 2; + /** 1) This is the first timeline to set this property.
+ * 2) The next track entry to be applied does have a timeline to set this property.
+ * 3) The next track entry after that one does have a timeline to set this property.
+ * 4) timelineDipMix stores the first subsequent track entry that does not have a timeline to set this property.
+ * Result: This is the same as DIP except the mix percentage from the timelineDipMix track entry is used. This handles when + * more than 2 track entries in a row have a timeline which sets the same property.
+ * Eg, A -> B -> C -> D where A, B, and C have a timeline to set the same property, but D does not. When A is applied, A's mix + * percentage is not used to avoid dipping, however a later track entry (D, the first entry without a timeline which sets the + * property) is actually mixing out A (which affects B and C). Without using D's mix percentage, A would be applied fully until + * mixed out, causing snapping. */ + static private final int DIP_MIX = 3; private AnimationStateData data; final Array tracks = new Array(); From 28fd5aff095ac05c35de0e9291f1a3cc28282183 Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Mon, 23 Oct 2017 18:30:46 +0200 Subject: [PATCH 2/3] [libgdx] Don't use the dip fix if mixing is complete. closes #1024 --- .../com/esotericsoftware/spine/AnimationState.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java index 376f613ae..d011999bb 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java @@ -281,13 +281,17 @@ public class AnimationState { break; case DIP: pose = MixPose.setup; - alpha = alphaDip; + alpha = mix == 1 ? 0 : alphaDip; break; default: pose = MixPose.setup; - alpha = alphaDip; - TrackEntry dipMix = (TrackEntry)timelineDipMix[i]; - alpha *= Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration); + if (mix == 1) + alpha = 0; + else { + alpha = alphaDip; + TrackEntry dipMix = (TrackEntry)timelineDipMix[i]; + alpha *= Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration); + } break; } from.totalAlpha += alpha; From 1f704aec5e1f074a4befad253fdf8ea2b7134854 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 24 Oct 2017 00:41:35 +0800 Subject: [PATCH 3/3] [csharp] Don't use the dip fix if mixing is complete. Based on: https://github.com/EsotericSoftware/spine-runtimes/commit/28fd5aff095ac05c35de0e9291f1a3cc28282183 See https://github.com/EsotericSoftware/spine-runtimes/issues/1024 --- spine-csharp/src/AnimationState.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/spine-csharp/src/AnimationState.cs b/spine-csharp/src/AnimationState.cs index f992efe0c..6e2dfb5b4 100644 --- a/spine-csharp/src/AnimationState.cs +++ b/spine-csharp/src/AnimationState.cs @@ -258,13 +258,17 @@ namespace Spine { break; case Dip: pose = MixPose.Setup; - alpha = alphaDip; + alpha = mix == 1 ? 0 : alphaDip; break; default: pose = MixPose.Setup; - alpha = alphaDip; - var dipMix = timelineDipMix[i]; - alpha *= Math.Max(0, 1 - dipMix.mixTime / dipMix.mixDuration); + if (mix == 1) { + alpha = 0; + } else { + alpha = alphaDip; + var dipMix = timelineDipMix[i]; + alpha *= Math.Max(0, 1 - dipMix.mixTime / dipMix.mixDuration); + } break; } from.totalAlpha += alpha;