From c23eb470e68361ec56c6d8327f53c15db4a0342d Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Fri, 1 Nov 2019 20:13:32 +0100 Subject: [PATCH 1/4] Minor cleanup, javadoc. --- .../com/esotericsoftware/spine/Animation.java | 46 +++++++++---------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java index d3e2412c3..4e1d94640 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java @@ -115,7 +115,7 @@ public class Animation { } /** Binary search using a stride of 1. - * @return The index of the first value less than or equal to the target, else the first value if none. */ + * @return The index of the first value <= to the target, else the first value if none. */ static int binarySearch (float[] values, float target) { int low = 0, high = values.length - 1, current; while (true) { @@ -130,11 +130,11 @@ public class Animation { /** Binary search using a stride of 2. * @param target >= the first and < the last value. - * @return The index / 2 of the first value less than or equal to the target. */ + * @return The index / 2 of the first value <= to the target. */ static int binarySearch2 (float[] values, float target) { int low = 0, high = (values.length >> 1) - 2, current; while (true) { - if (low >= high) return low; + if (low == high) return low; current = ((low + high) >>> 1) + 1; if (values[current << 1] <= target) low = current; @@ -144,12 +144,12 @@ public class Animation { } /** Binary search using the specified stride. - * @param target After the first and before the last value. - * @return The index / 2 of the first value less than or equal to the target. */ + * @param target >= the first and < the last value. + * @return The index / 2 of the first value <= to the target. */ static int binarySearch (float[] values, float target, int step) { int low = 0, high = values.length / step - 2, current; while (true) { - if (low >= high) return low; + if (low == high) return low; current = ((low + high) >>> 1) + 1; if (values[current * step] <= target) low = current; @@ -159,8 +159,8 @@ public class Animation { } /** Linear search using the specified stride. Not used, but for comparison with binary searches. - * @param target After the first and before the last value. - * @return index of first value greater than the target. */ + * @param target >= the first and < the last value. + * @return The index / 2 of the first value <= to the target. */ static int linearSearch (float[] values, float target, int step) { for (int i = 0, last = values.length - 1; i < last; i += step) if (values[i] > target) return i / step - 1; @@ -218,7 +218,7 @@ public class Animation { final float[] frames; /** @param frameEntries The number of entries stored per frame. - * @param propertyIds Unique identifiers for each property the timeline modifies. */ + * @param propertyIds Unique identifiers for the properties the timeline modifies. */ public Timeline (int frameCount, int frameEntries, String... propertyIds) { if (propertyIds == null) throw new IllegalArgumentException("propertyIds cannot be null."); this.propertyIds = propertyIds; @@ -284,7 +284,7 @@ public class Animation { /** @param frameEntries The number of entries stored per frame. * @param bezierCount The maximum number of frames that will use Bezier curves. See {@link #shrink(int)}. - * @param propertyIds Unique identifiers for each property the timeline modifies. */ + * @param propertyIds Unique identifiers for the properties the timeline modifies. */ public CurveTimeline (int frameCount, int frameEntries, int bezierCount, String... propertyIds) { super(frameCount, frameEntries, propertyIds); curves = new float[frameCount - 1 + bezierCount * BEZIER_SIZE]; @@ -328,10 +328,10 @@ public class Animation { } /** The base class for timelines that use interpolation between key frames for one or more properties using a percentage of the - * difference between values. */ + * difference between key frame values. */ static public abstract class PercentCurveTimeline extends CurveTimeline { /** @param bezierCount The maximum number of frames that will use Bezier curves. See {@link #shrink(int)}. - * @param propertyIds Unique identifiers for each property the timeline modifies. */ + * @param propertyIds Unique identifiers for the properties the timeline modifies. */ public PercentCurveTimeline (int frameCount, int frameEntries, int bezierCount, String... propertyIds) { super(frameCount, frameEntries, bezierCount, propertyIds); } @@ -369,11 +369,9 @@ public class Animation { float[] curves = this.curves; int i = (int)curves[frameIndex]; if (i < BEZIER) { - if (i == LINEAR) { - float time1 = frames[timeIndex]; - return MathUtils.clamp((time - time1) / (frames[timeIndex + entryCount] - time1), 0, 1); - } - return 0; + if (i == STEPPED) return 0; + float time1 = frames[timeIndex]; + return MathUtils.clamp((time - time1) / (frames[timeIndex + entryCount] - time1), 0, 1); } i -= BEZIER; if (curves[i] > time) { @@ -398,7 +396,7 @@ public class Animation { static final int VALUE1 = 1, VALUE2 = 2, NEXT_VALUE1 = 4, NEXT_VALUE2 = 5; /** @param bezierCount The maximum number of frames that will use Bezier curves. See {@link #shrink(int)}. - * @param propertyIds Unique identifiers for each property the timeline modifies. */ + * @param propertyIds Unique identifiers for the properties the timeline modifies. */ public PercentCurveTimeline2 (int frameCount, int bezierCount, String... propertyIds) { super(frameCount, ENTRIES, bezierCount, propertyIds); } @@ -423,7 +421,7 @@ public class Animation { static final int VALUE = 1, NEXT_VALUE = 3; /** @param bezierCount The maximum number of frames that will use Bezier curves. See {@link #shrink(int)}. - * @param propertyIds Unique identifiers for each property the timeline modifies. */ + * @param propertyIds Unique identifiers for the properties the timeline modifies. */ public ValueCurveTimeline (int frameCount, int bezierCount, String... propertyIds) { super(frameCount, 2, bezierCount, propertyIds); } @@ -474,12 +472,10 @@ public class Animation { int i = (int)curves[frameIndex]; if (i < BEZIER) { int frame = frameIndex << 1; - if (i == LINEAR) { - float value1 = frames[frame + VALUE], time1 = frames[frame]; - return value1 + (frames[frame + NEXT_VALUE] - value1) - * MathUtils.clamp((time - time1) / (frames[frame + ENTRIES] - time1), 0, 1); - } - return frames[frame + VALUE]; + if (i == STEPPED) return frames[frame + VALUE]; + float time1 = frames[frame], value1 = frames[frame + VALUE]; + return value1 + (frames[frame + NEXT_VALUE] - value1) + * MathUtils.clamp((time - time1) / (frames[frame + ENTRIES] - time1), 0, 1); } i -= BEZIER; if (curves[i] > time) { From 4762954446145f67642b6b1b2fac3caa12c309e9 Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Tue, 5 Nov 2019 19:02:19 +0100 Subject: [PATCH 2/4] Fixed bug with interpolation of first Bezier segment. --- .../src/com/esotericsoftware/spine/Animation.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java index 4e1d94640..21a68a811 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java @@ -375,8 +375,8 @@ public class Animation { } i -= BEZIER; if (curves[i] > time) { - float time1 = frames[timeIndex]; - return curves[i + 1] * (time - time1) / (curves[i] - time1); + float x = frames[timeIndex]; + return curves[i + 1] * (time - x) / (curves[i] - x); } int n = i + BEZIER_SIZE; for (i += 2; i < n; i += 2) { @@ -479,8 +479,9 @@ public class Animation { } i -= BEZIER; if (curves[i] > time) { - float value1 = frames[(frameIndex << 1) + VALUE]; - return value1 + (curves[i + 1] - value1) * (time - value1) / (curves[i] - value1); + int frame = frameIndex << 1; + float x = frames[frame], y = frames[frame + VALUE]; + return y + (curves[i + 1] - y) * (time - x) / (curves[i] - x); } int n = i + BEZIER_SIZE; for (i += 2; i < n; i += 2) { From faf22ce3cca5c29d941db545bd277470d5430af8 Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Tue, 5 Nov 2019 21:51:48 +0100 Subject: [PATCH 3/4] Removed clamping. It wasn't used in all code paths anyway. --- .../src/com/esotericsoftware/spine/Animation.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java index 21a68a811..bb9f62e93 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java @@ -34,7 +34,6 @@ import static com.esotericsoftware.spine.Animation.MixDirection.*; import static com.esotericsoftware.spine.utils.SpineUtils.*; import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.FloatArray; import com.badlogic.gdx.utils.ObjectSet; @@ -370,8 +369,8 @@ public class Animation { int i = (int)curves[frameIndex]; if (i < BEZIER) { if (i == STEPPED) return 0; - float time1 = frames[timeIndex]; - return MathUtils.clamp((time - time1) / (frames[timeIndex + entryCount] - time1), 0, 1); + float x = frames[timeIndex]; + return (time - x) / (frames[timeIndex + entryCount] - x); } i -= BEZIER; if (curves[i] > time) { @@ -473,9 +472,8 @@ public class Animation { if (i < BEZIER) { int frame = frameIndex << 1; if (i == STEPPED) return frames[frame + VALUE]; - float time1 = frames[frame], value1 = frames[frame + VALUE]; - return value1 + (frames[frame + NEXT_VALUE] - value1) - * MathUtils.clamp((time - time1) / (frames[frame + ENTRIES] - time1), 0, 1); + float x = frames[frame], y = frames[frame + VALUE]; + return y + (frames[frame + NEXT_VALUE] - y) * (time - x) / (frames[frame + ENTRIES] - x); } i -= BEZIER; if (curves[i] > time) { From 507687e205533cab40494f3edfabeea1a5ae0f06 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Mon, 11 Nov 2019 19:29:26 +0100 Subject: [PATCH 4/4] [unity] Fixed mask interaction materials not working when changing skins dynamically. Closes #1546. --- .../Components/SkeletonRenderer.cs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs index 876709338..f176fc30d 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs @@ -117,6 +117,14 @@ namespace Spine.Unity { [System.Serializable] public class SpriteMaskInteractionMaterials { + public bool AnyMaterialCreated { + get { + return materialsMaskDisabled.Length > 0 || + materialsInsideMask.Length > 0 || + materialsOutsideMask.Length > 0; + } + } + /// Material references for switching material sets at runtime when changes to . public Material[] materialsMaskDisabled = new Material[0]; /// Material references for switching material sets at runtime when changes to . @@ -417,12 +425,16 @@ namespace Spine.Unity { rendererBuffers.UpdateSharedMaterials(workingSubmeshInstructions); + bool materialsChanged = rendererBuffers.MaterialsChangedInLastUpdate(); if (updateTriangles) { // Check if the triangles should also be updated. meshGenerator.FillTriangles(currentMesh); meshRenderer.sharedMaterials = rendererBuffers.GetUpdatedSharedMaterialsArray(); - } else if (rendererBuffers.MaterialsChangedInLastUpdate()) { + } else if (materialsChanged) { meshRenderer.sharedMaterials = rendererBuffers.GetUpdatedSharedMaterialsArray(); } + if (materialsChanged && (this.maskMaterials.AnyMaterialCreated)) { + this.maskMaterials = new SpriteMaskInteractionMaterials(); + } meshGenerator.FillLateVertexData(currentMesh); @@ -512,6 +524,11 @@ namespace Spine.Unity { } #endif + if (Application.isPlaying) { + if (maskInteraction != SpriteMaskInteraction.None && maskMaterials.materialsMaskDisabled.Length == 0) + maskMaterials.materialsMaskDisabled = meshRenderer.sharedMaterials; + } + if (maskMaterials.materialsMaskDisabled.Length > 0 && maskMaterials.materialsMaskDisabled[0] != null && maskInteraction == SpriteMaskInteraction.None) { this.meshRenderer.materials = maskMaterials.materialsMaskDisabled;