From c056db02ee8eac292f092cbd2a55f87b83598b22 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Mon, 30 May 2022 15:02:22 +0200 Subject: [PATCH 1/3] [libgdx] Remove VertexEffect, see #2076 --- .../esotericsoftware/spine/TestHarness.java | 15 --- .../spine/VertexEffectTest.java | 124 ------------------ .../spine/SkeletonRenderer.java | 92 ++----------- .../spine/vertexeffects/JitterEffect.java | 70 ---------- .../spine/vertexeffects/SwirlEffect.java | 98 -------------- 5 files changed, 9 insertions(+), 390 deletions(-) delete mode 100644 spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/VertexEffectTest.java delete mode 100644 spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/vertexeffects/JitterEffect.java delete mode 100644 spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/vertexeffects/SwirlEffect.java diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/TestHarness.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/TestHarness.java index 94678ed81..a5c10ab57 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/TestHarness.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/TestHarness.java @@ -37,11 +37,8 @@ import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; -import com.badlogic.gdx.math.Interpolation; import com.badlogic.gdx.utils.ScreenUtils; -import com.esotericsoftware.spine.vertexeffects.SwirlEffect; - /** Boilerplate for basic skeleton rendering, used for various testing. */ public class TestHarness extends ApplicationAdapter { // static String JSON = "coin/coin-pro.json"; @@ -60,9 +57,6 @@ public class TestHarness extends ApplicationAdapter { Skeleton skeleton; AnimationState state; - SwirlEffect swirl; - float swirlTime; - public void create () { camera = new OrthographicCamera(); camera.setToOrtho(true); @@ -71,10 +65,6 @@ public class TestHarness extends ApplicationAdapter { renderer.setPremultipliedAlpha(true); shapes = new ShapeRenderer(); - swirl = new SwirlEffect(400); - swirl.setCenterY(-200); - renderer.setVertexEffect(swirl); - atlas = new TextureAtlas(Gdx.files.internal(ATLAS)); SkeletonJson json = new SkeletonJson(atlas); json.setScale(0.5f); @@ -101,11 +91,6 @@ public class TestHarness extends ApplicationAdapter { ScreenUtils.clear(0, 0, 0, 0); - swirlTime += Gdx.graphics.getDeltaTime(); - float percent = swirlTime % 2; - if (percent > 1) percent = 1 - (percent - 1); - swirl.setAngle(Interpolation.pow2.apply(-60, 60, percent)); - // Configure the camera, SpriteBatch, and SkeletonRendererDebug. camera.update(); batch.getProjectionMatrix().set(camera.combined); diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/VertexEffectTest.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/VertexEffectTest.java deleted file mode 100644 index 0175a7dda..000000000 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/VertexEffectTest.java +++ /dev/null @@ -1,124 +0,0 @@ -/****************************************************************************** - * Spine Runtimes License Agreement - * Last updated September 24, 2021. Replaces all prior versions. - * - * Copyright (c) 2013-2021, Esoteric Software LLC - * - * Integration of the Spine Runtimes into software or otherwise creating - * derivative works of the Spine Runtimes is permitted under the terms and - * conditions of Section 2 of the Spine Editor License Agreement: - * http://esotericsoftware.com/spine-editor-license - * - * Otherwise, it is permitted to integrate the Spine Runtimes into software - * or otherwise create derivative works of the Spine Runtimes (collectively, - * "Products"), provided that each user of the Products must obtain their own - * Spine Editor license and redistribution of the Products in any form must - * include this license and copyright notice. - * - * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, - * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *****************************************************************************/ - -package com.esotericsoftware.spine; - -import com.badlogic.gdx.ApplicationAdapter; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application; -import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration; -import com.badlogic.gdx.graphics.OrthographicCamera; -import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch; -import com.badlogic.gdx.graphics.g2d.TextureAtlas; -import com.badlogic.gdx.math.Interpolation; -import com.badlogic.gdx.utils.ScreenUtils; - -import com.esotericsoftware.spine.SkeletonRenderer.VertexEffect; -import com.esotericsoftware.spine.vertexeffects.SwirlEffect; - -/** Demonstrates applying a {@link VertexEffect}. */ -public class VertexEffectTest extends ApplicationAdapter { - OrthographicCamera camera; - PolygonSpriteBatch batch; - SkeletonRenderer renderer; - - SwirlEffect swirl; - float swirlTime; - - TextureAtlas atlas; - Skeleton skeleton; - AnimationState state; - - public void create () { - camera = new OrthographicCamera(); - batch = new PolygonSpriteBatch(); // Required to render meshes. SpriteBatch can't render meshes. - renderer = new SkeletonRenderer(); - renderer.setPremultipliedAlpha(true); - - atlas = new TextureAtlas(Gdx.files.internal("raptor/raptor-pma.atlas")); - SkeletonJson json = new SkeletonJson(atlas); // This loads skeleton JSON data, which is stateless. - json.setScale(0.5f); // Load the skeleton at 50% the size it was in Spine. - SkeletonData skeletonData = json.readSkeletonData(Gdx.files.internal("raptor/raptor-pro.json")); - - skeleton = new Skeleton(skeletonData); // Skeleton holds skeleton state (bone positions, slot attachments, etc). - skeleton.setPosition(350, 45); - - AnimationStateData stateData = new AnimationStateData(skeletonData); // Defines mixing (crossfading) between animations. - - state = new AnimationState(stateData); // Holds the animation state for a skeleton (current animation, time, etc). - state.setTimeScale(0.6f); // Slow all animations down to 60% speed. - - // Queue animations on tracks 0 and 1. - state.setAnimation(0, "walk", true); - state.addAnimation(1, "gun-grab", false, 2); // Keys in higher tracks override the pose from lower tracks. - - swirl = new SwirlEffect(400); - swirl.setCenter(0, 200); - renderer.setVertexEffect(swirl); - // renderer.setVertexEffect(new JitterEffect(10, 10)); - } - - public void render () { - // Update the skeleton and animation time. - float delta = Gdx.graphics.getDeltaTime(); - state.update(delta); - - swirlTime += delta; - float percent = swirlTime % 2; - if (percent > 1) percent = 1 - (percent - 1); - swirl.setAngle(Interpolation.pow2.apply(-60, 60, percent)); - - ScreenUtils.clear(0, 0, 0, 0); - - state.apply(skeleton); // Poses skeleton using current animations. This sets the bones' local SRT. - skeleton.updateWorldTransform(); // Uses the bones' local SRT to compute their world SRT. - - // Configure the camera, SpriteBatch, and SkeletonRendererDebug. - camera.update(); - batch.getProjectionMatrix().set(camera.combined); - - batch.begin(); - renderer.draw(batch, skeleton); // Draw the skeleton images. - batch.end(); - } - - public void resize (int width, int height) { - camera.setToOrtho(false); // Update camera with new size. - } - - public void dispose () { - atlas.dispose(); - } - - public static void main (String[] args) throws Exception { - Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration(); - config.setWindowedMode(800, 600); - new Lwjgl3Application(new VertexEffectTest(), config); - } -} diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java index bc7ed9984..505028dea 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java @@ -53,7 +53,6 @@ public class SkeletonRenderer { private boolean pmaColors, pmaBlendModes; private final FloatArray vertices = new FloatArray(32); private final SkeletonClipping clipper = new SkeletonClipping(); - private @Null VertexEffect vertexEffect; private final Vector2 temp = new Vector2(); private final Vector2 temp2 = new Vector2(); private final Color temp3 = new Color(); @@ -80,9 +79,6 @@ public class SkeletonRenderer { if (batch == null) throw new IllegalArgumentException("batch cannot be null."); if (skeleton == null) throw new IllegalArgumentException("skeleton cannot be null."); - VertexEffect vertexEffect = this.vertexEffect; - if (vertexEffect != null) vertexEffect.begin(skeleton); - boolean pmaColors = this.pmaColors, pmaBlendModes = this.pmaBlendModes; BlendMode blendMode = null; float[] vertices = this.vertices.items; @@ -121,8 +117,6 @@ public class SkeletonRenderer { vertices[v + 2] = uvs[u + 1]; } - if (vertexEffect != null) applyVertexEffect(vertices, 20, 5, c, 0); - batch.draw(region.getRegion().getTexture(), vertices, 0, 20); } else if (attachment instanceof ClippingAttachment) { @@ -138,7 +132,6 @@ public class SkeletonRenderer { if (attachmentSkeleton != null) draw(batch, attachmentSkeleton); } } - if (vertexEffect != null) vertexEffect.end(); } /** Renders the specified skeleton, including meshes, but without two color tinting. @@ -153,8 +146,6 @@ public class SkeletonRenderer { Vector2 tempPosition = this.temp, tempUV = this.temp2; Color tempLight1 = this.temp3, tempDark1 = this.temp4; Color tempLight2 = this.temp5, tempDark2 = this.temp6; - VertexEffect vertexEffect = this.vertexEffect; - if (vertexEffect != null) vertexEffect.begin(skeleton); boolean pmaColors = this.pmaColors, pmaBlendModes = this.pmaBlendModes; BlendMode blendMode = null; @@ -228,33 +219,13 @@ public class SkeletonRenderer { clipper.clipTriangles(vertices, verticesLength, triangles, triangles.length, uvs, c, 0, false); FloatArray clippedVertices = clipper.getClippedVertices(); ShortArray clippedTriangles = clipper.getClippedTriangles(); - if (vertexEffect != null) applyVertexEffect(clippedVertices.items, clippedVertices.size, 5, c, 0); batch.draw(texture, clippedVertices.items, 0, clippedVertices.size, clippedTriangles.items, 0, clippedTriangles.size); } else { - if (vertexEffect != null) { - tempLight1.set(NumberUtils.floatToIntColor(c)); - tempDark1.set(0); - for (int v = 0, u = 0; v < verticesLength; v += 5, u += 2) { - tempPosition.x = vertices[v]; - tempPosition.y = vertices[v + 1]; - tempLight2.set(tempLight1); - tempDark2.set(tempDark1); - tempUV.x = uvs[u]; - tempUV.y = uvs[u + 1]; - vertexEffect.transform(tempPosition, tempUV, tempLight2, tempDark2); - vertices[v] = tempPosition.x; - vertices[v + 1] = tempPosition.y; - vertices[v + 2] = tempLight2.toFloatBits(); - vertices[v + 3] = tempUV.x; - vertices[v + 4] = tempUV.y; - } - } else { - for (int v = 2, u = 0; v < verticesLength; v += 5, u += 2) { - vertices[v] = c; - vertices[v + 1] = uvs[u]; - vertices[v + 2] = uvs[u + 1]; - } + for (int v = 2, u = 0; v < verticesLength; v += 5, u += 2) { + vertices[v] = c; + vertices[v + 1] = uvs[u]; + vertices[v + 2] = uvs[u + 1]; } batch.draw(texture, vertices, 0, verticesLength, triangles, 0, triangles.length); } @@ -263,7 +234,6 @@ public class SkeletonRenderer { clipper.clipEnd(slot); } clipper.clipEnd(); - if (vertexEffect != null) vertexEffect.end(); } /** Renders the specified skeleton, including meshes and two color tinting. @@ -278,8 +248,6 @@ public class SkeletonRenderer { Vector2 tempPosition = this.temp, tempUV = this.temp2; Color tempLight1 = this.temp3, tempDark1 = this.temp4; Color tempLight2 = this.temp5, tempDark2 = this.temp6; - VertexEffect vertexEffect = this.vertexEffect; - if (vertexEffect != null) vertexEffect.begin(skeleton); boolean pmaColors = this.pmaColors, pmaBlendModes = this.pmaBlendModes; batch.setPremultipliedAlpha(pmaColors); @@ -362,35 +330,14 @@ public class SkeletonRenderer { clipper.clipTriangles(vertices, verticesLength, triangles, triangles.length, uvs, light, dark, true); FloatArray clippedVertices = clipper.getClippedVertices(); ShortArray clippedTriangles = clipper.getClippedTriangles(); - if (vertexEffect != null) applyVertexEffect(clippedVertices.items, clippedVertices.size, 6, light, dark); batch.drawTwoColor(texture, clippedVertices.items, 0, clippedVertices.size, clippedTriangles.items, 0, clippedTriangles.size); } else { - if (vertexEffect != null) { - tempLight1.set(NumberUtils.floatToIntColor(light)); - tempDark1.set(NumberUtils.floatToIntColor(dark)); - for (int v = 0, u = 0; v < verticesLength; v += 6, u += 2) { - tempPosition.x = vertices[v]; - tempPosition.y = vertices[v + 1]; - tempLight2.set(tempLight1); - tempDark2.set(tempDark1); - tempUV.x = uvs[u]; - tempUV.y = uvs[u + 1]; - vertexEffect.transform(tempPosition, tempUV, tempLight2, tempDark2); - vertices[v] = tempPosition.x; - vertices[v + 1] = tempPosition.y; - vertices[v + 2] = tempLight2.toFloatBits(); - vertices[v + 3] = tempDark2.toFloatBits(); - vertices[v + 4] = tempUV.x; - vertices[v + 5] = tempUV.y; - } - } else { - for (int v = 2, u = 0; v < verticesLength; v += 6, u += 2) { - vertices[v] = light; - vertices[v + 1] = dark; - vertices[v + 2] = uvs[u]; - vertices[v + 3] = uvs[u + 1]; - } + for (int v = 2, u = 0; v < verticesLength; v += 6, u += 2) { + vertices[v] = light; + vertices[v + 1] = dark; + vertices[v + 2] = uvs[u]; + vertices[v + 3] = uvs[u + 1]; } batch.drawTwoColor(texture, vertices, 0, verticesLength, triangles, 0, triangles.length); } @@ -399,14 +346,12 @@ public class SkeletonRenderer { clipper.clipEnd(slot); } clipper.clipEnd(); - if (vertexEffect != null) vertexEffect.end(); } private void applyVertexEffect (float[] vertices, int verticesLength, int stride, float light, float dark) { Vector2 tempPosition = this.temp, tempUV = this.temp2; Color tempLight1 = this.temp3, tempDark1 = this.temp4; Color tempLight2 = this.temp5, tempDark2 = this.temp6; - VertexEffect vertexEffect = this.vertexEffect; tempLight1.set(NumberUtils.floatToIntColor(light)); tempDark1.set(NumberUtils.floatToIntColor(dark)); if (stride == 5) { @@ -417,7 +362,6 @@ public class SkeletonRenderer { tempUV.y = vertices[v + 4]; tempLight2.set(tempLight1); tempDark2.set(tempDark1); - vertexEffect.transform(tempPosition, tempUV, tempLight2, tempDark2); vertices[v] = tempPosition.x; vertices[v + 1] = tempPosition.y; vertices[v + 2] = tempLight2.toFloatBits(); @@ -432,7 +376,6 @@ public class SkeletonRenderer { tempUV.y = vertices[v + 5]; tempLight2.set(tempLight1); tempDark2.set(tempDark1); - vertexEffect.transform(tempPosition, tempUV, tempLight2, tempDark2); vertices[v] = tempPosition.x; vertices[v + 1] = tempPosition.y; vertices[v + 2] = tempLight2.toFloatBits(); @@ -468,21 +411,4 @@ public class SkeletonRenderer { pmaColors = pmaColorsAndBlendModes; pmaBlendModes = pmaColorsAndBlendModes; } - - public @Null VertexEffect getVertexEffect () { - return vertexEffect; - } - - public void setVertexEffect (@Null VertexEffect vertexEffect) { - this.vertexEffect = vertexEffect; - } - - /** Modifies the skeleton or vertex positions, UVs, or colors during rendering. */ - static public interface VertexEffect { - public void begin (Skeleton skeleton); - - public void transform (Vector2 position, Vector2 uv, Color color, Color darkColor); - - public void end (); - } } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/vertexeffects/JitterEffect.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/vertexeffects/JitterEffect.java deleted file mode 100644 index c67aa490d..000000000 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/vertexeffects/JitterEffect.java +++ /dev/null @@ -1,70 +0,0 @@ -/****************************************************************************** - * Spine Runtimes License Agreement - * Last updated September 24, 2021. Replaces all prior versions. - * - * Copyright (c) 2013-2021, Esoteric Software LLC - * - * Integration of the Spine Runtimes into software or otherwise creating - * derivative works of the Spine Runtimes is permitted under the terms and - * conditions of Section 2 of the Spine Editor License Agreement: - * http://esotericsoftware.com/spine-editor-license - * - * Otherwise, it is permitted to integrate the Spine Runtimes into software - * or otherwise create derivative works of the Spine Runtimes (collectively, - * "Products"), provided that each user of the Products must obtain their own - * Spine Editor license and redistribution of the Products in any form must - * include this license and copyright notice. - * - * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, - * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *****************************************************************************/ - -package com.esotericsoftware.spine.vertexeffects; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.math.MathUtils; -import com.badlogic.gdx.math.Vector2; - -import com.esotericsoftware.spine.Skeleton; -import com.esotericsoftware.spine.SkeletonRenderer.VertexEffect; - -public class JitterEffect implements VertexEffect { - private float x, y; - - public JitterEffect (float x, float y) { - this.x = x; - this.y = y; - } - - public void begin (Skeleton skeleton) { - } - - public void transform (Vector2 position, Vector2 uv, Color light, Color dark) { - position.x += MathUtils.randomTriangular(-x, y); - position.y += MathUtils.randomTriangular(-x, y); - } - - public void end () { - } - - public void setJitter (float x, float y) { - this.x = x; - this.y = y; - } - - public void setJitterX (float x) { - this.x = x; - } - - public void setJitterY (float y) { - this.y = y; - } -} diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/vertexeffects/SwirlEffect.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/vertexeffects/SwirlEffect.java deleted file mode 100644 index a8efcacab..000000000 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/vertexeffects/SwirlEffect.java +++ /dev/null @@ -1,98 +0,0 @@ -/****************************************************************************** - * Spine Runtimes License Agreement - * Last updated September 24, 2021. Replaces all prior versions. - * - * Copyright (c) 2013-2021, Esoteric Software LLC - * - * Integration of the Spine Runtimes into software or otherwise creating - * derivative works of the Spine Runtimes is permitted under the terms and - * conditions of Section 2 of the Spine Editor License Agreement: - * http://esotericsoftware.com/spine-editor-license - * - * Otherwise, it is permitted to integrate the Spine Runtimes into software - * or otherwise create derivative works of the Spine Runtimes (collectively, - * "Products"), provided that each user of the Products must obtain their own - * Spine Editor license and redistribution of the Products in any form must - * include this license and copyright notice. - * - * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, - * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *****************************************************************************/ - -package com.esotericsoftware.spine.vertexeffects; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.math.Interpolation; -import com.badlogic.gdx.math.MathUtils; -import com.badlogic.gdx.math.Vector2; - -import com.esotericsoftware.spine.Skeleton; -import com.esotericsoftware.spine.SkeletonRenderer.VertexEffect; -import com.esotericsoftware.spine.utils.SpineUtils; - -public class SwirlEffect implements VertexEffect { - private float worldX, worldY, radius, angle; - private Interpolation interpolation = Interpolation.pow2Out; - private float centerX, centerY; - - public SwirlEffect (float radius) { - this.radius = radius; - } - - public void begin (Skeleton skeleton) { - worldX = skeleton.getX() + centerX; - worldY = skeleton.getY() + centerY; - } - - public void transform (Vector2 position, Vector2 uv, Color light, Color dark) { - float x = position.x - worldX; - float y = position.y - worldY; - float dist = (float)Math.sqrt(x * x + y * y); - if (dist < radius) { - float theta = interpolation.apply(0, angle, (radius - dist) / radius); - float cos = SpineUtils.cos(theta), sin = SpineUtils.sin(theta); - position.x = cos * x - sin * y + worldX; - position.y = sin * x + cos * y + worldY; - } - } - - public void end () { - } - - public void setRadius (float radius) { - this.radius = radius; - } - - public void setCenter (float centerX, float centerY) { - this.centerX = centerX; - this.centerY = centerY; - } - - public void setCenterX (float centerX) { - this.centerX = centerX; - } - - public void setCenterY (float centerY) { - this.centerY = centerY; - } - - public void setAngle (float degrees) { - this.angle = degrees * MathUtils.degRad; - } - - public Interpolation getInterpolation () { - return interpolation; - } - - public void setInterpolation (Interpolation interpolation) { - this.interpolation = interpolation; - } -} From 94277320385d5fdc1edaae5804ecfcaec529cbe8 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Mon, 30 May 2022 20:58:25 +0200 Subject: [PATCH 2/3] [unity] Added `UnscaledTime` property at `SkeletonAnimation`, behaving like `SkeletonGraphic.UnscaledTime`. --- CHANGELOG.md | 2 ++ .../Editor/Components/SkeletonAnimationInspector.cs | 8 +++++++- .../Editor/Components/SkeletonGraphicInspector.cs | 7 +++++-- .../spine-unity/Components/SkeletonAnimation.cs | 11 +++++++++-- .../Runtime/spine-unity/Components/SkeletonGraphic.cs | 4 +++- .../Spine/Runtime/spine-unity/ISkeletonAnimation.cs | 10 ++++++++++ 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbad1ab5a..a453aecc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -241,6 +241,7 @@ Also removed less commonly used extension methods: `TrackEntry.AllowImmediateQueue()`, `Animation.SetKeyedItemsToSetupPose()` and `Attachment.IsRenderable()`. + * Made `SkeletonGraphic.unscaledTime` parameter protected, use the new property `UnscaledTime` instead. * **`SkeletonGraphic` now no longer uses a `RawImage` component at each submesh renderer** GameObject when `allowMultipleCanvasRenderers` is true. Instead, a new custom component `SkeletonSubmeshGraphic` is used which is more resource friendly. Replacement of these components will be performed automatically through editor scripting, saving scenes or prefabs will persist the upgrade. * **Linear color space:** Previously Slot colors were not displayed the same in Unity as in the Spine Editor. This is now fixed at all shaders, including URP and LWRP shaders. See section *Additions* below for more details. If you have tweaked Slot colors to look correct in `Linear` color space in Unity but incorrect in Spine, you might want to adjust the tweaked colors. Slot colors displayed in Unity should now match colors displayed in the Spine Editor when configured to display as `Linear` color space in the Spine Editor Settings. @@ -307,6 +308,7 @@ * Added example component `SkeletonRenderTexture` to render a `SkeletonRenderer` to a `RenderTexture`, mainly for proper transparency. Added an example scene named `RenderTexture FadeOut Transparency` that demonstrates usage for a fadeout transparency effect. * Added another fadeout example component named `SkeletonRenderTextureFadeout` which takes over transparency fadeout when enabled. You can use this component as-is, attach it in disabled state and enable it to start a fadeout effect. * Timeline clips now offer an additional `Alpha` parameter for setting a custom constant mix alpha value other than 1.0, just as `TrackEntry.Alpha`. Defaults to 1.0. + * Added `UnscaledTime` property at `SkeletonAnimation` as well, behaving like `SkeletonGraphic.UnscaledTime`. If enabled, AnimationState uses unscaled game time (`Time.unscaledDeltaTime`), running animations independent of e.g. game pause (`Time.timeScale`). * **Changes of default values** diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonAnimationInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonAnimationInspector.cs index 3de82334b..427ba6226 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonAnimationInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonAnimationInspector.cs @@ -36,16 +36,21 @@ namespace Spine.Unity.Editor { [CustomEditor(typeof(SkeletonAnimation))] [CanEditMultipleObjects] public class SkeletonAnimationInspector : SkeletonRendererInspector { - protected SerializedProperty animationName, loop, timeScale, autoReset; + protected SerializedProperty animationName, loop, timeScale, unscaledTime, autoReset; protected bool wasAnimationParameterChanged = false; readonly GUIContent LoopLabel = new GUIContent("Loop", "Whether or not .AnimationName should loop. This only applies to the initial animation specified in the inspector, or any subsequent Animations played through .AnimationName. Animations set through state.SetAnimation are unaffected."); readonly GUIContent TimeScaleLabel = new GUIContent("Time Scale", "The rate at which animations progress over time. 1 means normal speed. 0.5 means 50% speed."); + readonly GUIContent UnscaledTimeLabel = new GUIContent("Unscaled Time", + "If enabled, AnimationState uses unscaled game time (Time.unscaledDeltaTime), " + + "running animations independent of e.g. game pause (Time.timeScale). " + + "Instance SkeletonAnimation.timeScale will still be applied."); protected override void OnEnable () { base.OnEnable(); animationName = serializedObject.FindProperty("_animationName"); loop = serializedObject.FindProperty("loop"); timeScale = serializedObject.FindProperty("timeScale"); + unscaledTime = serializedObject.FindProperty("unscaledTime"); } protected override void DrawInspectorGUI (bool multi) { @@ -69,6 +74,7 @@ namespace Spine.Unity.Editor { EditorGUILayout.PropertyField(loop, LoopLabel); wasAnimationParameterChanged |= EditorGUI.EndChangeCheck(); // Value used in the next update. EditorGUILayout.PropertyField(timeScale, TimeScaleLabel); + EditorGUILayout.PropertyField(unscaledTime, UnscaledTimeLabel); foreach (var o in targets) { var component = o as SkeletonAnimation; component.timeScale = Mathf.Max(component.timeScale, 0); diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicInspector.cs index e3f439147..c6a402943 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/SkeletonGraphicInspector.cs @@ -62,7 +62,10 @@ namespace Spine.Unity.Editor { SerializedProperty allowMultipleCanvasRenderers, separatorSlotNames, enableSeparatorSlots, updateSeparatorPartLocation; SerializedProperty raycastTarget; - + readonly GUIContent UnscaledTimeLabel = new GUIContent("Unscaled Time", + "If enabled, AnimationState uses unscaled game time (Time.unscaledDeltaTime), " + + "running animations independent of e.g. game pause (Time.timeScale). " + + "Instance SkeletonAnimation.timeScale will still be applied."); SkeletonGraphic thisSkeletonGraphic; protected bool isInspectingPrefab; @@ -284,7 +287,7 @@ namespace Spine.Unity.Editor { 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(unscaledTime, UnscaledTimeLabel); EditorGUILayout.Space(); EditorGUILayout.PropertyField(freeze); EditorGUILayout.Space(); diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs index 5d536f44d..962eb6f57 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonAnimation.cs @@ -93,6 +93,13 @@ namespace Spine.Unity { [SerializeField] protected UpdateTiming updateTiming = UpdateTiming.InUpdate; public UpdateTiming UpdateTiming { get { return updateTiming; } set { updateTiming = value; } } + + /// If enabled, AnimationState uses unscaled game time + /// (Time.unscaledDeltaTime instead of normal game time(Time.deltaTime), + /// running animations independent of e.g. game pause (Time.timeScale). + /// Instance SkeletonAnimation.timeScale will still be applied. + [SerializeField] protected bool unscaledTime; + public bool UnscaledTime { get { return unscaledTime; } set { unscaledTime = value; } } #endregion #region Serialized state and Beginner API @@ -200,12 +207,12 @@ namespace Spine.Unity { } #endif if (updateTiming != UpdateTiming.InUpdate) return; - Update(Time.deltaTime); + Update(unscaledTime ? Time.unscaledDeltaTime : Time.deltaTime); } virtual protected void FixedUpdate () { if (updateTiming != UpdateTiming.InFixedUpdate) return; - Update(Time.deltaTime); + Update(unscaledTime ? Time.unscaledDeltaTime : Time.deltaTime); } /// Progresses the AnimationState according to the given deltaTime, and applies it to the Skeleton. Use Time.deltaTime to update manually. Use deltaTime 0 to update without progressing the time. diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs index efc4d95e4..7b1e244e7 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs @@ -77,7 +77,6 @@ namespace Spine.Unity { /// reset to UpdateMode.FullUpdate when the mesh becomes visible again. public UpdateMode updateWhenInvisible = UpdateMode.FullUpdate; - public bool unscaledTime; public bool allowMultipleCanvasRenderers = false; public List canvasRenderers = new List(); protected List submeshGraphics = new List(); @@ -499,6 +498,9 @@ namespace Spine.Unity { [SerializeField] protected UpdateTiming updateTiming = UpdateTiming.InUpdate; public UpdateTiming UpdateTiming { get { return updateTiming; } set { updateTiming = value; } } + [SerializeField] protected bool unscaledTime; + public bool UnscaledTime { get { return unscaledTime; } set { unscaledTime = value; } } + /// Occurs after the vertex data populated every frame, before the vertices are pushed into the mesh. public event Spine.Unity.MeshGeneratorDelegate OnPostProcessVertices; diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/ISkeletonAnimation.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/ISkeletonAnimation.cs index a3d08b3ae..c43489e89 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/ISkeletonAnimation.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/ISkeletonAnimation.cs @@ -43,6 +43,11 @@ namespace Spine.Unity { InFixedUpdate } + public enum UpdateTimeScale { + GameTime = 0, + UnscaledGameTime + } + public delegate void UpdateBonesDelegate (ISkeletonAnimation animated); public interface ISpineComponent { } @@ -82,6 +87,11 @@ namespace Spine.Unity { public interface IAnimationStateComponent : ISpineComponent { /// Gets the Spine.AnimationState of the animated Spine Component. This is equivalent to SkeletonAnimation.state. AnimationState AnimationState { get; } + /// If enabled, AnimationState time is advanced by Unscaled Game Time + /// (Time.unscaledDeltaTime instead of the default Game Time(Time.deltaTime). + /// to animate independent of game Time.timeScale. + /// Instance SkeletonGraphic.timeScale and SkeletonAnimation.timeScale will still be applied. + public bool UnscaledTime { get; set; } } /// A Spine-Unity Component that holds a reference to a SkeletonRenderer. From 8753dfcb8f458d71b68b545c0a4d9be92408829b Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Tue, 31 May 2022 12:20:36 +0200 Subject: [PATCH 3/3] Updated CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a453aecc0..c0b1cdf57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ * `spVertexAttachment->deformAttachment` was renamed to `spVertexAttachment->timelineAttachment`. * `spSkeleton_update()` has been removed. * `spSkeleton->time` has been removed. + * `spVertexEffect` has been removed. ### SFML * Updated example to use SFML 2.5.1. @@ -35,6 +36,7 @@ * `VertexAttachment::getDeformAttachment()` was renamed to `VertexAttachment::getTimelineAttachment()`. * `Skeleton::update()` has been removed. * `Skeleton::getTime()` has been removed. + * `VertexEffect` has been removed. ### Cocos2d-x @@ -104,6 +106,7 @@ * `VertexAttachment#setDeformAttachment()` and `VertexAttachment#getDeformAttachment()` have been replaced with `VertexAttachment#setTimelineAttachment()` and `VertexAttachment#getTimelineAttachment()`. * `RegionAttachment#updateOffset()` has been renamed to `RegionAttachment#updateRegion()`. The caller must ensure that the attachment's region is not `null`. * `RegionAttachment#computeWorldVertices()` takes a `Slot` instead of a `Bone` as the first argument. + * `VertexEffect` has been removed. ### libGDX @@ -123,6 +126,7 @@ * `RegionAttachment#updateOffset()` has been renamed to `RegionAttachment#updateRegion()`. The caller must ensure that the attachment's region is not `null`. * `RegionAttachment#computeWorldVertices()` takes a `Slot` instead of a `Bone` as the first argument. * Removed `PlayerEditor`. + * `VertexEffect` has been removed. ### WebGL backend * `PolygonBatcher.start()` now disables culling and restores the previous state on `PolygonBatcher.end()`.