mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-06 07:14:55 +08:00
Merge branch '4.1-beta' into 4.2-beta
This commit is contained in:
commit
ec327ef4fe
@ -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()`.
|
||||
@ -241,6 +245,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 +312,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**
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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 ();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -93,6 +93,13 @@ namespace Spine.Unity {
|
||||
|
||||
[SerializeField] protected UpdateTiming updateTiming = UpdateTiming.InUpdate;
|
||||
public UpdateTiming UpdateTiming { get { return updateTiming; } set { updateTiming = value; } }
|
||||
|
||||
/// <summary>If enabled, AnimationState uses unscaled game time
|
||||
/// (<c>Time.unscaledDeltaTime</c> instead of normal game time(<c>Time.deltaTime</c>),
|
||||
/// running animations independent of e.g. game pause (<c>Time.timeScale</c>).
|
||||
/// Instance SkeletonAnimation.timeScale will still be applied.</summary>
|
||||
[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);
|
||||
}
|
||||
|
||||
/// <summary>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.</summary>
|
||||
|
||||
@ -77,7 +77,6 @@ namespace Spine.Unity {
|
||||
/// reset to <c>UpdateMode.FullUpdate</c> when the mesh becomes visible again.</summary>
|
||||
public UpdateMode updateWhenInvisible = UpdateMode.FullUpdate;
|
||||
|
||||
public bool unscaledTime;
|
||||
public bool allowMultipleCanvasRenderers = false;
|
||||
public List<CanvasRenderer> canvasRenderers = new List<CanvasRenderer>();
|
||||
protected List<SkeletonSubmeshGraphic> submeshGraphics = new List<SkeletonSubmeshGraphic>();
|
||||
@ -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; } }
|
||||
|
||||
/// <summary> Occurs after the vertex data populated every frame, before the vertices are pushed into the mesh.</summary>
|
||||
public event Spine.Unity.MeshGeneratorDelegate OnPostProcessVertices;
|
||||
|
||||
|
||||
@ -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 {
|
||||
/// <summary>Gets the Spine.AnimationState of the animated Spine Component. This is equivalent to SkeletonAnimation.state.</summary>
|
||||
AnimationState AnimationState { get; }
|
||||
/// <summary>If enabled, AnimationState time is advanced by Unscaled Game Time
|
||||
/// (<c>Time.unscaledDeltaTime</c> instead of the default Game Time(<c>Time.deltaTime</c>).
|
||||
/// to animate independent of game <c>Time.timeScale</c>.
|
||||
/// Instance SkeletonGraphic.timeScale and SkeletonAnimation.timeScale will still be applied.</summary>
|
||||
public bool UnscaledTime { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>A Spine-Unity Component that holds a reference to a SkeletonRenderer.</summary>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user