mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
[libgdx] Added a Physics enum to updateWorldTransform and Updateable#update to control how physics and other non-deterministic updates are applied.
This commit is contained in:
parent
9678808aaf
commit
4116af02fa
@ -34,6 +34,7 @@ import com.badlogic.gdx.utils.Null;
|
|||||||
|
|
||||||
import com.esotericsoftware.spine.Animation.MixBlend;
|
import com.esotericsoftware.spine.Animation.MixBlend;
|
||||||
import com.esotericsoftware.spine.Animation.MixDirection;
|
import com.esotericsoftware.spine.Animation.MixDirection;
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
import com.esotericsoftware.spine.attachments.AttachmentLoader;
|
import com.esotericsoftware.spine.attachments.AttachmentLoader;
|
||||||
import com.esotericsoftware.spine.attachments.BoundingBoxAttachment;
|
import com.esotericsoftware.spine.attachments.BoundingBoxAttachment;
|
||||||
import com.esotericsoftware.spine.attachments.ClippingAttachment;
|
import com.esotericsoftware.spine.attachments.ClippingAttachment;
|
||||||
@ -83,7 +84,7 @@ public class BonePlotting {
|
|||||||
float time = 0;
|
float time = 0;
|
||||||
while (time < animation.getDuration()) {
|
while (time < animation.getDuration()) {
|
||||||
animation.apply(skeleton, time, time, false, null, 1, MixBlend.first, MixDirection.in);
|
animation.apply(skeleton, time, time, false, null, 1, MixBlend.first, MixDirection.in);
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
|
|
||||||
System.out.println(animation.getName() + "," //
|
System.out.println(animation.getName() + "," //
|
||||||
+ bone.getWorldX() + "," + bone.getWorldY() + "," + bone.getWorldRotationX());
|
+ bone.getWorldX() + "," + bone.getWorldY() + "," + bone.getWorldRotationX());
|
||||||
|
|||||||
@ -54,6 +54,7 @@ import com.badlogic.gdx.utils.ScreenUtils;
|
|||||||
|
|
||||||
import com.esotericsoftware.spine.Animation.MixBlend;
|
import com.esotericsoftware.spine.Animation.MixBlend;
|
||||||
import com.esotericsoftware.spine.Animation.MixDirection;
|
import com.esotericsoftware.spine.Animation.MixDirection;
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
import com.esotericsoftware.spine.attachments.AtlasAttachmentLoader;
|
import com.esotericsoftware.spine.attachments.AtlasAttachmentLoader;
|
||||||
import com.esotericsoftware.spine.attachments.RegionAttachment;
|
import com.esotericsoftware.spine.attachments.RegionAttachment;
|
||||||
import com.esotericsoftware.spine.attachments.Sequence;
|
import com.esotericsoftware.spine.attachments.Sequence;
|
||||||
@ -104,7 +105,7 @@ public class Box2DExample extends ApplicationAdapter {
|
|||||||
skeleton = new Skeleton(skeletonData);
|
skeleton = new Skeleton(skeletonData);
|
||||||
skeleton.x = -32;
|
skeleton.x = -32;
|
||||||
skeleton.y = 1;
|
skeleton.y = 1;
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
|
|
||||||
// See Box2DTest in libgdx for more detailed information about Box2D setup.
|
// See Box2DTest in libgdx for more detailed information about Box2D setup.
|
||||||
camera = new OrthographicCamera(48, 32);
|
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);
|
animation.apply(skeleton, time, time, true, events, 1, MixBlend.first, MixDirection.in);
|
||||||
skeleton.x += 8 * delta;
|
skeleton.x += 8 * delta;
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
skeletonRenderer.draw(batch, skeleton);
|
skeletonRenderer.draw(batch, skeleton);
|
||||||
|
|
||||||
batch.end();
|
batch.end();
|
||||||
|
|||||||
@ -42,6 +42,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
|||||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
|
||||||
import com.badlogic.gdx.utils.ScreenUtils;
|
import com.badlogic.gdx.utils.ScreenUtils;
|
||||||
|
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
|
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
|
||||||
|
|
||||||
/** Demonstrates rendering an animation to a frame buffer (FBO) and then rendering the FBO to the screen. */
|
/** 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.
|
// Create a skeleton instance, set the position of its root bone, and update its world transform.
|
||||||
skeleton = new Skeleton(skeletonData);
|
skeleton = new Skeleton(skeletonData);
|
||||||
skeleton.setPosition(250, 20);
|
skeleton.setPosition(250, 20);
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
|
|
||||||
// Create an FBO and a texture region with Y flipped.
|
// Create an FBO and a texture region with Y flipped.
|
||||||
fbo = new FrameBuffer(Pixmap.Format.RGBA8888, 512, 512, false);
|
fbo = new FrameBuffer(Pixmap.Format.RGBA8888, 512, 512, false);
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import com.badlogic.gdx.math.Vector2;
|
|||||||
import com.badlogic.gdx.math.Vector3;
|
import com.badlogic.gdx.math.Vector3;
|
||||||
import com.badlogic.gdx.utils.ScreenUtils;
|
import com.badlogic.gdx.utils.ScreenUtils;
|
||||||
|
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
|
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
|
/** 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.
|
// later.
|
||||||
state.update(Gdx.graphics.getDeltaTime());
|
state.update(Gdx.graphics.getDeltaTime());
|
||||||
state.apply(skeleton);
|
state.apply(skeleton);
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
|
|
||||||
// Position the "crosshair" bone at the mouse
|
// Position the "crosshair" bone at the mouse
|
||||||
// location. We do this before calling
|
// location. We do this before calling
|
||||||
@ -122,7 +123,7 @@ public class IKTest extends ApplicationAdapter {
|
|||||||
// Calculate final world transform with the
|
// Calculate final world transform with the
|
||||||
// crosshair bone set to the mouse cursor
|
// crosshair bone set to the mouse cursor
|
||||||
// position.
|
// position.
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
|
|
||||||
// Clear the screen, update the camera and
|
// Clear the screen, update the camera and
|
||||||
// render the skeleton.
|
// render the skeleton.
|
||||||
|
|||||||
@ -37,6 +37,8 @@ import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch;
|
|||||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||||
import com.badlogic.gdx.utils.ScreenUtils;
|
import com.badlogic.gdx.utils.ScreenUtils;
|
||||||
|
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
|
|
||||||
/** Demonstrates creating and configuring a new skin at runtime. */
|
/** Demonstrates creating and configuring a new skin at runtime. */
|
||||||
public class MixAndMatchTest extends ApplicationAdapter {
|
public class MixAndMatchTest extends ApplicationAdapter {
|
||||||
OrthographicCamera camera;
|
OrthographicCamera camera;
|
||||||
@ -92,7 +94,7 @@ public class MixAndMatchTest extends ApplicationAdapter {
|
|||||||
ScreenUtils.clear(0, 0, 0, 0);
|
ScreenUtils.clear(0, 0, 0, 0);
|
||||||
|
|
||||||
state.apply(skeleton); // Poses skeleton using current animations. This sets the bones' local SRT.
|
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
|
// Configure the camera, and PolygonSpriteBatch
|
||||||
camera.update();
|
camera.update();
|
||||||
|
|||||||
@ -58,6 +58,7 @@ import com.badlogic.gdx.utils.ScreenUtils;
|
|||||||
|
|
||||||
import com.esotericsoftware.spine.Animation.MixBlend;
|
import com.esotericsoftware.spine.Animation.MixBlend;
|
||||||
import com.esotericsoftware.spine.Animation.MixDirection;
|
import com.esotericsoftware.spine.Animation.MixDirection;
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
|
|
||||||
/** Demonstrates simplistic usage of lighting with normal maps.
|
/** Demonstrates simplistic usage of lighting with normal maps.
|
||||||
* <p>
|
* <p>
|
||||||
@ -110,7 +111,7 @@ public class NormalMapTest extends ApplicationAdapter {
|
|||||||
skeleton = new Skeleton(skeleton);
|
skeleton = new Skeleton(skeleton);
|
||||||
skeleton.setX(ui.prefs.getFloat("x", Gdx.graphics.getWidth() / 2));
|
skeleton.setX(ui.prefs.getFloat("x", Gdx.graphics.getWidth() / 2));
|
||||||
skeleton.setY(ui.prefs.getFloat("y", Gdx.graphics.getHeight() / 4));
|
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() {
|
Gdx.input.setInputProcessor(new InputMultiplexer(ui.stage, new InputAdapter() {
|
||||||
public boolean touchDown (int screenX, int screenY, int pointer, int button) {
|
public boolean touchDown (int screenX, int screenY, int pointer, int button) {
|
||||||
@ -136,7 +137,7 @@ public class NormalMapTest extends ApplicationAdapter {
|
|||||||
float lastTime = time;
|
float lastTime = time;
|
||||||
time += Gdx.graphics.getDeltaTime();
|
time += Gdx.graphics.getDeltaTime();
|
||||||
if (animation != null) animation.apply(skeleton, lastTime, time, true, null, 1, MixBlend.first, MixDirection.in);
|
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.x = Gdx.input.getX();
|
||||||
lightPosition.y = (Gdx.graphics.getHeight() - 1 - Gdx.input.getY());
|
lightPosition.y = (Gdx.graphics.getHeight() - 1 - Gdx.input.getY());
|
||||||
|
|||||||
@ -48,6 +48,7 @@ import com.badlogic.gdx.utils.ScreenUtils;
|
|||||||
|
|
||||||
import com.esotericsoftware.spine.Animation.MixBlend;
|
import com.esotericsoftware.spine.Animation.MixBlend;
|
||||||
import com.esotericsoftware.spine.Animation.MixDirection;
|
import com.esotericsoftware.spine.Animation.MixDirection;
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
|
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
|
||||||
|
|
||||||
/** Demonstrates rendering an animation to a frame buffer (FBO) and then writing each frame as a PNG. */
|
/** 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.
|
// Create a skeleton instance, set the position of its root bone, and update its world transform.
|
||||||
skeleton = new Skeleton(skeletonData);
|
skeleton = new Skeleton(skeletonData);
|
||||||
skeleton.setPosition(250, 20);
|
skeleton.setPosition(250, 20);
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
|
|
||||||
// Create an FBO and a texture region.
|
// Create an FBO and a texture region.
|
||||||
fbo = new FrameBuffer(Pixmap.Format.RGBA8888, 512, 512, false);
|
fbo = new FrameBuffer(Pixmap.Format.RGBA8888, 512, 512, false);
|
||||||
@ -104,7 +105,7 @@ public class PngExportTest extends ApplicationAdapter {
|
|||||||
int frame = 1;
|
int frame = 1;
|
||||||
while (time < animation.getDuration()) {
|
while (time < animation.getDuration()) {
|
||||||
animation.apply(skeleton, time, time, false, null, 1, MixBlend.first, MixDirection.in);
|
animation.apply(skeleton, time, time, false, null, 1, MixBlend.first, MixDirection.in);
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
|
|
||||||
// Render the skeleton to the FBO.
|
// Render the skeleton to the FBO.
|
||||||
ScreenUtils.clear(0, 0, 0, 0);
|
ScreenUtils.clear(0, 0, 0, 0);
|
||||||
|
|||||||
@ -36,6 +36,7 @@ import com.badlogic.gdx.graphics.GL20;
|
|||||||
import com.badlogic.gdx.graphics.OrthographicCamera;
|
import com.badlogic.gdx.graphics.OrthographicCamera;
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||||
|
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
|
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
|
||||||
|
|
||||||
/** Demonstrates loading, animating, and rendering a skeleton.
|
/** Demonstrates loading, animating, and rendering a skeleton.
|
||||||
@ -86,7 +87,7 @@ public class SimpleTest1 extends ApplicationAdapter {
|
|||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
state.apply(skeleton); // Poses skeleton using current animations. This sets the bones' local SRT.
|
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.
|
// Configure the camera, SpriteBatch, and SkeletonRendererDebug.
|
||||||
camera.update();
|
camera.update();
|
||||||
|
|||||||
@ -41,6 +41,7 @@ import com.badlogic.gdx.math.Vector3;
|
|||||||
|
|
||||||
import com.esotericsoftware.spine.AnimationState.AnimationStateListener;
|
import com.esotericsoftware.spine.AnimationState.AnimationStateListener;
|
||||||
import com.esotericsoftware.spine.AnimationState.TrackEntry;
|
import com.esotericsoftware.spine.AnimationState.TrackEntry;
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
import com.esotericsoftware.spine.attachments.BoundingBoxAttachment;
|
import com.esotericsoftware.spine.attachments.BoundingBoxAttachment;
|
||||||
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
|
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
|
||||||
|
|
||||||
@ -147,7 +148,7 @@ public class SimpleTest2 extends ApplicationAdapter {
|
|||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
if (state.apply(skeleton)) // Poses skeleton using current animations. This sets the bones' local SRT.
|
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.
|
// Configure the camera, SpriteBatch, and SkeletonRendererDebug.
|
||||||
camera.update();
|
camera.update();
|
||||||
|
|||||||
@ -37,6 +37,8 @@ import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch;
|
|||||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||||
import com.badlogic.gdx.utils.ScreenUtils;
|
import com.badlogic.gdx.utils.ScreenUtils;
|
||||||
|
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
|
|
||||||
/** Demonstrates applying multiple animations at once using {@link AnimationState} tracks. */
|
/** Demonstrates applying multiple animations at once using {@link AnimationState} tracks. */
|
||||||
public class SimpleTest3 extends ApplicationAdapter {
|
public class SimpleTest3 extends ApplicationAdapter {
|
||||||
OrthographicCamera camera;
|
OrthographicCamera camera;
|
||||||
@ -84,7 +86,7 @@ public class SimpleTest3 extends ApplicationAdapter {
|
|||||||
ScreenUtils.clear(0, 0, 0, 0);
|
ScreenUtils.clear(0, 0, 0, 0);
|
||||||
|
|
||||||
if (state.apply(skeleton)) // Poses skeleton using current animations. This sets the bones' local SRT.
|
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.
|
// Configure the camera, SpriteBatch, and SkeletonRendererDebug.
|
||||||
camera.update();
|
camera.update();
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch;
|
|||||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||||
import com.badlogic.gdx.utils.ScreenUtils;
|
import com.badlogic.gdx.utils.ScreenUtils;
|
||||||
|
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
import com.esotericsoftware.spine.utils.SkeletonDataLoader;
|
import com.esotericsoftware.spine.utils.SkeletonDataLoader;
|
||||||
import com.esotericsoftware.spine.utils.SkeletonDataLoader.SkeletonDataParameter;
|
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.update(Gdx.graphics.getDeltaTime()); // Update the animation time.
|
||||||
|
|
||||||
state.apply(skeleton); // Poses skeleton using current animations. This sets the bones' local SRT.
|
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.
|
// Configure the camera, SpriteBatch, and SkeletonRendererDebug.
|
||||||
camera.update();
|
camera.update();
|
||||||
|
|||||||
@ -37,6 +37,7 @@ import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch;
|
|||||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||||
import com.badlogic.gdx.utils.ScreenUtils;
|
import com.badlogic.gdx.utils.ScreenUtils;
|
||||||
|
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
import com.esotericsoftware.spine.attachments.SkeletonAttachment;
|
import com.esotericsoftware.spine.attachments.SkeletonAttachment;
|
||||||
|
|
||||||
/** Demonstrates using {@link SkeletonAttachment} to use an entire skeleton as an attachment. */
|
/** Demonstrates using {@link SkeletonAttachment} to use an entire skeleton as an attachment. */
|
||||||
@ -93,11 +94,11 @@ public class SkeletonAttachmentTest extends ApplicationAdapter {
|
|||||||
public void render () {
|
public void render () {
|
||||||
spineboyState.update(Gdx.graphics.getDeltaTime());
|
spineboyState.update(Gdx.graphics.getDeltaTime());
|
||||||
spineboyState.apply(spineboy);
|
spineboyState.apply(spineboy);
|
||||||
spineboy.updateWorldTransform();
|
spineboy.updateWorldTransform(Physics.update);
|
||||||
|
|
||||||
goblinState.update(Gdx.graphics.getDeltaTime());
|
goblinState.update(Gdx.graphics.getDeltaTime());
|
||||||
goblinState.apply(goblin);
|
goblinState.apply(goblin);
|
||||||
goblin.updateWorldTransform(attachmentBone);
|
goblin.updateWorldTransform(Physics.update, attachmentBone);
|
||||||
|
|
||||||
ScreenUtils.clear(0, 0, 0, 0);
|
ScreenUtils.clear(0, 0, 0, 0);
|
||||||
|
|
||||||
|
|||||||
@ -39,6 +39,8 @@ import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
|||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||||
import com.badlogic.gdx.utils.ScreenUtils;
|
import com.badlogic.gdx.utils.ScreenUtils;
|
||||||
|
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
|
|
||||||
/** Boilerplate for basic skeleton rendering, used for various testing. */
|
/** Boilerplate for basic skeleton rendering, used for various testing. */
|
||||||
public class TestHarness extends ApplicationAdapter {
|
public class TestHarness extends ApplicationAdapter {
|
||||||
// static String JSON = "coin/coin-pro.json";
|
// static String JSON = "coin/coin-pro.json";
|
||||||
@ -79,7 +81,7 @@ public class TestHarness extends ApplicationAdapter {
|
|||||||
// state.setAnimation(0, "rotate", false);
|
// state.setAnimation(0, "rotate", false);
|
||||||
state.update(0);
|
state.update(0);
|
||||||
state.apply(skeleton);
|
state.apply(skeleton);
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render () {
|
public void render () {
|
||||||
@ -87,7 +89,7 @@ public class TestHarness extends ApplicationAdapter {
|
|||||||
state.update(0.25f); // Update the animation time.
|
state.update(0.25f); // Update the animation time.
|
||||||
}
|
}
|
||||||
state.apply(skeleton); // Poses skeleton using current animations. This sets the bones' local SRT.
|
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);
|
ScreenUtils.clear(0, 0, 0, 0);
|
||||||
|
|
||||||
|
|||||||
@ -39,6 +39,7 @@ import com.badlogic.gdx.utils.ScreenUtils;
|
|||||||
|
|
||||||
import com.esotericsoftware.spine.Animation.MixBlend;
|
import com.esotericsoftware.spine.Animation.MixBlend;
|
||||||
import com.esotericsoftware.spine.Animation.MixDirection;
|
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}.
|
/** Demonstrates using the timeline API. See {@link SimpleTest1} for a higher level API using {@link AnimationState}.
|
||||||
* <p>
|
* <p>
|
||||||
@ -79,7 +80,7 @@ public class TimelineApiTest extends ApplicationAdapter {
|
|||||||
jumpAnimation = skeletonData.findAnimation("jump");
|
jumpAnimation = skeletonData.findAnimation("jump");
|
||||||
|
|
||||||
skeleton = new Skeleton(skeletonData);
|
skeleton = new Skeleton(skeletonData);
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
skeleton.setPosition(-50, 20);
|
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);
|
walkAnimation.apply(skeleton, time, time, true, events, 1, MixBlend.first, MixDirection.in);
|
||||||
}
|
}
|
||||||
|
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
|
|
||||||
batch.begin();
|
batch.begin();
|
||||||
renderer.draw(batch, skeleton);
|
renderer.draw(batch, skeleton);
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import com.badlogic.gdx.utils.Array;
|
|||||||
import com.badlogic.gdx.utils.Null;
|
import com.badlogic.gdx.utils.Null;
|
||||||
|
|
||||||
import com.esotericsoftware.spine.BoneData.TransformMode;
|
import com.esotericsoftware.spine.BoneData.TransformMode;
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
|
|
||||||
/** Stores a bone's current pose.
|
/** Stores a bone's current pose.
|
||||||
* <p>
|
* <p>
|
||||||
@ -82,7 +83,7 @@ public class Bone implements Updatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Computes the world transform using the parent bone and this bone's local applied transform. */
|
/** 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);
|
updateWorldTransform(ax, ay, arotation, ascaleX, ascaleY, ashearX, ashearY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,8 +619,8 @@ public class Bone implements Updatable {
|
|||||||
|
|
||||||
/** Rotates the world transform the specified amount.
|
/** Rotates the world transform the specified amount.
|
||||||
* <p>
|
* <p>
|
||||||
* After changes are made to the world transform, {@link #updateAppliedTransform()} should be called and {@link #update()} will
|
* After changes are made to the world transform, {@link #updateAppliedTransform()} should be called and
|
||||||
* need to be called on any child bones, recursively. */
|
* {@link #update(Physics)} will need to be called on any child bones, recursively. */
|
||||||
public void rotateWorld (float degrees) {
|
public void rotateWorld (float degrees) {
|
||||||
degrees *= degRad;
|
degrees *= degRad;
|
||||||
float sin = sin(degrees), cos = cos(degrees);
|
float sin = sin(degrees), cos = cos(degrees);
|
||||||
|
|||||||
@ -32,6 +32,8 @@ package com.esotericsoftware.spine;
|
|||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
import com.badlogic.gdx.utils.Null;
|
import com.badlogic.gdx.utils.Null;
|
||||||
|
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
|
|
||||||
/** Stores the setup pose for a {@link Bone}. */
|
/** Stores the setup pose for a {@link Bone}. */
|
||||||
public class BoneData {
|
public class BoneData {
|
||||||
final int index;
|
final int index;
|
||||||
@ -175,8 +177,8 @@ public class BoneData {
|
|||||||
this.transformMode = transformMode;
|
this.transformMode = transformMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** When true, {@link Skeleton#updateWorldTransform()} only updates this bone if the {@link Skeleton#getSkin()} contains this
|
/** When true, {@link Skeleton#updateWorldTransform(Physics)} only updates this bone if the {@link Skeleton#getSkin()} contains
|
||||||
* bone.
|
* this bone.
|
||||||
* <p>
|
* <p>
|
||||||
* See {@link Skin#getBones()}. */
|
* See {@link Skin#getBones()}. */
|
||||||
public boolean getSkinRequired () {
|
public boolean getSkinRequired () {
|
||||||
|
|||||||
@ -29,6 +29,8 @@
|
|||||||
|
|
||||||
package com.esotericsoftware.spine;
|
package com.esotericsoftware.spine;
|
||||||
|
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
|
|
||||||
/** The base class for all constraint datas. */
|
/** The base class for all constraint datas. */
|
||||||
abstract public class ConstraintData {
|
abstract public class ConstraintData {
|
||||||
final String name;
|
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
|
/** 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 () {
|
public int getOrder () {
|
||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
@ -55,8 +57,8 @@ abstract public class ConstraintData {
|
|||||||
this.order = order;
|
this.order = order;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** When true, {@link Skeleton#updateWorldTransform()} only updates this constraint if the {@link Skeleton#getSkin()} contains
|
/** When true, {@link Skeleton#updateWorldTransform(Physics)} only updates this constraint if the {@link Skeleton#getSkin()}
|
||||||
* this constraint.
|
* contains this constraint.
|
||||||
* <p>
|
* <p>
|
||||||
* See {@link Skin#getConstraints()}. */
|
* See {@link Skin#getConstraints()}. */
|
||||||
public boolean getSkinRequired () {
|
public boolean getSkinRequired () {
|
||||||
|
|||||||
@ -33,6 +33,8 @@ import static com.esotericsoftware.spine.utils.SpineUtils.*;
|
|||||||
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
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
|
/** 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.
|
* the last bone is as close to the target bone as possible.
|
||||||
* <p>
|
* <p>
|
||||||
@ -87,7 +89,7 @@ public class IkConstraint implements Updatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Applies the constraint to the constrained bones. */
|
/** Applies the constraint to the constrained bones. */
|
||||||
public void update () {
|
public void update (Physics physics) {
|
||||||
if (mix == 0) return;
|
if (mix == 0) return;
|
||||||
Bone target = this.target;
|
Bone target = this.target;
|
||||||
Object[] bones = this.bones.items;
|
Object[] bones = this.bones.items;
|
||||||
|
|||||||
@ -39,6 +39,7 @@ import com.badlogic.gdx.utils.FloatArray;
|
|||||||
import com.esotericsoftware.spine.PathConstraintData.PositionMode;
|
import com.esotericsoftware.spine.PathConstraintData.PositionMode;
|
||||||
import com.esotericsoftware.spine.PathConstraintData.RotateMode;
|
import com.esotericsoftware.spine.PathConstraintData.RotateMode;
|
||||||
import com.esotericsoftware.spine.PathConstraintData.SpacingMode;
|
import com.esotericsoftware.spine.PathConstraintData.SpacingMode;
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
import com.esotericsoftware.spine.attachments.Attachment;
|
import com.esotericsoftware.spine.attachments.Attachment;
|
||||||
import com.esotericsoftware.spine.attachments.PathAttachment;
|
import com.esotericsoftware.spine.attachments.PathAttachment;
|
||||||
|
|
||||||
@ -101,7 +102,7 @@ public class PathConstraint implements Updatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Applies the constraint to the constrained bones. */
|
/** Applies the constraint to the constrained bones. */
|
||||||
public void update () {
|
public void update (Physics physics) {
|
||||||
Attachment attachment = target.attachment;
|
Attachment attachment = target.attachment;
|
||||||
if (!(attachment instanceof PathAttachment)) return;
|
if (!(attachment instanceof PathAttachment)) return;
|
||||||
|
|
||||||
|
|||||||
@ -29,14 +29,23 @@
|
|||||||
|
|
||||||
package com.esotericsoftware.spine;
|
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.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.
|
/** Stores the current pose for a physics constraint. A physics constraint applies physics to bones.
|
||||||
* <p>
|
* <p>
|
||||||
* See <a href="http://esotericsoftware.com/spine-physics-constraints">Physics constraints</a> in the Spine User Guide. */
|
* See <a href="http://esotericsoftware.com/spine-physics-constraints">Physics constraints</a> in the Spine User Guide. */
|
||||||
public class PhysicsConstraint implements Updatable {
|
public class PhysicsConstraint implements Updatable {
|
||||||
final PhysicsConstraintData data;
|
final PhysicsConstraintData data;
|
||||||
final Array<Bone> bones;
|
final Array<Bone> bones;
|
||||||
|
State[] states = {};
|
||||||
float mix;
|
float mix;
|
||||||
|
|
||||||
boolean active;
|
boolean active;
|
||||||
@ -66,19 +75,158 @@ public class PhysicsConstraint implements Updatable {
|
|||||||
mix = constraint.mix;
|
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;
|
remaining = 0;
|
||||||
lastTime = skeleton.time;
|
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;
|
PhysicsConstraintData data = this.data;
|
||||||
mix = data.mix;
|
mix = data.mix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Applies the constraint to the constrained bones. */
|
/** Applies the constraint to the constrained bones. */
|
||||||
public void update () {
|
public void update (Physics physics) {
|
||||||
if (mix == 0) return;
|
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<Bone> 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 () {
|
public boolean isActive () {
|
||||||
@ -93,4 +241,9 @@ public class PhysicsConstraint implements Updatable {
|
|||||||
public String toString () {
|
public String toString () {
|
||||||
return data.name;
|
return data.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class State {
|
||||||
|
boolean last;
|
||||||
|
float x, y, tipx, tipy, offset, velocity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,9 +36,9 @@ import com.badlogic.gdx.utils.Array;
|
|||||||
* See <a href="http://esotericsoftware.com/spine-physics-constraints">Physics constraints</a> in the Spine User Guide. */
|
* See <a href="http://esotericsoftware.com/spine-physics-constraints">Physics constraints</a> in the Spine User Guide. */
|
||||||
public class PhysicsConstraintData extends ConstraintData {
|
public class PhysicsConstraintData extends ConstraintData {
|
||||||
final Array<BoneData> bones = new Array();
|
final Array<BoneData> bones = new Array();
|
||||||
float speed = 1, mass = 1;
|
float speed = 1, mass = 1; // BOZO - Keep speed?
|
||||||
float strength, friction, damping, inertia, wind, gravity, mix;
|
float strength, friction, damping, inertia, wind, gravity, mix;
|
||||||
boolean translate, rotate, scale, shear;
|
boolean x, y, rotate, scaleX, shearX;
|
||||||
|
|
||||||
public PhysicsConstraintData (String name) {
|
public PhysicsConstraintData (String name) {
|
||||||
super(name);
|
super(name);
|
||||||
@ -113,12 +113,20 @@ public class PhysicsConstraintData extends ConstraintData {
|
|||||||
this.gravity = gravity;
|
this.gravity = gravity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getTranslate () {
|
public boolean getX () {
|
||||||
return translate;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTranslate (boolean translate) {
|
public void setX (boolean x) {
|
||||||
this.translate = translate;
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getY () {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setY (boolean y) {
|
||||||
|
this.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getRotate () {
|
public boolean getRotate () {
|
||||||
@ -129,20 +137,20 @@ public class PhysicsConstraintData extends ConstraintData {
|
|||||||
this.rotate = rotate;
|
this.rotate = rotate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getScale () {
|
public boolean getScaleX () {
|
||||||
return scale;
|
return scaleX;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setScale (boolean scale) {
|
public void setScaleX (boolean scaleX) {
|
||||||
this.scale = scale;
|
this.scaleX = scaleX;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getShear () {
|
public boolean getShearX () {
|
||||||
return shear;
|
return shearX;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setShear (boolean shear) {
|
public void setShearX (boolean shearX) {
|
||||||
this.shear = shear;
|
this.shearX = shearX;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained poses. */
|
/** A percentage (0-1) that controls the mix between the constrained and unconstrained poses. */
|
||||||
|
|||||||
@ -384,7 +384,7 @@ public class Skeleton {
|
|||||||
* <p>
|
* <p>
|
||||||
* See <a href="http://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
|
* See <a href="http://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
|
||||||
* Runtimes Guide. */
|
* Runtimes Guide. */
|
||||||
public void updateWorldTransform () {
|
public void updateWorldTransform (Physics physics) {
|
||||||
Object[] bones = this.bones.items;
|
Object[] bones = this.bones.items;
|
||||||
for (int i = 0, n = this.bones.size; i < n; i++) {
|
for (int i = 0, n = this.bones.size; i < n; i++) {
|
||||||
Bone bone = (Bone)bones[i];
|
Bone bone = (Bone)bones[i];
|
||||||
@ -399,7 +399,7 @@ public class Skeleton {
|
|||||||
|
|
||||||
Object[] updateCache = this.updateCache.items;
|
Object[] updateCache = this.updateCache.items;
|
||||||
for (int i = 0, n = this.updateCache.size; i < n; i++)
|
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
|
/** 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 {
|
|||||||
* <p>
|
* <p>
|
||||||
* See <a href="http://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
|
* See <a href="http://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
|
||||||
* Runtimes Guide. */
|
* Runtimes Guide. */
|
||||||
public void updateWorldTransform (Bone parent) {
|
public void updateWorldTransform (Physics physics, Bone parent) {
|
||||||
if (parent == null) throw new IllegalArgumentException("parent cannot be null.");
|
if (parent == null) throw new IllegalArgumentException("parent cannot be null.");
|
||||||
|
|
||||||
Object[] bones = this.bones.items;
|
Object[] bones = this.bones.items;
|
||||||
@ -443,7 +443,7 @@ public class Skeleton {
|
|||||||
Object[] updateCache = this.updateCache.items;
|
Object[] updateCache = this.updateCache.items;
|
||||||
for (int i = 0, n = this.updateCache.size; i < n; i++) {
|
for (int i = 0, n = this.updateCache.size; i < n; i++) {
|
||||||
Updatable updatable = (Updatable)updateCache[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 () {
|
public String toString () {
|
||||||
return data.name != null ? data.name : super.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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,8 @@ import static com.esotericsoftware.spine.utils.SpineUtils.*;
|
|||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.utils.Array;
|
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
|
/** 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.
|
* bones to match that of the target bone.
|
||||||
* <p>
|
* <p>
|
||||||
@ -90,7 +92,7 @@ public class TransformConstraint implements Updatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Applies the constraint to the constrained bones. */
|
/** 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 (mixRotate == 0 && mixX == 0 && mixY == 0 && mixScaleX == 0 && mixScaleY == 0 && mixShearY == 0) return;
|
||||||
if (data.local) {
|
if (data.local) {
|
||||||
if (data.relative)
|
if (data.relative)
|
||||||
|
|||||||
@ -29,9 +29,12 @@
|
|||||||
|
|
||||||
package com.esotericsoftware.spine;
|
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 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}
|
/** 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.
|
* does not contain this item.
|
||||||
|
|||||||
@ -52,6 +52,7 @@ import com.badlogic.gdx.utils.viewport.ScreenViewport;
|
|||||||
import com.esotericsoftware.spine.Animation.MixBlend;
|
import com.esotericsoftware.spine.Animation.MixBlend;
|
||||||
import com.esotericsoftware.spine.AnimationState.AnimationStateAdapter;
|
import com.esotericsoftware.spine.AnimationState.AnimationStateAdapter;
|
||||||
import com.esotericsoftware.spine.AnimationState.TrackEntry;
|
import com.esotericsoftware.spine.AnimationState.TrackEntry;
|
||||||
|
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||||
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
|
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
|
||||||
|
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
@ -154,10 +155,7 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
skeleton = new Skeleton(skeletonData);
|
skeleton = new Skeleton(skeletonData);
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
skeleton.setToSetupPose();
|
|
||||||
skeleton = new Skeleton(skeleton); // Tests copy constructors.
|
|
||||||
skeleton.updateWorldTransform();
|
|
||||||
|
|
||||||
state = new AnimationState(new AnimationStateData(skeletonData));
|
state = new AnimationState(new AnimationStateData(skeletonData));
|
||||||
state.addListener(new AnimationStateAdapter() {
|
state.addListener(new AnimationStateAdapter() {
|
||||||
@ -269,7 +267,7 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
delta = Math.min(delta, 0.032f) * ui.speedSlider.getValue();
|
delta = Math.min(delta, 0.032f) * ui.speedSlider.getValue();
|
||||||
state.update(delta);
|
state.update(delta);
|
||||||
state.apply(skeleton);
|
state.apply(skeleton);
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
|
|
||||||
batch.begin();
|
batch.begin();
|
||||||
renderer.draw(batch, skeleton);
|
renderer.draw(batch, skeleton);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user