diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/BonePlotting.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/BonePlotting.java index fbd35dee4..6451ae162 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/BonePlotting.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/BonePlotting.java @@ -34,6 +34,7 @@ import com.badlogic.gdx.utils.Null; import com.esotericsoftware.spine.Animation.MixBlend; import com.esotericsoftware.spine.Animation.MixDirection; +import com.esotericsoftware.spine.Skeleton.Physics; import com.esotericsoftware.spine.attachments.AttachmentLoader; import com.esotericsoftware.spine.attachments.BoundingBoxAttachment; import com.esotericsoftware.spine.attachments.ClippingAttachment; @@ -83,7 +84,7 @@ public class BonePlotting { float time = 0; while (time < animation.getDuration()) { animation.apply(skeleton, time, time, false, null, 1, MixBlend.first, MixDirection.in); - skeleton.updateWorldTransform(); + skeleton.updateWorldTransform(Physics.update); System.out.println(animation.getName() + "," // + bone.getWorldX() + "," + bone.getWorldY() + "," + bone.getWorldRotationX()); diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/Box2DExample.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/Box2DExample.java index a27a9b27c..caf1c4b63 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/Box2DExample.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/Box2DExample.java @@ -54,6 +54,7 @@ import com.badlogic.gdx.utils.ScreenUtils; import com.esotericsoftware.spine.Animation.MixBlend; import com.esotericsoftware.spine.Animation.MixDirection; +import com.esotericsoftware.spine.Skeleton.Physics; import com.esotericsoftware.spine.attachments.AtlasAttachmentLoader; import com.esotericsoftware.spine.attachments.RegionAttachment; import com.esotericsoftware.spine.attachments.Sequence; @@ -104,7 +105,7 @@ public class Box2DExample extends ApplicationAdapter { skeleton = new Skeleton(skeletonData); skeleton.x = -32; skeleton.y = 1; - skeleton.updateWorldTransform(); + skeleton.updateWorldTransform(Physics.update); // See Box2DTest in libgdx for more detailed information about Box2D setup. camera = new OrthographicCamera(48, 32); @@ -150,7 +151,7 @@ public class Box2DExample extends ApplicationAdapter { animation.apply(skeleton, time, time, true, events, 1, MixBlend.first, MixDirection.in); skeleton.x += 8 * delta; - skeleton.updateWorldTransform(); + skeleton.updateWorldTransform(Physics.update); skeletonRenderer.draw(batch, skeleton); batch.end(); diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/FboTest.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/FboTest.java index cabac8715..dd1621216 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/FboTest.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/FboTest.java @@ -42,6 +42,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.graphics.glutils.FrameBuffer; import com.badlogic.gdx.utils.ScreenUtils; +import com.esotericsoftware.spine.Skeleton.Physics; import com.esotericsoftware.spine.utils.TwoColorPolygonBatch; /** Demonstrates rendering an animation to a frame buffer (FBO) and then rendering the FBO to the screen. */ @@ -75,7 +76,7 @@ public class FboTest extends ApplicationAdapter { // Create a skeleton instance, set the position of its root bone, and update its world transform. skeleton = new Skeleton(skeletonData); skeleton.setPosition(250, 20); - skeleton.updateWorldTransform(); + skeleton.updateWorldTransform(Physics.update); // Create an FBO and a texture region with Y flipped. fbo = new FrameBuffer(Pixmap.Format.RGBA8888, 512, 512, false); diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/IKTest.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/IKTest.java index c42577b60..0ea9f26de 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/IKTest.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/IKTest.java @@ -38,6 +38,7 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.utils.ScreenUtils; +import com.esotericsoftware.spine.Skeleton.Physics; import com.esotericsoftware.spine.utils.TwoColorPolygonBatch; /** Demonstrates how to let the target bone of an IK constraint follow the mouse or touch position, which in turn repositions part @@ -97,7 +98,7 @@ public class IKTest extends ApplicationAdapter { // later. state.update(Gdx.graphics.getDeltaTime()); state.apply(skeleton); - skeleton.updateWorldTransform(); + skeleton.updateWorldTransform(Physics.update); // Position the "crosshair" bone at the mouse // location. We do this before calling @@ -122,7 +123,7 @@ public class IKTest extends ApplicationAdapter { // Calculate final world transform with the // crosshair bone set to the mouse cursor // position. - skeleton.updateWorldTransform(); + skeleton.updateWorldTransform(Physics.update); // Clear the screen, update the camera and // render the skeleton. diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/MixAndMatchTest.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/MixAndMatchTest.java index 24d143c8c..34fccbe31 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/MixAndMatchTest.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/MixAndMatchTest.java @@ -37,6 +37,8 @@ import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.utils.ScreenUtils; +import com.esotericsoftware.spine.Skeleton.Physics; + /** Demonstrates creating and configuring a new skin at runtime. */ public class MixAndMatchTest extends ApplicationAdapter { OrthographicCamera camera; @@ -92,7 +94,7 @@ public class MixAndMatchTest extends ApplicationAdapter { 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. + skeleton.updateWorldTransform(Physics.update); // Uses the bones' local SRT to compute their world SRT. // Configure the camera, and PolygonSpriteBatch camera.update(); diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/NormalMapTest.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/NormalMapTest.java index 119a632bb..0743ef562 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/NormalMapTest.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/NormalMapTest.java @@ -58,6 +58,7 @@ import com.badlogic.gdx.utils.ScreenUtils; import com.esotericsoftware.spine.Animation.MixBlend; import com.esotericsoftware.spine.Animation.MixDirection; +import com.esotericsoftware.spine.Skeleton.Physics; /** Demonstrates simplistic usage of lighting with normal maps. *

@@ -110,7 +111,7 @@ public class NormalMapTest extends ApplicationAdapter { skeleton = new Skeleton(skeleton); skeleton.setX(ui.prefs.getFloat("x", Gdx.graphics.getWidth() / 2)); skeleton.setY(ui.prefs.getFloat("y", Gdx.graphics.getHeight() / 4)); - skeleton.updateWorldTransform(); + skeleton.updateWorldTransform(Physics.update); Gdx.input.setInputProcessor(new InputMultiplexer(ui.stage, new InputAdapter() { public boolean touchDown (int screenX, int screenY, int pointer, int button) { @@ -136,7 +137,7 @@ public class NormalMapTest extends ApplicationAdapter { float lastTime = time; time += Gdx.graphics.getDeltaTime(); if (animation != null) animation.apply(skeleton, lastTime, time, true, null, 1, MixBlend.first, MixDirection.in); - skeleton.updateWorldTransform(); + skeleton.updateWorldTransform(Physics.update); lightPosition.x = Gdx.input.getX(); lightPosition.y = (Gdx.graphics.getHeight() - 1 - Gdx.input.getY()); diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/PngExportTest.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/PngExportTest.java index 648e7532a..4259e0c42 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/PngExportTest.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/PngExportTest.java @@ -48,6 +48,7 @@ import com.badlogic.gdx.utils.ScreenUtils; import com.esotericsoftware.spine.Animation.MixBlend; import com.esotericsoftware.spine.Animation.MixDirection; +import com.esotericsoftware.spine.Skeleton.Physics; import com.esotericsoftware.spine.utils.TwoColorPolygonBatch; /** Demonstrates rendering an animation to a frame buffer (FBO) and then writing each frame as a PNG. */ @@ -81,7 +82,7 @@ public class PngExportTest extends ApplicationAdapter { // Create a skeleton instance, set the position of its root bone, and update its world transform. skeleton = new Skeleton(skeletonData); skeleton.setPosition(250, 20); - skeleton.updateWorldTransform(); + skeleton.updateWorldTransform(Physics.update); // Create an FBO and a texture region. fbo = new FrameBuffer(Pixmap.Format.RGBA8888, 512, 512, false); @@ -104,7 +105,7 @@ public class PngExportTest extends ApplicationAdapter { int frame = 1; while (time < animation.getDuration()) { animation.apply(skeleton, time, time, false, null, 1, MixBlend.first, MixDirection.in); - skeleton.updateWorldTransform(); + skeleton.updateWorldTransform(Physics.update); // Render the skeleton to the FBO. ScreenUtils.clear(0, 0, 0, 0); diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SimpleTest1.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SimpleTest1.java index e1f613e83..55947d066 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SimpleTest1.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SimpleTest1.java @@ -36,6 +36,7 @@ import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.esotericsoftware.spine.Skeleton.Physics; import com.esotericsoftware.spine.utils.TwoColorPolygonBatch; /** Demonstrates loading, animating, and rendering a skeleton. @@ -86,7 +87,7 @@ public class SimpleTest1 extends ApplicationAdapter { Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 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. + skeleton.updateWorldTransform(Physics.update); // Uses the bones' local SRT to compute their world SRT. // Configure the camera, SpriteBatch, and SkeletonRendererDebug. camera.update(); diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SimpleTest2.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SimpleTest2.java index 94fa8f0df..f2309c6fa 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SimpleTest2.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SimpleTest2.java @@ -41,6 +41,7 @@ import com.badlogic.gdx.math.Vector3; import com.esotericsoftware.spine.AnimationState.AnimationStateListener; import com.esotericsoftware.spine.AnimationState.TrackEntry; +import com.esotericsoftware.spine.Skeleton.Physics; import com.esotericsoftware.spine.attachments.BoundingBoxAttachment; import com.esotericsoftware.spine.utils.TwoColorPolygonBatch; @@ -147,7 +148,7 @@ public class SimpleTest2 extends ApplicationAdapter { Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); if (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. + skeleton.updateWorldTransform(Physics.update); // Uses the bones' local SRT to compute their world SRT. // Configure the camera, SpriteBatch, and SkeletonRendererDebug. camera.update(); diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SimpleTest3.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SimpleTest3.java index b91541ceb..90aa9fda2 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SimpleTest3.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SimpleTest3.java @@ -37,6 +37,8 @@ import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.utils.ScreenUtils; +import com.esotericsoftware.spine.Skeleton.Physics; + /** Demonstrates applying multiple animations at once using {@link AnimationState} tracks. */ public class SimpleTest3 extends ApplicationAdapter { OrthographicCamera camera; @@ -84,7 +86,7 @@ public class SimpleTest3 extends ApplicationAdapter { ScreenUtils.clear(0, 0, 0, 0); if (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. + skeleton.updateWorldTransform(Physics.update); // Uses the bones' local SRT to compute their world SRT. // Configure the camera, SpriteBatch, and SkeletonRendererDebug. camera.update(); diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SkeletonAssetManagerTest.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SkeletonAssetManagerTest.java index 1c8d490e4..e5738d9f9 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SkeletonAssetManagerTest.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SkeletonAssetManagerTest.java @@ -38,6 +38,7 @@ import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.utils.ScreenUtils; +import com.esotericsoftware.spine.Skeleton.Physics; import com.esotericsoftware.spine.utils.SkeletonDataLoader; import com.esotericsoftware.spine.utils.SkeletonDataLoader.SkeletonDataParameter; @@ -102,7 +103,7 @@ public class SkeletonAssetManagerTest extends ApplicationAdapter { state.update(Gdx.graphics.getDeltaTime()); // Update the animation time. 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. + skeleton.updateWorldTransform(Physics.update); // Uses the bones' local SRT to compute their world SRT. // Configure the camera, SpriteBatch, and SkeletonRendererDebug. camera.update(); diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SkeletonAttachmentTest.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SkeletonAttachmentTest.java index 30318727b..b176bfa1f 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SkeletonAttachmentTest.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/SkeletonAttachmentTest.java @@ -37,6 +37,7 @@ import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.utils.ScreenUtils; +import com.esotericsoftware.spine.Skeleton.Physics; import com.esotericsoftware.spine.attachments.SkeletonAttachment; /** Demonstrates using {@link SkeletonAttachment} to use an entire skeleton as an attachment. */ @@ -93,11 +94,11 @@ public class SkeletonAttachmentTest extends ApplicationAdapter { public void render () { spineboyState.update(Gdx.graphics.getDeltaTime()); spineboyState.apply(spineboy); - spineboy.updateWorldTransform(); + spineboy.updateWorldTransform(Physics.update); goblinState.update(Gdx.graphics.getDeltaTime()); goblinState.apply(goblin); - goblin.updateWorldTransform(attachmentBone); + goblin.updateWorldTransform(Physics.update, attachmentBone); ScreenUtils.clear(0, 0, 0, 0); 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 3a67882b4..dc3fd1399 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 @@ -39,6 +39,8 @@ import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.utils.ScreenUtils; +import com.esotericsoftware.spine.Skeleton.Physics; + /** Boilerplate for basic skeleton rendering, used for various testing. */ public class TestHarness extends ApplicationAdapter { // static String JSON = "coin/coin-pro.json"; @@ -79,7 +81,7 @@ public class TestHarness extends ApplicationAdapter { // state.setAnimation(0, "rotate", false); state.update(0); state.apply(skeleton); - skeleton.updateWorldTransform(); + skeleton.updateWorldTransform(Physics.update); } public void render () { @@ -87,7 +89,7 @@ public class TestHarness extends ApplicationAdapter { state.update(0.25f); // Update the animation time. } 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. + skeleton.updateWorldTransform(Physics.update); // Uses the bones' local SRT to compute their world SRT. ScreenUtils.clear(0, 0, 0, 0); diff --git a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/TimelineApiTest.java b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/TimelineApiTest.java index 0ccfed366..8d493779e 100644 --- a/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/TimelineApiTest.java +++ b/spine-libgdx/spine-libgdx-tests/src/com/esotericsoftware/spine/TimelineApiTest.java @@ -39,6 +39,7 @@ import com.badlogic.gdx.utils.ScreenUtils; import com.esotericsoftware.spine.Animation.MixBlend; import com.esotericsoftware.spine.Animation.MixDirection; +import com.esotericsoftware.spine.Skeleton.Physics; /** Demonstrates using the timeline API. See {@link SimpleTest1} for a higher level API using {@link AnimationState}. *

@@ -79,7 +80,7 @@ public class TimelineApiTest extends ApplicationAdapter { jumpAnimation = skeletonData.findAnimation("jump"); skeleton = new Skeleton(skeletonData); - skeleton.updateWorldTransform(); + skeleton.updateWorldTransform(Physics.update); skeleton.setPosition(-50, 20); } @@ -127,7 +128,7 @@ public class TimelineApiTest extends ApplicationAdapter { walkAnimation.apply(skeleton, time, time, true, events, 1, MixBlend.first, MixDirection.in); } - skeleton.updateWorldTransform(); + skeleton.updateWorldTransform(Physics.update); batch.begin(); renderer.draw(batch, skeleton); diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Bone.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Bone.java index 295b9c763..ab6820022 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Bone.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Bone.java @@ -38,6 +38,7 @@ import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Null; import com.esotericsoftware.spine.BoneData.TransformMode; +import com.esotericsoftware.spine.Skeleton.Physics; /** Stores a bone's current pose. *

@@ -82,7 +83,7 @@ public class Bone implements Updatable { } /** Computes the world transform using the parent bone and this bone's local applied transform. */ - public void update () { + public void update (Physics physics) { updateWorldTransform(ax, ay, arotation, ascaleX, ascaleY, ashearX, ashearY); } @@ -618,8 +619,8 @@ public class Bone implements Updatable { /** Rotates the world transform the specified amount. *

- * After changes are made to the world transform, {@link #updateAppliedTransform()} should be called and {@link #update()} will - * need to be called on any child bones, recursively. */ + * After changes are made to the world transform, {@link #updateAppliedTransform()} should be called and + * {@link #update(Physics)} will need to be called on any child bones, recursively. */ public void rotateWorld (float degrees) { degrees *= degRad; float sin = sin(degrees), cos = cos(degrees); diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/BoneData.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/BoneData.java index 0c4c42865..38f946f06 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/BoneData.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/BoneData.java @@ -32,6 +32,8 @@ package com.esotericsoftware.spine; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.utils.Null; +import com.esotericsoftware.spine.Skeleton.Physics; + /** Stores the setup pose for a {@link Bone}. */ public class BoneData { final int index; @@ -175,8 +177,8 @@ public class BoneData { this.transformMode = transformMode; } - /** When true, {@link Skeleton#updateWorldTransform()} only updates this bone if the {@link Skeleton#getSkin()} contains this - * bone. + /** When true, {@link Skeleton#updateWorldTransform(Physics)} only updates this bone if the {@link Skeleton#getSkin()} contains + * this bone. *

* See {@link Skin#getBones()}. */ public boolean getSkinRequired () { diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/ConstraintData.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/ConstraintData.java index b17535c62..d4d4144bc 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/ConstraintData.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/ConstraintData.java @@ -29,6 +29,8 @@ package com.esotericsoftware.spine; +import com.esotericsoftware.spine.Skeleton.Physics; + /** The base class for all constraint datas. */ abstract public class ConstraintData { final String name; @@ -46,7 +48,7 @@ abstract public class ConstraintData { } /** The ordinal of this constraint for the order a skeleton's constraints will be applied by - * {@link Skeleton#updateWorldTransform()}. */ + * {@link Skeleton#updateWorldTransform(Physics)}. */ public int getOrder () { return order; } @@ -55,8 +57,8 @@ abstract public class ConstraintData { this.order = order; } - /** When true, {@link Skeleton#updateWorldTransform()} only updates this constraint if the {@link Skeleton#getSkin()} contains - * this constraint. + /** When true, {@link Skeleton#updateWorldTransform(Physics)} only updates this constraint if the {@link Skeleton#getSkin()} + * contains this constraint. *

* See {@link Skin#getConstraints()}. */ public boolean getSkinRequired () { diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/IkConstraint.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/IkConstraint.java index e0448b999..ef8192f08 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/IkConstraint.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/IkConstraint.java @@ -33,6 +33,8 @@ import static com.esotericsoftware.spine.utils.SpineUtils.*; import com.badlogic.gdx.utils.Array; +import com.esotericsoftware.spine.Skeleton.Physics; + /** Stores the current pose for an IK constraint. An IK constraint adjusts the rotation of 1 or 2 constrained bones so the tip of * the last bone is as close to the target bone as possible. *

@@ -87,7 +89,7 @@ public class IkConstraint implements Updatable { } /** Applies the constraint to the constrained bones. */ - public void update () { + public void update (Physics physics) { if (mix == 0) return; Bone target = this.target; Object[] bones = this.bones.items; diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraint.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraint.java index 3c84809f6..f395d7e64 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraint.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraint.java @@ -39,6 +39,7 @@ import com.badlogic.gdx.utils.FloatArray; import com.esotericsoftware.spine.PathConstraintData.PositionMode; import com.esotericsoftware.spine.PathConstraintData.RotateMode; import com.esotericsoftware.spine.PathConstraintData.SpacingMode; +import com.esotericsoftware.spine.Skeleton.Physics; import com.esotericsoftware.spine.attachments.Attachment; import com.esotericsoftware.spine.attachments.PathAttachment; @@ -101,7 +102,7 @@ public class PathConstraint implements Updatable { } /** Applies the constraint to the constrained bones. */ - public void update () { + public void update (Physics physics) { Attachment attachment = target.attachment; if (!(attachment instanceof PathAttachment)) return; diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraint.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraint.java index 4316a497c..e69e6542d 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraint.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraint.java @@ -29,14 +29,23 @@ package com.esotericsoftware.spine; +import static com.badlogic.gdx.math.Interpolation.*; +import static com.esotericsoftware.spine.utils.SpineUtils.*; + +import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; +import com.esotericsoftware.spine.Skeleton.Physics; + +// BOZO - Physics steps/something in metrics view. + /** Stores the current pose for a physics constraint. A physics constraint applies physics to bones. *

* See Physics constraints in the Spine User Guide. */ public class PhysicsConstraint implements Updatable { final PhysicsConstraintData data; final Array bones; + State[] states = {}; float mix; boolean active; @@ -66,19 +75,158 @@ public class PhysicsConstraint implements Updatable { mix = constraint.mix; } - public void setToSetupPose () { + /** Caches information about bones. Must be called if {@link PathConstraintData#getBones()} is modified. */ + public void updateBones () { + int count = 0; + if (data.x) count = 1; + if (data.y) count++; + if (data.rotate) count++; + if (data.scaleX) count++; + if (data.shearX) count++; + count *= bones.size * 2; + if (states.length != count) { + states = new State[count]; + for (int i = 0; i < count; i++) + states[i] = new State(); + } + } + + public void reset () { remaining = 0; lastTime = skeleton.time; + for (int i = 0, n = states.length; i < n; i++) { + State state = states[i]; + state.last = false; + state.offset = 0; + state.velocity = 0; + } + } + + public void setToSetupPose () { + reset(); + PhysicsConstraintData data = this.data; mix = data.mix; } /** Applies the constraint to the constrained bones. */ - public void update () { + public void update (Physics physics) { if (mix == 0) return; - // BOZO + data.rotate = true; // BOZO - Remove. + updateBones(); // BOZO - Remove. + + Object[] bones = this.bones.items; + int boneCount = this.bones.size; + + switch (physics) { + case none: + return; + case reset: + reset(); + // Fall through. + case update: + for (int i = 0; i < boneCount; i++) { + Bone bone = (Bone)bones[i]; + if (data.rotate) { + Vector2 tip = bone.localToWorld(new Vector2(bone.data.length, 0)); + State state = states[i]; + if (!state.last) + state.last = true; + else if (state.x != bone.worldX || state.y != bone.worldY) { + float angleToOldTip = new Vector2(state.tipx, state.tipy).sub(bone.worldX, bone.worldY).angleDeg() + + state.offset - bone.getWorldRotationX(); + angleToOldTip -= (16384 - (int)(16384.499999999996 - angleToOldTip / 360)) * 360; + state.offset = linear.apply(0, angleToOldTip, data.inertia); +// if (angleToOldTip > 0.0001f || angleToOldTip < -0.0001f) // +// System.out.println(angleToOldTip); +// if (applyShear) { +// if (rotationOffset > 0) +// rotationOffset = Math.max(0, rotationOffset - shearOffset); +// else +// rotationOffset = Math.min(0, rotationOffset - shearOffset); +// } + } + tip = bone.localToWorld(new Vector2(bone.data.length, 0)); +// if (bone.worldX!=271.64316f) +// System.out.println(bone.worldX); + if (bone.worldY != 662.5888f) System.out.println(bone.worldY); +// System.out.println(bone.worldY); + state.x = bone.worldX; + state.y = bone.worldY; + state.tipx = tip.x; + state.tipy = tip.y; + } + // BOZO - Update physics x, y, scaleX, shearX. + } + } + + boolean angle = data.rotate || data.scaleX || data.shearX; + + remaining += Math.max(skeleton.time - lastTime, 0); + lastTime = skeleton.time; + + float step = 0.016f; // BOZO - Keep fixed step? Make it configurable? + float cos = 0, sin = 0; + while (remaining >= step) { + remaining -= step; + + for (int i = 0; i < boneCount; i++) { + Bone bone = (Bone)bones[i]; + if (angle) { + float r = bone.getWorldRotationX() * degRad; + cos = (float)Math.cos(r); + sin = (float)Math.sin(r); + } + if (data.rotate) { + State state = states[i]; + // BOZO - Keep length affecting rotation? Calculate world length? + float windForce = bone.data.length * 0.5f * (-data.wind * sin - data.gravity * cos); + float springForce = state.offset * data.strength; + float frictionForce = data.friction * state.velocity; + state.velocity += (windForce - springForce - frictionForce) / data.mass; + state.offset += state.velocity * step; + state.velocity *= data.damping; + } + } + } + + if (mix == 1) { + for (int i = 0; i < boneCount; i++) { + Bone bone = (Bone)bones[i]; + if (angle) { + float r = bone.getWorldRotationX() * degRad; + cos = (float)Math.cos(r); + sin = (float)Math.sin(r); + } + if (data.rotate) { + State state = states[i]; + bone.rotateWorld(state.offset); + bone.updateAppliedTransform(); + } + } + } else { + // BOZO - PhysicsConstraint mix. + } + } + + public void step () { + // BOZO - PhysicsConstraint#step. + } + + /** The bones that will be modified by this physics constraint. */ + public Array getBones () { + return bones; + } + + /** A percentage (0-1) that controls the mix between the constrained and unconstrained poses. */ + public float getMix () { + return mix; + } + + public void setMix (float mix) { + this.mix = mix; } public boolean isActive () { @@ -93,4 +241,9 @@ public class PhysicsConstraint implements Updatable { public String toString () { return data.name; } + + static class State { + boolean last; + float x, y, tipx, tipy, offset, velocity; + } } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraintData.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraintData.java index bfaae993f..53ac05c7e 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraintData.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PhysicsConstraintData.java @@ -36,9 +36,9 @@ import com.badlogic.gdx.utils.Array; * See Physics constraints in the Spine User Guide. */ public class PhysicsConstraintData extends ConstraintData { final Array bones = new Array(); - float speed = 1, mass = 1; + float speed = 1, mass = 1; // BOZO - Keep speed? float strength, friction, damping, inertia, wind, gravity, mix; - boolean translate, rotate, scale, shear; + boolean x, y, rotate, scaleX, shearX; public PhysicsConstraintData (String name) { super(name); @@ -113,12 +113,20 @@ public class PhysicsConstraintData extends ConstraintData { this.gravity = gravity; } - public boolean getTranslate () { - return translate; + public boolean getX () { + return x; } - public void setTranslate (boolean translate) { - this.translate = translate; + public void setX (boolean x) { + this.x = x; + } + + public boolean getY () { + return y; + } + + public void setY (boolean y) { + this.y = y; } public boolean getRotate () { @@ -129,20 +137,20 @@ public class PhysicsConstraintData extends ConstraintData { this.rotate = rotate; } - public boolean getScale () { - return scale; + public boolean getScaleX () { + return scaleX; } - public void setScale (boolean scale) { - this.scale = scale; + public void setScaleX (boolean scaleX) { + this.scaleX = scaleX; } - public boolean getShear () { - return shear; + public boolean getShearX () { + return shearX; } - public void setShear (boolean shear) { - this.shear = shear; + public void setShearX (boolean shearX) { + this.shearX = shearX; } /** A percentage (0-1) that controls the mix between the constrained and unconstrained poses. */ diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java index 9ae381d81..cf57df9fe 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java @@ -384,7 +384,7 @@ public class Skeleton { *

* See World transforms in the Spine * Runtimes Guide. */ - public void updateWorldTransform () { + public void updateWorldTransform (Physics physics) { Object[] bones = this.bones.items; for (int i = 0, n = this.bones.size; i < n; i++) { Bone bone = (Bone)bones[i]; @@ -399,7 +399,7 @@ public class Skeleton { Object[] updateCache = this.updateCache.items; for (int i = 0, n = this.updateCache.size; i < n; i++) - ((Updatable)updateCache[i]).update(); + ((Updatable)updateCache[i]).update(physics); } /** Temporarily sets the root bone as a child of the specified bone, then updates the world transform for each bone and applies @@ -407,7 +407,7 @@ public class Skeleton { *

* See World transforms in the Spine * Runtimes Guide. */ - public void updateWorldTransform (Bone parent) { + public void updateWorldTransform (Physics physics, Bone parent) { if (parent == null) throw new IllegalArgumentException("parent cannot be null."); Object[] bones = this.bones.items; @@ -443,7 +443,7 @@ public class Skeleton { Object[] updateCache = this.updateCache.items; for (int i = 0, n = this.updateCache.size; i < n; i++) { Updatable updatable = (Updatable)updateCache[i]; - if (updatable != rootBone) updatable.update(); + if (updatable != rootBone) updatable.update(physics); } } @@ -833,4 +833,19 @@ public class Skeleton { public String toString () { return data.name != null ? data.name : super.toString(); } + + /** Determines how physics and other non-deterministic updates are applied. */ + static public enum Physics { + /** Physics are not updated or applied. */ + none, + + /** Physics are not updated but the pose from physics is applied. */ + pose, + + /** Physics are updated and the pose from physics is applied. */ + update, + + /** Physics are reset to the current pose. */ + reset + } } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/TransformConstraint.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/TransformConstraint.java index 31fce064c..b7354a2d4 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/TransformConstraint.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/TransformConstraint.java @@ -34,6 +34,8 @@ import static com.esotericsoftware.spine.utils.SpineUtils.*; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; +import com.esotericsoftware.spine.Skeleton.Physics; + /** Stores the current pose for a transform constraint. A transform constraint adjusts the world transform of the constrained * bones to match that of the target bone. *

@@ -90,7 +92,7 @@ public class TransformConstraint implements Updatable { } /** Applies the constraint to the constrained bones. */ - public void update () { + public void update (Physics physics) { if (mixRotate == 0 && mixX == 0 && mixY == 0 && mixScaleX == 0 && mixScaleY == 0 && mixShearY == 0) return; if (data.local) { if (data.relative) diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Updatable.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Updatable.java index 6c75f4ac9..f68b23c10 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Updatable.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Updatable.java @@ -29,9 +29,12 @@ package com.esotericsoftware.spine; -/** The interface for items updated by {@link Skeleton#updateWorldTransform()}. */ +import com.esotericsoftware.spine.Skeleton.Physics; + +/** The interface for items updated by {@link Skeleton#updateWorldTransform(Physics)}. */ public interface Updatable { - public void update (); + /** @param physics Determines how physics and other non-deterministic updates are applied. */ + public void update (Physics physics); /** Returns false when this item has not been updated because a skin is required and the {@link Skeleton#getSkin() active skin} * does not contain this item. diff --git a/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java b/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java index 8ae287a16..2ed912edb 100644 --- a/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java +++ b/spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewer.java @@ -52,6 +52,7 @@ import com.badlogic.gdx.utils.viewport.ScreenViewport; import com.esotericsoftware.spine.Animation.MixBlend; import com.esotericsoftware.spine.AnimationState.AnimationStateAdapter; import com.esotericsoftware.spine.AnimationState.TrackEntry; +import com.esotericsoftware.spine.Skeleton.Physics; import com.esotericsoftware.spine.utils.TwoColorPolygonBatch; import java.awt.Toolkit; @@ -154,10 +155,7 @@ public class SkeletonViewer extends ApplicationAdapter { } skeleton = new Skeleton(skeletonData); - skeleton.updateWorldTransform(); - skeleton.setToSetupPose(); - skeleton = new Skeleton(skeleton); // Tests copy constructors. - skeleton.updateWorldTransform(); + skeleton.updateWorldTransform(Physics.update); state = new AnimationState(new AnimationStateData(skeletonData)); state.addListener(new AnimationStateAdapter() { @@ -269,7 +267,7 @@ public class SkeletonViewer extends ApplicationAdapter { delta = Math.min(delta, 0.032f) * ui.speedSlider.getValue(); state.update(delta); state.apply(skeleton); - skeleton.updateWorldTransform(); + skeleton.updateWorldTransform(Physics.update); batch.begin(); renderer.draw(batch, skeleton);