From 472392190f09e17e41d3db2f3915d1c37999a08c Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Mon, 23 Oct 2017 18:15:49 +0200 Subject: [PATCH 1/6] [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/6] [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/6] [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; From 7c29b9573a0117018be709190b4a344502726783 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 24 Oct 2017 18:29:01 +0800 Subject: [PATCH 4/6] [unity] Fix SkeletonGraphic shader alpha. --- .../SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader index 66dd907a2..2993e815a 100644 --- a/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader +++ b/spine-unity/Assets/spine-unity/Modules/SkeletonGraphic/Shaders/Spine-SkeletonGraphic.shader @@ -91,7 +91,7 @@ Shader "Spine/SkeletonGraphic (Premultiply Alpha)" OUT.vertex.xy += (_ScreenParams.zw-1.0) * float2(-1,1); #endif - OUT.color = IN.color * _Color; + OUT.color = IN.color * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with vertexColor. return OUT; } @@ -112,4 +112,4 @@ Shader "Spine/SkeletonGraphic (Premultiply Alpha)" ENDCG } } -} \ No newline at end of file +} From b502aa3c238a9479974eda6f449f4e8251d73c9d Mon Sep 17 00:00:00 2001 From: John Date: Wed, 25 Oct 2017 20:30:23 +0800 Subject: [PATCH 5/6] [unity] Handle null preview texture in editor. --- .../Asset Types/Editor/SkeletonDataAssetInspector.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs b/spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs index 43ee8ce84..c6d0bbc95 100644 --- a/spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs +++ b/spine-unity/Assets/spine-unity/Asset Types/Editor/SkeletonDataAssetInspector.cs @@ -726,6 +726,9 @@ namespace Spine.Unity.Editor { } void DoRenderPreview (bool drawHandles) { + if (this.PreviewUtilityCamera.activeTexture == null || this.PreviewUtilityCamera.targetTexture == null ) + return; + GameObject go = this.m_previewInstance; if (m_requireRefresh && go != null) { From 93d34666b0d69f349dbaddfa3e980799967739af Mon Sep 17 00:00:00 2001 From: badlogic Date: Fri, 27 Oct 2017 10:45:29 +0200 Subject: [PATCH 6/6] Fixed typo in README.md --- spine-ts/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spine-ts/README.md b/spine-ts/README.md index 0b0b00b10..6c3db8048 100644 --- a/spine-ts/README.md +++ b/spine-ts/README.md @@ -143,7 +143,7 @@ To specify the configuration of a Spine Widget via HTML, you can use these HTML * `data-images-path`: optional, the location of images on the server to load atlas pages from. If omitted, atlas `.png` page files are loaded relative to the `.atlas` file. * `data-skin`: optional, the name of the skin to use. Defaults to `default` if omitted. * `data-loop`: optional, whether to loop the animation or not. Defaults to `true` if omitted. - * `data-scale`: optional, the scaling factor to apply when loading the `.json` file. Defaults to `1` if omitted. Irrelevant if `data-fit-to-canavs` is `true`. + * `data-scale`: optional, the scaling factor to apply when loading the `.json` file. Defaults to `1` if omitted. Irrelevant if `data-fit-to-canvas` is `true`. * `data-x`: optional, the x-coordinate to display the animation at. The origin is in the bottom left corner. Defaults to `0` if omitted. Irrelevant if `data-fit-to-canvas` is `true`. * `data-y`: optional, the y-coordinate to display the animation at. The origin is in the bottom left corner with the y-axis pointing upwards. Defaults to `0` if omitted. Irrelevant if `data-fit-to-canvas` is `true`. * `data-fit-to-canvas`: optional, whether to fit the animation to the canvas size or not. Defaults to `true` if omitted, in which case `data-scale`, `data-x` and `data-y` are irrelevant. This setting calculates the setup pose bounding box using the specified skin to center and scale the animation on the canvas.