mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 22:34:53 +08:00
[libgdx] SlotPose and other refactoring.
This commit is contained in:
parent
cab6f73396
commit
cab5944663
@ -37,7 +37,6 @@ import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||
import com.badlogic.gdx.utils.viewport.ScreenViewport;
|
||||
|
||||
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||
import com.esotericsoftware.spine.utils.SkeletonActor;
|
||||
import com.esotericsoftware.spine.utils.TwoColorPolygonBatch;
|
||||
|
||||
|
||||
@ -92,8 +92,8 @@ public class AttachmentTimelineTests {
|
||||
private void test (float delta, Attachment attachment) {
|
||||
state.update(delta);
|
||||
state.apply(skeleton);
|
||||
if (slot.getAttachment() != attachment)
|
||||
throw new FailException("Wrong attachment: " + slot.getAttachment() + " != " + attachment);
|
||||
if (slot.getPose().getAttachment() != attachment)
|
||||
throw new FailException("Wrong attachment: " + slot.getPose().getAttachment() + " != " + attachment);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -34,7 +34,6 @@ 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;
|
||||
@ -76,7 +75,7 @@ public class BonePlotting {
|
||||
|
||||
SkeletonData skeletonData = json.readSkeletonData(new FileHandle("assets/spineboy/spineboy-ess.json"));
|
||||
Skeleton skeleton = new Skeleton(skeletonData);
|
||||
BoneApplied bone = skeleton.findBone("gun-tip").getApplied();
|
||||
BoneApplied bone = skeleton.findBone("gun-tip").getAppliedPose();
|
||||
|
||||
// Pose the skeleton at regular intervals throughout each animation.
|
||||
float fps = 1 / 15f;
|
||||
|
||||
@ -54,7 +54,6 @@ 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;
|
||||
@ -116,8 +115,8 @@ public class Box2DExample extends ApplicationAdapter {
|
||||
// Create a body for each attachment. Note it is probably better to create just a few bodies rather than one for each
|
||||
// region attachment, but this is just an example.
|
||||
for (Slot slot : skeleton.getSlots()) {
|
||||
if (!(slot.getAttachment() instanceof Box2dAttachment)) continue;
|
||||
Box2dAttachment attachment = (Box2dAttachment)slot.getAttachment();
|
||||
if (!(slot.getPose().getAttachment() instanceof Box2dAttachment)) continue;
|
||||
Box2dAttachment attachment = (Box2dAttachment)slot.getPose().getAttachment();
|
||||
|
||||
PolygonShape boxPoly = new PolygonShape();
|
||||
boxPoly.setAsBox(attachment.getWidth() / 2 * attachment.getScaleX(), attachment.getHeight() / 2 * attachment.getScaleY(),
|
||||
@ -159,10 +158,10 @@ public class Box2DExample extends ApplicationAdapter {
|
||||
|
||||
// Position the physics body for each attachment.
|
||||
for (Slot slot : skeleton.getSlots()) {
|
||||
if (!(slot.getAttachment() instanceof Box2dAttachment)) continue;
|
||||
Box2dAttachment attachment = (Box2dAttachment)slot.getAttachment();
|
||||
if (!(slot.getAppliedPose().getAttachment() instanceof Box2dAttachment)) continue;
|
||||
Box2dAttachment attachment = (Box2dAttachment)slot.getAppliedPose().getAttachment();
|
||||
if (attachment.body == null) continue;
|
||||
BoneApplied bone = slot.getBone().getApplied();
|
||||
BoneApplied bone = slot.getBone().getAppliedPose();
|
||||
float x = bone.getWorldX();
|
||||
float y = bone.getWorldY();
|
||||
float rotation = bone.getWorldRotationX();
|
||||
|
||||
@ -42,7 +42,6 @@ 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. */
|
||||
|
||||
@ -38,7 +38,6 @@ 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
|
||||
@ -107,8 +106,8 @@ public class IKTest extends ApplicationAdapter {
|
||||
|
||||
Bone crosshair = skeleton.findBone("crosshair"); // Should be cached.
|
||||
boneCoords.set(cameraCoords.x, cameraCoords.y);
|
||||
crosshair.getParent().getApplied().worldToLocal(boneCoords); // camera space to local bone space
|
||||
crosshair.setPosition(boneCoords.x, boneCoords.y); // override the crosshair position
|
||||
crosshair.getParent().getAppliedPose().worldToLocal(boneCoords); // camera space to local bone space
|
||||
crosshair.getPose().setPosition(boneCoords.x, boneCoords.y); // override the crosshair position
|
||||
|
||||
// Calculate final world transform with the crosshair bone set to the mouse cursor position. Update physics this time.
|
||||
skeleton.updateWorldTransform(Physics.update);
|
||||
|
||||
@ -37,8 +37,6 @@ 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;
|
||||
|
||||
@ -58,7 +58,6 @@ 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.
|
||||
* <p>
|
||||
@ -107,7 +106,7 @@ public class NormalMapTest extends ApplicationAdapter {
|
||||
if (animation == null) animation = skeletonData.getAnimations().first();
|
||||
|
||||
skeleton = new Skeleton(skeletonData);
|
||||
skeleton.setToSetupPose();
|
||||
skeleton.setupPose();
|
||||
skeleton = new Skeleton(skeleton);
|
||||
skeleton.setX(ui.prefs.getFloat("x", Gdx.graphics.getWidth() / 2));
|
||||
skeleton.setY(ui.prefs.getFloat("y", Gdx.graphics.getHeight() / 4));
|
||||
|
||||
@ -35,7 +35,7 @@ import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
|
||||
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.
|
||||
|
||||
@ -37,7 +37,6 @@ 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.
|
||||
|
||||
@ -35,7 +35,7 @@ import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
|
||||
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.
|
||||
|
||||
@ -35,7 +35,7 @@ import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
|
||||
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.
|
||||
|
||||
@ -48,7 +48,6 @@ 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. */
|
||||
|
||||
@ -36,7 +36,6 @@ 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.
|
||||
|
||||
@ -41,7 +41,6 @@ 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;
|
||||
|
||||
@ -123,14 +122,14 @@ public class SimpleTest2 extends ApplicationAdapter {
|
||||
BoundingBoxAttachment hit = bounds.containsPoint(point.x, point.y); // Check if inside a bounding box.
|
||||
if (hit != null) {
|
||||
System.out.println("hit: " + hit);
|
||||
skeleton.findSlot("head").getColor().set(Color.RED); // Turn head red until touchUp.
|
||||
skeleton.findSlot("head").getPose().getColor().set(Color.RED); // Turn head red until touchUp.
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean touchUp (int screenX, int screenY, int pointer, int button) {
|
||||
skeleton.findSlot("head").getColor().set(Color.WHITE);
|
||||
skeleton.findSlot("head").getPose().getColor().set(Color.WHITE);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -37,8 +37,6 @@ 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;
|
||||
|
||||
@ -38,7 +38,6 @@ 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;
|
||||
|
||||
|
||||
@ -37,7 +37,6 @@ 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. */
|
||||
@ -77,7 +76,7 @@ public class SkeletonAttachmentTest extends ApplicationAdapter {
|
||||
SkeletonData skeletonData = json.readSkeletonData(Gdx.files.internal("goblins/goblins-pro.json"));
|
||||
goblin = new Skeleton(skeletonData);
|
||||
goblin.setSkin("goblin");
|
||||
goblin.setSlotsToSetupPose();
|
||||
goblin.setupPoseSlots();
|
||||
|
||||
goblinState = new AnimationState(new AnimationStateData(skeletonData));
|
||||
goblinState.setAnimation(0, "walk", true);
|
||||
@ -86,8 +85,8 @@ public class SkeletonAttachmentTest extends ApplicationAdapter {
|
||||
SkeletonAttachment skeletonAttachment = new SkeletonAttachment("goblin");
|
||||
skeletonAttachment.setSkeleton(goblin);
|
||||
Slot slot = spineboy.findSlot("front-upper-arm");
|
||||
slot.setAttachment(skeletonAttachment);
|
||||
attachmentBone = slot.getBone().getApplied();
|
||||
slot.getPose().setAttachment(skeletonAttachment);
|
||||
attachmentBone = slot.getBone().getAppliedPose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -39,8 +39,6 @@ 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 = "raptor/raptor-pro.json";
|
||||
|
||||
@ -39,7 +39,6 @@ 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}.
|
||||
* <p>
|
||||
|
||||
@ -560,10 +560,10 @@ public class Animation {
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction, boolean appliedPose) {
|
||||
|
||||
Bone pose = skeleton.bones.get(boneIndex);
|
||||
if (pose.active) {
|
||||
BonePose bone = appliedPose ? pose.applied : pose;
|
||||
bone.rotation = getRelativeValue(time, alpha, blend, bone.rotation, pose.data.rotation);
|
||||
Bone bone = skeleton.bones.get(boneIndex);
|
||||
if (bone.active) {
|
||||
BonePose pose = appliedPose ? bone.applied : bone.pose;
|
||||
pose.rotation = getRelativeValue(time, alpha, blend, pose.rotation, bone.data.rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -586,20 +586,20 @@ public class Animation {
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction, boolean appliedPose) {
|
||||
|
||||
Bone pose = skeleton.bones.get(boneIndex);
|
||||
if (!pose.active) return;
|
||||
BonePose bone = appliedPose ? pose.applied : pose;
|
||||
Bone bone = skeleton.bones.get(boneIndex);
|
||||
if (!bone.active) return;
|
||||
BonePose pose = appliedPose ? bone.applied : bone.pose;
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) {
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bone.x = pose.data.x;
|
||||
bone.y = pose.data.y;
|
||||
pose.x = bone.data.x;
|
||||
pose.y = bone.data.y;
|
||||
return;
|
||||
case first:
|
||||
bone.x += (pose.data.x - bone.x) * alpha;
|
||||
bone.y += (pose.data.y - bone.y) * alpha;
|
||||
pose.x += (bone.data.x - pose.x) * alpha;
|
||||
pose.y += (bone.data.y - pose.y) * alpha;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -626,17 +626,17 @@ public class Animation {
|
||||
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bone.x = pose.data.x + x * alpha;
|
||||
bone.y = pose.data.y + y * alpha;
|
||||
pose.x = bone.data.x + x * alpha;
|
||||
pose.y = bone.data.y + y * alpha;
|
||||
break;
|
||||
case first:
|
||||
case replace:
|
||||
bone.x += (pose.data.x + x - bone.x) * alpha;
|
||||
bone.y += (pose.data.y + y - bone.y) * alpha;
|
||||
pose.x += (bone.data.x + x - pose.x) * alpha;
|
||||
pose.y += (bone.data.y + y - pose.y) * alpha;
|
||||
break;
|
||||
case add:
|
||||
bone.x += x * alpha;
|
||||
bone.y += y * alpha;
|
||||
pose.x += x * alpha;
|
||||
pose.y += y * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -657,10 +657,10 @@ public class Animation {
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction, boolean appliedPose) {
|
||||
|
||||
Bone pose = skeleton.bones.get(boneIndex);
|
||||
if (pose.active) {
|
||||
BonePose bone = appliedPose ? pose.applied : pose;
|
||||
bone.x = getRelativeValue(time, alpha, blend, bone.x, pose.data.x);
|
||||
Bone bone = skeleton.bones.get(boneIndex);
|
||||
if (bone.active) {
|
||||
BonePose pose = appliedPose ? bone.applied : bone.pose;
|
||||
pose.x = getRelativeValue(time, alpha, blend, pose.x, bone.data.x);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -681,10 +681,10 @@ public class Animation {
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction, boolean appliedPose) {
|
||||
|
||||
Bone pose = skeleton.bones.get(boneIndex);
|
||||
if (pose.active) {
|
||||
BonePose bone = appliedPose ? pose.applied : pose;
|
||||
bone.y = getRelativeValue(time, alpha, blend, bone.y, pose.data.y);
|
||||
Bone bone = skeleton.bones.get(boneIndex);
|
||||
if (bone.active) {
|
||||
BonePose pose = appliedPose ? bone.applied : bone.pose;
|
||||
pose.y = getRelativeValue(time, alpha, blend, pose.y, bone.data.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -707,20 +707,20 @@ public class Animation {
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction, boolean appliedPose) {
|
||||
|
||||
Bone pose = skeleton.bones.get(boneIndex);
|
||||
if (!pose.active) return;
|
||||
BonePose bone = appliedPose ? pose.applied : pose;
|
||||
Bone bone = skeleton.bones.get(boneIndex);
|
||||
if (!bone.active) return;
|
||||
BonePose pose = appliedPose ? bone.applied : bone.pose;
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) {
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bone.scaleX = pose.data.scaleX;
|
||||
bone.scaleY = pose.data.scaleY;
|
||||
pose.scaleX = bone.data.scaleX;
|
||||
pose.scaleY = bone.data.scaleY;
|
||||
return;
|
||||
case first:
|
||||
bone.scaleX += (pose.data.scaleX - bone.scaleX) * alpha;
|
||||
bone.scaleY += (pose.data.scaleY - bone.scaleY) * alpha;
|
||||
pose.scaleX += (bone.data.scaleX - pose.scaleX) * alpha;
|
||||
pose.scaleY += (bone.data.scaleY - pose.scaleY) * alpha;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -744,16 +744,16 @@ public class Animation {
|
||||
x = getBezierValue(time, i, VALUE1, curveType - BEZIER);
|
||||
y = getBezierValue(time, i, VALUE2, curveType + BEZIER_SIZE - BEZIER);
|
||||
}
|
||||
x *= pose.data.scaleX;
|
||||
y *= pose.data.scaleY;
|
||||
x *= bone.data.scaleX;
|
||||
y *= bone.data.scaleY;
|
||||
|
||||
if (alpha == 1) {
|
||||
if (blend == add) {
|
||||
bone.scaleX += x - pose.data.scaleX;
|
||||
bone.scaleY += y - pose.data.scaleY;
|
||||
pose.scaleX += x - bone.data.scaleX;
|
||||
pose.scaleY += y - bone.data.scaleY;
|
||||
} else {
|
||||
bone.scaleX = x;
|
||||
bone.scaleY = y;
|
||||
pose.scaleX = x;
|
||||
pose.scaleY = y;
|
||||
}
|
||||
} else {
|
||||
// Mixing out uses sign of setup or current pose, else use sign of key.
|
||||
@ -761,40 +761,40 @@ public class Animation {
|
||||
if (direction == out) {
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bx = pose.data.scaleX;
|
||||
by = pose.data.scaleY;
|
||||
bone.scaleX = bx + (Math.abs(x) * Math.signum(bx) - bx) * alpha;
|
||||
bone.scaleY = by + (Math.abs(y) * Math.signum(by) - by) * alpha;
|
||||
bx = bone.data.scaleX;
|
||||
by = bone.data.scaleY;
|
||||
pose.scaleX = bx + (Math.abs(x) * Math.signum(bx) - bx) * alpha;
|
||||
pose.scaleY = by + (Math.abs(y) * Math.signum(by) - by) * alpha;
|
||||
break;
|
||||
case first:
|
||||
case replace:
|
||||
bx = bone.scaleX;
|
||||
by = bone.scaleY;
|
||||
bone.scaleX = bx + (Math.abs(x) * Math.signum(bx) - bx) * alpha;
|
||||
bone.scaleY = by + (Math.abs(y) * Math.signum(by) - by) * alpha;
|
||||
bx = pose.scaleX;
|
||||
by = pose.scaleY;
|
||||
pose.scaleX = bx + (Math.abs(x) * Math.signum(bx) - bx) * alpha;
|
||||
pose.scaleY = by + (Math.abs(y) * Math.signum(by) - by) * alpha;
|
||||
break;
|
||||
case add:
|
||||
bone.scaleX += (x - pose.data.scaleX) * alpha;
|
||||
bone.scaleY += (y - pose.data.scaleY) * alpha;
|
||||
pose.scaleX += (x - bone.data.scaleX) * alpha;
|
||||
pose.scaleY += (y - bone.data.scaleY) * alpha;
|
||||
}
|
||||
} else {
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bx = Math.abs(pose.data.scaleX) * Math.signum(x);
|
||||
by = Math.abs(pose.data.scaleY) * Math.signum(y);
|
||||
bone.scaleX = bx + (x - bx) * alpha;
|
||||
bone.scaleY = by + (y - by) * alpha;
|
||||
bx = Math.abs(bone.data.scaleX) * Math.signum(x);
|
||||
by = Math.abs(bone.data.scaleY) * Math.signum(y);
|
||||
pose.scaleX = bx + (x - bx) * alpha;
|
||||
pose.scaleY = by + (y - by) * alpha;
|
||||
break;
|
||||
case first:
|
||||
case replace:
|
||||
bx = Math.abs(bone.scaleX) * Math.signum(x);
|
||||
by = Math.abs(bone.scaleY) * Math.signum(y);
|
||||
bone.scaleX = bx + (x - bx) * alpha;
|
||||
bone.scaleY = by + (y - by) * alpha;
|
||||
bx = Math.abs(pose.scaleX) * Math.signum(x);
|
||||
by = Math.abs(pose.scaleY) * Math.signum(y);
|
||||
pose.scaleX = bx + (x - bx) * alpha;
|
||||
pose.scaleY = by + (y - by) * alpha;
|
||||
break;
|
||||
case add:
|
||||
bone.scaleX += (x - pose.data.scaleX) * alpha;
|
||||
bone.scaleY += (y - pose.data.scaleY) * alpha;
|
||||
pose.scaleX += (x - bone.data.scaleX) * alpha;
|
||||
pose.scaleY += (y - bone.data.scaleY) * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -817,10 +817,10 @@ public class Animation {
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction, boolean appliedPose) {
|
||||
|
||||
Bone pose = skeleton.bones.get(boneIndex);
|
||||
if (pose.active) {
|
||||
BonePose bone = appliedPose ? pose.applied : pose;
|
||||
bone.scaleX = getScaleValue(time, alpha, blend, direction, bone.scaleX, pose.data.scaleX);
|
||||
Bone bone = skeleton.bones.get(boneIndex);
|
||||
if (bone.active) {
|
||||
BonePose pose = appliedPose ? bone.applied : bone.pose;
|
||||
pose.scaleX = getScaleValue(time, alpha, blend, direction, pose.scaleX, bone.data.scaleX);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -841,10 +841,10 @@ public class Animation {
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction, boolean appliedPose) {
|
||||
|
||||
Bone pose = skeleton.bones.get(boneIndex);
|
||||
if (pose.active) {
|
||||
BonePose bone = appliedPose ? pose.applied : pose;
|
||||
bone.scaleY = getScaleValue(time, alpha, blend, direction, bone.scaleY, pose.data.scaleY);
|
||||
Bone bone = skeleton.bones.get(boneIndex);
|
||||
if (bone.active) {
|
||||
BonePose pose = appliedPose ? bone.applied : bone.pose;
|
||||
pose.scaleY = getScaleValue(time, alpha, blend, direction, pose.scaleY, bone.data.scaleY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -867,20 +867,20 @@ public class Animation {
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction, boolean appliedPose) {
|
||||
|
||||
Bone pose = skeleton.bones.get(boneIndex);
|
||||
if (!pose.active) return;
|
||||
BonePose bone = appliedPose ? pose.applied : pose;
|
||||
Bone bone = skeleton.bones.get(boneIndex);
|
||||
if (!bone.active) return;
|
||||
BonePose pose = appliedPose ? bone.applied : bone.pose;
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) {
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bone.shearX = pose.data.shearX;
|
||||
bone.shearY = pose.data.shearY;
|
||||
pose.shearX = bone.data.shearX;
|
||||
pose.shearY = bone.data.shearY;
|
||||
return;
|
||||
case first:
|
||||
bone.shearX += (pose.data.shearX - bone.shearX) * alpha;
|
||||
bone.shearY += (pose.data.shearY - bone.shearY) * alpha;
|
||||
pose.shearX += (bone.data.shearX - pose.shearX) * alpha;
|
||||
pose.shearY += (bone.data.shearY - pose.shearY) * alpha;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -907,17 +907,17 @@ public class Animation {
|
||||
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bone.shearX = pose.data.shearX + x * alpha;
|
||||
bone.shearY = pose.data.shearY + y * alpha;
|
||||
pose.shearX = bone.data.shearX + x * alpha;
|
||||
pose.shearY = bone.data.shearY + y * alpha;
|
||||
break;
|
||||
case first:
|
||||
case replace:
|
||||
bone.shearX += (pose.data.shearX + x - bone.shearX) * alpha;
|
||||
bone.shearY += (pose.data.shearY + y - bone.shearY) * alpha;
|
||||
pose.shearX += (bone.data.shearX + x - pose.shearX) * alpha;
|
||||
pose.shearY += (bone.data.shearY + y - pose.shearY) * alpha;
|
||||
break;
|
||||
case add:
|
||||
bone.shearX += x * alpha;
|
||||
bone.shearY += y * alpha;
|
||||
pose.shearX += x * alpha;
|
||||
pose.shearY += y * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -938,10 +938,10 @@ public class Animation {
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction, boolean appliedPose) {
|
||||
|
||||
Bone pose = skeleton.bones.get(boneIndex);
|
||||
if (pose.active) {
|
||||
BonePose bone = appliedPose ? pose.applied : pose;
|
||||
bone.shearX = getRelativeValue(time, alpha, blend, bone.shearX, pose.data.shearX);
|
||||
Bone bone = skeleton.bones.get(boneIndex);
|
||||
if (bone.active) {
|
||||
BonePose pose = appliedPose ? bone.applied : bone.pose;
|
||||
pose.shearX = getRelativeValue(time, alpha, blend, pose.shearX, bone.data.shearX);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -962,10 +962,10 @@ public class Animation {
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction, boolean appliedPose) {
|
||||
|
||||
Bone pose = skeleton.bones.get(boneIndex);
|
||||
if (pose.active) {
|
||||
BonePose bone = appliedPose ? pose.applied : pose;
|
||||
bone.shearY = getRelativeValue(time, alpha, blend, bone.shearY, pose.data.shearY);
|
||||
Bone bone = skeleton.bones.get(boneIndex);
|
||||
if (bone.active) {
|
||||
BonePose pose = appliedPose ? bone.applied : bone.pose;
|
||||
pose.shearY = getRelativeValue(time, alpha, blend, pose.shearY, bone.data.shearY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1002,25 +1002,25 @@ public class Animation {
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha, MixBlend blend,
|
||||
MixDirection direction, boolean appliedPose) {
|
||||
|
||||
Bone pose = skeleton.bones.get(boneIndex);
|
||||
if (!pose.active) return;
|
||||
BonePose bone = appliedPose ? pose.applied : pose;
|
||||
Bone bone = skeleton.bones.get(boneIndex);
|
||||
if (!bone.active) return;
|
||||
BonePose pose = appliedPose ? bone.applied : bone.pose;
|
||||
|
||||
if (direction == out) {
|
||||
if (blend == setup) bone.inherit = pose.data.inherit;
|
||||
if (blend == setup) pose.inherit = bone.data.inherit;
|
||||
return;
|
||||
}
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) {
|
||||
if (blend == setup || blend == first) bone.inherit = pose.data.inherit;
|
||||
if (blend == setup || blend == first) pose.inherit = bone.data.inherit;
|
||||
return;
|
||||
}
|
||||
bone.inherit = Inherit.values[(int)frames[search(frames, time, ENTRIES) + INHERIT]];
|
||||
pose.inherit = Inherit.values[(int)frames[search(frames, time, ENTRIES) + INHERIT]];
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a slot's {@link Slot#getColor()}. */
|
||||
/** Changes a slot's {@link SlotPose#getColor()}. */
|
||||
static public class RGBATimeline extends CurveTimeline implements SlotTimeline {
|
||||
static public final int ENTRIES = 5;
|
||||
static private final int R = 1, G = 2, B = 3, A = 4;
|
||||
@ -1059,10 +1059,10 @@ public class Animation {
|
||||
|
||||
Slot slot = skeleton.slots.get(slotIndex);
|
||||
if (!slot.bone.active) return;
|
||||
if (appliedPose) slot = slot.applied;
|
||||
SlotPose pose = appliedPose ? slot.applied : slot.pose;
|
||||
|
||||
float[] frames = this.frames;
|
||||
Color color = slot.color;
|
||||
Color color = pose.color;
|
||||
if (time < frames[0]) {
|
||||
Color setup = slot.data.color;
|
||||
switch (blend) {
|
||||
@ -1113,7 +1113,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes the RGB for a slot's {@link Slot#getColor()}. */
|
||||
/** Changes the RGB for a slot's {@link SlotPose#getColor()}. */
|
||||
static public class RGBTimeline extends CurveTimeline implements SlotTimeline {
|
||||
static public final int ENTRIES = 4;
|
||||
static private final int R = 1, G = 2, B = 3;
|
||||
@ -1149,10 +1149,10 @@ public class Animation {
|
||||
|
||||
Slot slot = skeleton.slots.get(slotIndex);
|
||||
if (!slot.bone.active) return;
|
||||
if (appliedPose) slot = slot.applied;
|
||||
SlotPose pose = appliedPose ? slot.applied : slot.pose;
|
||||
|
||||
float[] frames = this.frames;
|
||||
Color color = slot.color;
|
||||
Color color = pose.color;
|
||||
if (time < frames[0]) {
|
||||
Color setup = slot.data.color;
|
||||
switch (blend) {
|
||||
@ -1211,7 +1211,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes the alpha for a slot's {@link Slot#getColor()}. */
|
||||
/** Changes the alpha for a slot's {@link SlotPose#getColor()}. */
|
||||
static public class AlphaTimeline extends CurveTimeline1 implements SlotTimeline {
|
||||
final int slotIndex;
|
||||
|
||||
@ -1229,10 +1229,10 @@ public class Animation {
|
||||
|
||||
Slot slot = skeleton.slots.get(slotIndex);
|
||||
if (!slot.bone.active) return;
|
||||
if (appliedPose) slot = slot.applied;
|
||||
SlotPose pose = appliedPose ? slot.applied : slot.pose;
|
||||
|
||||
float[] frames = this.frames;
|
||||
Color color = slot.color;
|
||||
Color color = pose.color;
|
||||
if (time < frames[0]) {
|
||||
Color setup = slot.data.color;
|
||||
switch (blend) {
|
||||
@ -1255,7 +1255,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a slot's {@link Slot#getColor()} and {@link Slot#getDarkColor()} for two color tinting. */
|
||||
/** Changes a slot's {@link SlotPose#getColor()} and {@link SlotPose#getDarkColor()} for two color tinting. */
|
||||
static public class RGBA2Timeline extends CurveTimeline implements SlotTimeline {
|
||||
static public final int ENTRIES = 8;
|
||||
static private final int R = 1, G = 2, B = 3, A = 4, R2 = 5, G2 = 6, B2 = 7;
|
||||
@ -1275,7 +1275,7 @@ public class Animation {
|
||||
}
|
||||
|
||||
/** The index of the slot in {@link Skeleton#getSlots()} that will be changed when this timeline is applied. The
|
||||
* {@link Slot#getDarkColor()} must not be null. */
|
||||
* {@link SlotPose#getDarkColor()} must not be null. */
|
||||
public int getSlotIndex () {
|
||||
return slotIndex;
|
||||
}
|
||||
@ -1300,10 +1300,10 @@ public class Animation {
|
||||
|
||||
Slot slot = skeleton.slots.get(slotIndex);
|
||||
if (!slot.bone.active) return;
|
||||
if (appliedPose) slot = slot.applied;
|
||||
SlotPose pose = appliedPose ? slot.applied : slot.pose;
|
||||
|
||||
float[] frames = this.frames;
|
||||
Color light = slot.color, dark = slot.darkColor;
|
||||
Color light = pose.color, dark = pose.darkColor;
|
||||
if (time < frames[0]) {
|
||||
Color setupLight = slot.data.color, setupDark = slot.data.darkColor;
|
||||
switch (blend) {
|
||||
@ -1384,7 +1384,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes the RGB for a slot's {@link Slot#getColor()} and {@link Slot#getDarkColor()} for two color tinting. */
|
||||
/** Changes the RGB for a slot's {@link SlotPose#getColor()} and {@link SlotPose#getDarkColor()} for two color tinting. */
|
||||
static public class RGB2Timeline extends CurveTimeline implements SlotTimeline {
|
||||
static public final int ENTRIES = 7;
|
||||
static private final int R = 1, G = 2, B = 3, R2 = 4, G2 = 5, B2 = 6;
|
||||
@ -1403,7 +1403,7 @@ public class Animation {
|
||||
}
|
||||
|
||||
/** The index of the slot in {@link Skeleton#getSlots()} that will be changed when this timeline is applied. The
|
||||
* {@link Slot#getDarkColor()} must not be null. */
|
||||
* {@link SlotPose#getDarkColor()} must not be null. */
|
||||
public int getSlotIndex () {
|
||||
return slotIndex;
|
||||
}
|
||||
@ -1427,10 +1427,10 @@ public class Animation {
|
||||
|
||||
Slot slot = skeleton.slots.get(slotIndex);
|
||||
if (!slot.bone.active) return;
|
||||
if (appliedPose) slot = slot.applied;
|
||||
SlotPose pose = appliedPose ? slot.applied : slot.pose;
|
||||
|
||||
float[] frames = this.frames;
|
||||
Color light = slot.color, dark = slot.darkColor;
|
||||
Color light = pose.color, dark = pose.darkColor;
|
||||
if (time < frames[0]) {
|
||||
Color setupLight = slot.data.color, setupDark = slot.data.darkColor;
|
||||
switch (blend) {
|
||||
@ -1516,7 +1516,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a slot's {@link Slot#getAttachment()}. */
|
||||
/** Changes a slot's {@link SlotPose#getAttachment()}. */
|
||||
static public class AttachmentTimeline extends Timeline implements SlotTimeline {
|
||||
final int slotIndex;
|
||||
final String[] attachmentNames;
|
||||
@ -1553,27 +1553,27 @@ public class Animation {
|
||||
|
||||
Slot slot = skeleton.slots.get(slotIndex);
|
||||
if (!slot.bone.active) return;
|
||||
if (appliedPose) slot = slot.applied;
|
||||
SlotPose pose = appliedPose ? slot.applied : slot.pose;
|
||||
|
||||
if (direction == out) {
|
||||
if (blend == setup) setAttachment(skeleton, slot, slot.data.attachmentName);
|
||||
if (blend == setup) setAttachment(skeleton, pose, slot.data.attachmentName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (time < this.frames[0]) {
|
||||
if (blend == setup || blend == first) setAttachment(skeleton, slot, slot.data.attachmentName);
|
||||
if (blend == setup || blend == first) setAttachment(skeleton, pose, slot.data.attachmentName);
|
||||
return;
|
||||
}
|
||||
|
||||
setAttachment(skeleton, slot, attachmentNames[search(this.frames, time)]);
|
||||
setAttachment(skeleton, pose, attachmentNames[search(this.frames, time)]);
|
||||
}
|
||||
|
||||
private void setAttachment (Skeleton skeleton, Slot slot, String attachmentName) {
|
||||
slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(slotIndex, attachmentName));
|
||||
private void setAttachment (Skeleton skeleton, SlotPose pose, String attachmentName) {
|
||||
pose.setAttachment(attachmentName == null ? null : skeleton.getAttachment(slotIndex, attachmentName));
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a slot's {@link Slot#getDeform()} to deform a {@link VertexAttachment}. */
|
||||
/** Changes a slot's {@link SlotPose#getDeform()} to deform a {@link VertexAttachment}. */
|
||||
static public class DeformTimeline extends CurveTimeline implements SlotTimeline {
|
||||
final int slotIndex;
|
||||
final VertexAttachment attachment;
|
||||
@ -1671,11 +1671,12 @@ public class Animation {
|
||||
MixDirection direction, boolean appliedPose) {
|
||||
|
||||
Slot slot = skeleton.slots.get(slotIndex);
|
||||
if (!slot.bone.active || !(slot.attachment instanceof VertexAttachment vertexAttachment)
|
||||
if (!slot.bone.active) return;
|
||||
SlotPose pose = appliedPose ? slot.applied : slot.pose;
|
||||
if (!(pose.attachment instanceof VertexAttachment vertexAttachment)
|
||||
|| vertexAttachment.getTimelineAttachment() != attachment) return;
|
||||
if (appliedPose) slot = slot.applied;
|
||||
|
||||
FloatArray deformArray = slot.deform;
|
||||
FloatArray deformArray = pose.deform;
|
||||
if (deformArray.size == 0) blend = setup;
|
||||
|
||||
float[][] vertices = this.vertices;
|
||||
@ -2612,7 +2613,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a slot's {@link Slot#getSequenceIndex()} for an attachment's {@link Sequence}. */
|
||||
/** Changes a slot's {@link SlotPose#getSequenceIndex()} for an attachment's {@link Sequence}. */
|
||||
static public class SequenceTimeline extends Timeline implements SlotTimeline {
|
||||
static public final int ENTRIES = 3;
|
||||
static private final int MODE = 1, DELAY = 2;
|
||||
@ -2654,9 +2655,9 @@ public class Animation {
|
||||
|
||||
Slot slot = skeleton.slots.get(slotIndex);
|
||||
if (!slot.bone.active) return;
|
||||
if (appliedPose) slot = slot.applied;
|
||||
SlotPose pose = appliedPose ? slot.applied : slot.pose;
|
||||
|
||||
Attachment slotAttachment = slot.attachment;
|
||||
Attachment slotAttachment = pose.attachment;
|
||||
if (slotAttachment != attachment) {
|
||||
if (!(slotAttachment instanceof VertexAttachment vertexAttachment)
|
||||
|| vertexAttachment.getTimelineAttachment() != attachment) return;
|
||||
@ -2665,13 +2666,13 @@ public class Animation {
|
||||
if (sequence == null) return;
|
||||
|
||||
if (direction == out) {
|
||||
if (blend == setup) slot.setSequenceIndex(-1);
|
||||
if (blend == setup) pose.setSequenceIndex(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) {
|
||||
if (blend == setup || blend == first) slot.setSequenceIndex(-1);
|
||||
if (blend == setup || blend == first) pose.setSequenceIndex(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2709,7 +2710,7 @@ public class Animation {
|
||||
if (index >= count) index = n - index;
|
||||
}
|
||||
}
|
||||
slot.setSequenceIndex(index);
|
||||
pose.setSequenceIndex(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -278,7 +278,7 @@ public class AnimationState {
|
||||
var slot = (Slot)slots[i];
|
||||
if (slot.attachmentState == setupState) {
|
||||
String attachmentName = slot.data.attachmentName;
|
||||
slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(slot.data.index, attachmentName));
|
||||
slot.getPose().setAttachment(attachmentName == null ? null : skeleton.getAttachment(slot.data.index, attachmentName));
|
||||
}
|
||||
}
|
||||
unkeyedState += 2; // Increasing after each use avoids the need to reset attachmentState for every slot.
|
||||
@ -399,7 +399,7 @@ public class AnimationState {
|
||||
}
|
||||
|
||||
private void setAttachment (Skeleton skeleton, Slot slot, String attachmentName, boolean attachments) {
|
||||
slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(slot.data.index, attachmentName));
|
||||
slot.getPose().setAttachment(attachmentName == null ? null : skeleton.getAttachment(slot.data.index, attachmentName));
|
||||
if (attachments) slot.attachmentState = unkeyedState + CURRENT;
|
||||
}
|
||||
|
||||
@ -417,21 +417,22 @@ public class AnimationState {
|
||||
|
||||
Bone bone = skeleton.bones.get(timeline.boneIndex);
|
||||
if (!bone.active) return;
|
||||
BonePose pose = bone.getPose();
|
||||
float[] frames = timeline.frames;
|
||||
float r1, r2;
|
||||
if (time < frames[0]) { // Time is before first frame.
|
||||
switch (blend) {
|
||||
case setup:
|
||||
bone.rotation = bone.data.rotation;
|
||||
pose.rotation = bone.data.rotation;
|
||||
// Fall through.
|
||||
default:
|
||||
return;
|
||||
case first:
|
||||
r1 = bone.rotation;
|
||||
r1 = pose.rotation;
|
||||
r2 = bone.data.rotation;
|
||||
}
|
||||
} else {
|
||||
r1 = blend == MixBlend.setup ? bone.data.rotation : bone.rotation;
|
||||
r1 = blend == MixBlend.setup ? bone.data.rotation : pose.rotation;
|
||||
r2 = bone.data.rotation + timeline.getCurveValue(time);
|
||||
}
|
||||
|
||||
@ -465,7 +466,7 @@ public class AnimationState {
|
||||
timelinesRotation[i] = total;
|
||||
}
|
||||
timelinesRotation[i + 1] = diff;
|
||||
bone.rotation = r1 + total * alpha;
|
||||
pose.rotation = r1 + total * alpha;
|
||||
}
|
||||
|
||||
private void queueEvents (TrackEntry entry, float animationTime) {
|
||||
|
||||
@ -32,18 +32,19 @@ package com.esotericsoftware.spine;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Null;
|
||||
|
||||
/** Stores a bone's current pose.
|
||||
// BOZO - Update javadocs.
|
||||
/** The current pose for a bone, before constraints are applied.
|
||||
* <p>
|
||||
* A bone has a local transform which is used to compute its world transform. A bone also has an applied transform, which is a
|
||||
* local transform that can be applied to compute the world transform. The local transform and applied transform may differ if a
|
||||
* constraint or application code modifies the world transform after it was computed from the local transform. */
|
||||
public class Bone extends BonePose {
|
||||
public class Bone {
|
||||
final BoneData data;
|
||||
final Skeleton skeleton;
|
||||
@Null final Bone parent;
|
||||
final Array<Bone> children;
|
||||
final Array<Bone> children = new Array();
|
||||
final BonePose pose = new BonePose();
|
||||
final BoneApplied applied = new BoneApplied(this);
|
||||
|
||||
boolean sorted, active;
|
||||
|
||||
public Bone (BoneData data, Skeleton skeleton, @Null Bone parent) {
|
||||
@ -52,31 +53,20 @@ public class Bone extends BonePose {
|
||||
this.data = data;
|
||||
this.skeleton = skeleton;
|
||||
this.parent = parent;
|
||||
children = new Array();
|
||||
|
||||
setToSetupPose();
|
||||
setupPose();
|
||||
}
|
||||
|
||||
/** Copy constructor. Does not copy the {@link #getChildren()} bones. */
|
||||
public Bone (Bone bone, Skeleton skeleton, @Null Bone parent) {
|
||||
super(bone);
|
||||
this.data = bone.data;
|
||||
this.skeleton = skeleton;
|
||||
this.parent = parent;
|
||||
children = new Array();
|
||||
data = bone.data;
|
||||
pose.set(bone.pose);
|
||||
}
|
||||
|
||||
/** Sets this bone's local transform to the setup pose. */
|
||||
public void setToSetupPose () {
|
||||
BoneData data = this.data;
|
||||
x = data.x;
|
||||
y = data.y;
|
||||
rotation = data.rotation;
|
||||
scaleX = data.scaleX;
|
||||
scaleY = data.scaleY;
|
||||
shearX = data.shearX;
|
||||
shearY = data.shearY;
|
||||
inherit = data.inherit;
|
||||
public void setupPose () {
|
||||
pose.set(data);
|
||||
}
|
||||
|
||||
/** The bone's setup pose data. */
|
||||
@ -84,6 +74,16 @@ public class Bone extends BonePose {
|
||||
return data;
|
||||
}
|
||||
|
||||
/** Returns the bone's pose. */
|
||||
public BonePose getPose () {
|
||||
return pose;
|
||||
}
|
||||
|
||||
/** Returns the bone's applied pose. */
|
||||
public BoneApplied getAppliedPose () {
|
||||
return applied;
|
||||
}
|
||||
|
||||
/** The skeleton this bone belongs to. */
|
||||
public Skeleton getSkeleton () {
|
||||
return skeleton;
|
||||
@ -99,9 +99,8 @@ public class Bone extends BonePose {
|
||||
return children;
|
||||
}
|
||||
|
||||
/** Returns false when this bone won't be updated by
|
||||
* {@link Skeleton#updateWorldTransform(com.esotericsoftware.spine.Skeleton.Physics)} because a skin is required and the
|
||||
* {@link Skeleton#getSkin() active skin} does not contain this item.
|
||||
/** Returns false when this bone won't be updated by {@link Skeleton#updateWorldTransform(com.esotericsoftware.spine.Physics)}
|
||||
* because a skin is required and the {@link Skeleton#getSkin() active skin} does not contain this item.
|
||||
* @see Skin#getBones()
|
||||
* @see Skin#getConstraints()
|
||||
* @see BoneData#getSkinRequired()
|
||||
@ -110,11 +109,6 @@ public class Bone extends BonePose {
|
||||
return active;
|
||||
}
|
||||
|
||||
/** Returns the bone for applied pose. */
|
||||
public BoneApplied getApplied () {
|
||||
return applied;
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
return data.name;
|
||||
}
|
||||
|
||||
@ -9,16 +9,17 @@ import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Null;
|
||||
|
||||
import com.esotericsoftware.spine.BoneData.Inherit;
|
||||
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||
|
||||
/** The applied pose for a bone. This is the {@link Bone} pose with constraints applied and the world transform computed by
|
||||
* {@link Skeleton#updateWorldTransform(Physics)}. */
|
||||
public class BoneApplied extends BonePose implements Updatable {
|
||||
final Bone pose;
|
||||
final Bone bone;
|
||||
@Null final BoneApplied parent;
|
||||
float a, b, worldX;
|
||||
float c, d, worldY;
|
||||
|
||||
BoneApplied (Bone bone) {
|
||||
pose = bone;
|
||||
this.bone = bone;
|
||||
parent = bone.parent == null ? null : bone.parent.applied;
|
||||
}
|
||||
|
||||
@ -36,10 +37,9 @@ public class BoneApplied extends BonePose implements Updatable {
|
||||
* See <a href="https://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
public void update (Physics physics) {
|
||||
Skeleton skeleton = pose.skeleton;
|
||||
|
||||
BoneApplied parent = this.parent;
|
||||
if (parent == null) { // Root bone.
|
||||
Skeleton skeleton = bone.skeleton;
|
||||
float sx = skeleton.scaleX, sy = skeleton.scaleY;
|
||||
float rx = (rotation + shearX) * degRad;
|
||||
float ry = (rotation + 90 + shearY) * degRad;
|
||||
@ -79,7 +79,7 @@ public class BoneApplied extends BonePose implements Updatable {
|
||||
d = sin(ry) * scaleY;
|
||||
}
|
||||
case noRotationOrReflection -> {
|
||||
float sx = 1 / skeleton.scaleX, sy = 1 / skeleton.scaleY;
|
||||
float sx = 1 / bone.skeleton.scaleX, sy = 1 / bone.skeleton.scaleY;
|
||||
pa *= sx;
|
||||
pc *= sy;
|
||||
float s = pa * pa + pc * pc, prx;
|
||||
@ -105,6 +105,7 @@ public class BoneApplied extends BonePose implements Updatable {
|
||||
d = pc * lb + pd * ld;
|
||||
}
|
||||
case noScale, noScaleOrReflection -> {
|
||||
Skeleton skeleton = bone.skeleton;
|
||||
rotation *= degRad;
|
||||
float cos = cos(rotation), sin = sin(rotation);
|
||||
float za = (pa * cos + pb * sin) / skeleton.scaleX;
|
||||
@ -130,6 +131,7 @@ public class BoneApplied extends BonePose implements Updatable {
|
||||
d = zc * lb + zd * ld;
|
||||
}
|
||||
}
|
||||
Skeleton skeleton = bone.skeleton;
|
||||
a *= skeleton.scaleX;
|
||||
b *= skeleton.scaleX;
|
||||
c *= skeleton.scaleY;
|
||||
@ -145,12 +147,10 @@ public class BoneApplied extends BonePose implements Updatable {
|
||||
* Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. The local transform after
|
||||
* calling this method is equivalent to the local transform used to compute the world transform, but may not be identical. */
|
||||
public void updateLocalTransform () {
|
||||
Skeleton skeleton = pose.skeleton;
|
||||
|
||||
BoneApplied parent = this.parent;
|
||||
if (parent == null) {
|
||||
x = worldX - skeleton.x;
|
||||
y = worldY - skeleton.y;
|
||||
x = worldX - bone.skeleton.x;
|
||||
y = worldY - bone.skeleton.y;
|
||||
float a = this.a, b = this.b, c = this.c, d = this.d;
|
||||
rotation = atan2Deg(c, a);
|
||||
scaleX = (float)Math.sqrt(a * a + c * c);
|
||||
@ -174,6 +174,7 @@ public class BoneApplied extends BonePose implements Updatable {
|
||||
rc = c;
|
||||
rd = d;
|
||||
} else {
|
||||
Skeleton skeleton = bone.skeleton;
|
||||
switch (inherit) {
|
||||
case noRotationOrReflection -> {
|
||||
float s = Math.abs(pa * pd - pb * pc) / (pa * pa + pc * pc);
|
||||
@ -371,4 +372,8 @@ public class BoneApplied extends BonePose implements Updatable {
|
||||
c = sin * ra + cos * c;
|
||||
d = sin * rb + cos * d;
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
return bone.data.name;
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,16 +32,12 @@ 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 BonePose}. */
|
||||
public class BoneData {
|
||||
/** The setup pose for a bone. */
|
||||
public class BoneData extends BonePose {
|
||||
final int index;
|
||||
final String name;
|
||||
@Null final BoneData parent;
|
||||
float length;
|
||||
float x, y, rotation, scaleX = 1, scaleY = 1, shearX, shearY;
|
||||
Inherit inherit = Inherit.normal;
|
||||
boolean skinRequired;
|
||||
|
||||
// Nonessential.
|
||||
@ -59,18 +55,11 @@ public class BoneData {
|
||||
|
||||
/** Copy constructor. */
|
||||
public BoneData (BoneData bone, @Null BoneData parent) {
|
||||
if (bone == null) throw new IllegalArgumentException("bone cannot be null.");
|
||||
index = bone.index;
|
||||
name = bone.name;
|
||||
this.parent = parent;
|
||||
length = bone.length;
|
||||
x = bone.x;
|
||||
y = bone.y;
|
||||
rotation = bone.rotation;
|
||||
scaleX = bone.scaleX;
|
||||
scaleY = bone.scaleY;
|
||||
shearX = bone.shearX;
|
||||
shearY = bone.shearY;
|
||||
set(bone);
|
||||
}
|
||||
|
||||
/** The index of the bone in {@link Skeleton#getBones()}. */
|
||||
@ -96,89 +85,6 @@ public class BoneData {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
/** The local x translation. */
|
||||
public float getX () {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX (float x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
/** The local y translation. */
|
||||
public float getY () {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY (float y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public void setPosition (float x, float y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/** The local rotation in degrees, counter clockwise. */
|
||||
public float getRotation () {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
public void setRotation (float rotation) {
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
/** The local scaleX. */
|
||||
public float getScaleX () {
|
||||
return scaleX;
|
||||
}
|
||||
|
||||
public void setScaleX (float scaleX) {
|
||||
this.scaleX = scaleX;
|
||||
}
|
||||
|
||||
/** The local scaleY. */
|
||||
public float getScaleY () {
|
||||
return scaleY;
|
||||
}
|
||||
|
||||
public void setScaleY (float scaleY) {
|
||||
this.scaleY = scaleY;
|
||||
}
|
||||
|
||||
public void setScale (float scaleX, float scaleY) {
|
||||
this.scaleX = scaleX;
|
||||
this.scaleY = scaleY;
|
||||
}
|
||||
|
||||
/** The local shearX. */
|
||||
public float getShearX () {
|
||||
return shearX;
|
||||
}
|
||||
|
||||
public void setShearX (float shearX) {
|
||||
this.shearX = shearX;
|
||||
}
|
||||
|
||||
/** The local shearX. */
|
||||
public float getShearY () {
|
||||
return shearY;
|
||||
}
|
||||
|
||||
public void setShearY (float shearY) {
|
||||
this.shearY = shearY;
|
||||
}
|
||||
|
||||
/** Determines how parent world transforms affect this bone. */
|
||||
public Inherit getInherit () {
|
||||
return inherit;
|
||||
}
|
||||
|
||||
public void setInherit (Inherit inherit) {
|
||||
if (inherit == null) throw new IllegalArgumentException("inherit cannot be null.");
|
||||
this.inherit = inherit;
|
||||
}
|
||||
|
||||
/** When true, {@link Skeleton#updateWorldTransform(Physics)} only updates this bone if the {@link Skeleton#getSkin()} contains
|
||||
* this bone.
|
||||
* <p>
|
||||
|
||||
@ -31,11 +31,7 @@ package com.esotericsoftware.spine;
|
||||
|
||||
import com.esotericsoftware.spine.BoneData.Inherit;
|
||||
|
||||
/** Stores a bone's current pose.
|
||||
* <p>
|
||||
* A bone has a local transform which is used to compute its world transform. A bone also has an applied transform, which is a
|
||||
* local transform that can be applied to compute the world transform. The local transform and applied transform may differ if a
|
||||
* constraint or application code modifies the world transform after it was computed from the local transform. */
|
||||
/** Stores a bone's local pose. */
|
||||
public class BonePose {
|
||||
float x, y, rotation, scaleX, scaleY, shearX, shearY;
|
||||
Inherit inherit;
|
||||
@ -43,8 +39,8 @@ public class BonePose {
|
||||
BonePose () {
|
||||
}
|
||||
|
||||
/** Copy constructor. */
|
||||
public BonePose (BonePose bone) {
|
||||
public void set (BonePose bone) {
|
||||
if (bone == null) throw new IllegalArgumentException("bone cannot be null.");
|
||||
x = bone.x;
|
||||
y = bone.y;
|
||||
rotation = bone.rotation;
|
||||
|
||||
@ -29,8 +29,6 @@
|
||||
|
||||
package com.esotericsoftware.spine;
|
||||
|
||||
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||
|
||||
/** The base class for all constraint datas. */
|
||||
abstract public class ConstraintData {
|
||||
final String name;
|
||||
|
||||
@ -34,7 +34,6 @@ import static com.esotericsoftware.spine.utils.SpineUtils.*;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
|
||||
import com.esotericsoftware.spine.BoneData.Inherit;
|
||||
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.
|
||||
@ -70,16 +69,16 @@ public class IkConstraint implements Updatable {
|
||||
|
||||
applied = new IkConstraint(data, bones, target);
|
||||
|
||||
setToSetupPose();
|
||||
setupPose();
|
||||
}
|
||||
|
||||
/** Copy constructor. */
|
||||
public IkConstraint (IkConstraint constraint, Skeleton skeleton) {
|
||||
this(constraint.data, skeleton);
|
||||
setToSetupPose();
|
||||
setupPose();
|
||||
}
|
||||
|
||||
public void setToSetupPose () {
|
||||
public void setupPose () {
|
||||
IkConstraintData data = this.data;
|
||||
mix = data.mix;
|
||||
softness = data.softness;
|
||||
@ -168,7 +167,7 @@ public class IkConstraint implements Updatable {
|
||||
}
|
||||
|
||||
/** Returns false when this constraint won't be updated by
|
||||
* {@link Skeleton#updateWorldTransform(com.esotericsoftware.spine.Skeleton.Physics)} because a skin is required and the
|
||||
* {@link Skeleton#updateWorldTransform(com.esotericsoftware.spine.Physics)} because a skin is required and the
|
||||
* {@link Skeleton#getSkin() active skin} does not contain this item.
|
||||
* @see Skin#getBones()
|
||||
* @see Skin#getConstraints()
|
||||
@ -196,12 +195,12 @@ public class IkConstraint implements Updatable {
|
||||
float rotationIK = -bone.shearX - bone.rotation, tx, ty;
|
||||
switch (bone.inherit) {
|
||||
case onlyTranslation:
|
||||
tx = (targetX - bone.worldX) * Math.signum(bone.pose.skeleton.scaleX);
|
||||
ty = (targetY - bone.worldY) * Math.signum(bone.pose.skeleton.scaleY);
|
||||
tx = (targetX - bone.worldX) * Math.signum(bone.bone.skeleton.scaleX);
|
||||
ty = (targetY - bone.worldY) * Math.signum(bone.bone.skeleton.scaleY);
|
||||
break;
|
||||
case noRotationOrReflection:
|
||||
float s = Math.abs(pa * pd - pb * pc) / Math.max(0.0001f, pa * pa + pc * pc);
|
||||
Skeleton skeleton = bone.pose.skeleton;
|
||||
Skeleton skeleton = bone.bone.skeleton;
|
||||
float sa = pa / skeleton.scaleX;
|
||||
float sc = pc / skeleton.scaleY;
|
||||
pb = -sc * s * skeleton.scaleX;
|
||||
@ -233,7 +232,7 @@ public class IkConstraint implements Updatable {
|
||||
ty = targetY - bone.worldY;
|
||||
}
|
||||
}
|
||||
float b = bone.pose.data.length * bone.scaleX;
|
||||
float b = bone.bone.data.length * bone.scaleX;
|
||||
if (b > 0.0001f) {
|
||||
float dd = tx * tx + ty * ty;
|
||||
if ((compress && dd < b * b) || (stretch && dd > b * b)) {
|
||||
@ -290,7 +289,7 @@ public class IkConstraint implements Updatable {
|
||||
float id = a * d - b * c, x = cwx - pp.worldX, y = cwy - pp.worldY;
|
||||
id = Math.abs(id) <= 0.0001f ? 0 : 1 / id;
|
||||
float dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py;
|
||||
float l1 = (float)Math.sqrt(dx * dx + dy * dy), l2 = child.pose.data.length * csx, a1, a2;
|
||||
float l1 = (float)Math.sqrt(dx * dx + dy * dy), l2 = child.bone.data.length * csx, a1, a2;
|
||||
if (l1 < 0.0001f) {
|
||||
apply(parent, targetX, targetY, false, stretch, false, alpha);
|
||||
child.rotation = 0;
|
||||
|
||||
@ -35,12 +35,10 @@ import java.util.Arrays;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.FloatArray;
|
||||
import com.badlogic.gdx.utils.Null;
|
||||
|
||||
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.PathAttachment;
|
||||
|
||||
/** Stores the current pose for a path constraint. A path constraint adjusts the rotation, translation, and scale of the
|
||||
@ -82,16 +80,16 @@ public class PathConstraint implements Updatable {
|
||||
|
||||
applied = new PathConstraint(data, bones, slot);
|
||||
|
||||
setToSetupPose();
|
||||
setupPose();
|
||||
}
|
||||
|
||||
/** Copy constructor. */
|
||||
public PathConstraint (PathConstraint constraint, Skeleton skeleton) {
|
||||
this(constraint.data, skeleton);
|
||||
setToSetupPose();
|
||||
setupPose();
|
||||
}
|
||||
|
||||
public void setToSetupPose () {
|
||||
public void setupPose () {
|
||||
PathConstraintData data = this.data;
|
||||
position = data.position;
|
||||
spacing = data.spacing;
|
||||
@ -102,7 +100,7 @@ public class PathConstraint implements Updatable {
|
||||
|
||||
/** Applies the constraint to the constrained bones. */
|
||||
public void update (Physics physics) {
|
||||
if (!(slot.attachment instanceof PathAttachment pathAttachment)) return;
|
||||
if (!(slot.applied.attachment instanceof PathAttachment pathAttachment)) return;
|
||||
|
||||
float mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY;
|
||||
if (mixRotate == 0 && mixX == 0 && mixY == 0) return;
|
||||
@ -119,7 +117,7 @@ public class PathConstraint implements Updatable {
|
||||
if (scale) {
|
||||
for (int i = 0, n = spacesCount - 1; i < n; i++) {
|
||||
var bone = (BoneApplied)bones[i];
|
||||
float setupLength = bone.pose.data.length;
|
||||
float setupLength = bone.bone.data.length;
|
||||
float x = setupLength * bone.a, y = setupLength * bone.c;
|
||||
lengths[i] = (float)Math.sqrt(x * x + y * y);
|
||||
}
|
||||
@ -130,7 +128,7 @@ public class PathConstraint implements Updatable {
|
||||
float sum = 0;
|
||||
for (int i = 0, n = spacesCount - 1; i < n;) {
|
||||
var bone = (BoneApplied)bones[i];
|
||||
float setupLength = bone.pose.data.length;
|
||||
float setupLength = bone.bone.data.length;
|
||||
if (setupLength < epsilon) {
|
||||
if (scale) lengths[i] = 0;
|
||||
spaces[++i] = spacing;
|
||||
@ -152,7 +150,7 @@ public class PathConstraint implements Updatable {
|
||||
boolean lengthSpacing = data.spacingMode == SpacingMode.length;
|
||||
for (int i = 0, n = spacesCount - 1; i < n;) {
|
||||
var bone = (BoneApplied)bones[i];
|
||||
float setupLength = bone.pose.data.length;
|
||||
float setupLength = bone.bone.data.length;
|
||||
if (setupLength < epsilon) {
|
||||
if (scale) lengths[i] = 0;
|
||||
spaces[++i] = spacing;
|
||||
@ -203,7 +201,7 @@ public class PathConstraint implements Updatable {
|
||||
if (tip) {
|
||||
cos = cos(r);
|
||||
sin = sin(r);
|
||||
float length = bone.pose.data.length;
|
||||
float length = bone.bone.data.length;
|
||||
boneX += (length * (cos * a - sin * c) - dx) * mixRotate;
|
||||
boneY += (length * (sin * a + cos * c) - dy) * mixRotate;
|
||||
} else
|
||||
@ -543,7 +541,7 @@ public class PathConstraint implements Updatable {
|
||||
}
|
||||
|
||||
/** Returns false when this constraint won't be updated by
|
||||
* {@link Skeleton#updateWorldTransform(com.esotericsoftware.spine.Skeleton.Physics)} because a skin is required and the
|
||||
* {@link Skeleton#updateWorldTransform(com.esotericsoftware.spine.Physics)} because a skin is required and the
|
||||
* {@link Skeleton#getSkin() active skin} does not contain this item.
|
||||
* @see Skin#getBones()
|
||||
* @see Skin#getConstraints()
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
|
||||
package com.esotericsoftware.spine;
|
||||
|
||||
/** Determines how physics and other non-deterministic updates are applied. */
|
||||
public enum Physics {
|
||||
/** Physics are not updated or applied. */
|
||||
none,
|
||||
|
||||
/** Physics are reset to the current pose. */
|
||||
reset,
|
||||
|
||||
/** Physics are updated and the pose from physics is applied. */
|
||||
update,
|
||||
|
||||
/** Physics are not updated but the pose from physics is applied. */
|
||||
pose
|
||||
}
|
||||
@ -31,8 +31,6 @@ package com.esotericsoftware.spine;
|
||||
|
||||
import static com.esotericsoftware.spine.utils.SpineUtils.*;
|
||||
|
||||
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||
|
||||
/** Stores the current pose for a physics constraint. A physics constraint applies physics to bones.
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-physics-constraints">Physics constraints</a> in the Spine User Guide. */
|
||||
@ -69,13 +67,13 @@ public class PhysicsConstraint implements Updatable {
|
||||
|
||||
applied = new PhysicsConstraint(data, skeleton, bone);
|
||||
|
||||
setToSetupPose();
|
||||
setupPose();
|
||||
}
|
||||
|
||||
/** Copy constructor. */
|
||||
public PhysicsConstraint (PhysicsConstraint constraint, Skeleton skeleton) {
|
||||
this(constraint.data, skeleton);
|
||||
setToSetupPose();
|
||||
setupPose();
|
||||
}
|
||||
|
||||
public void reset () {
|
||||
@ -92,7 +90,7 @@ public class PhysicsConstraint implements Updatable {
|
||||
scaleVelocity = 0;
|
||||
}
|
||||
|
||||
public void setToSetupPose () {
|
||||
public void setupPose () {
|
||||
PhysicsConstraintData data = this.data;
|
||||
inertia = data.inertia;
|
||||
strength = data.strength;
|
||||
@ -127,7 +125,7 @@ public class PhysicsConstraint implements Updatable {
|
||||
|
||||
boolean x = data.x > 0, y = data.y > 0, rotateOrShearX = data.rotate > 0 || data.shearX > 0, scaleX = data.scaleX > 0;
|
||||
BoneApplied bone = this.bone;
|
||||
float l = bone.pose.data.length;
|
||||
float l = bone.bone.data.length;
|
||||
|
||||
switch (physics) {
|
||||
case none:
|
||||
@ -352,7 +350,7 @@ public class PhysicsConstraint implements Updatable {
|
||||
}
|
||||
|
||||
/** Returns false when this constraint won't be updated by
|
||||
* {@link Skeleton#updateWorldTransform(com.esotericsoftware.spine.Skeleton.Physics)} because a skin is required and the
|
||||
* {@link Skeleton#updateWorldTransform(com.esotericsoftware.spine.Physics)} because a skin is required and the
|
||||
* {@link Skeleton#getSkin() active skin} does not contain this item.
|
||||
* @see Skin#getBones()
|
||||
* @see Skin#getConstraints()
|
||||
|
||||
@ -273,20 +273,20 @@ public class Skeleton {
|
||||
}
|
||||
|
||||
private void sortIkConstraint (IkConstraint constraint) {
|
||||
constraint.active = constraint.target.pose.active
|
||||
constraint.active = constraint.target.bone.active
|
||||
&& (!constraint.data.skinRequired || (skin != null && skin.constraints.contains(constraint.data, true)));
|
||||
if (!constraint.active) return;
|
||||
|
||||
sortBone(constraint.target.pose);
|
||||
sortBone(constraint.target.bone);
|
||||
|
||||
Array<BoneApplied> constrained = constraint.bones;
|
||||
Bone parent = constrained.first().pose;
|
||||
Bone parent = constrained.first().bone;
|
||||
sortBone(parent);
|
||||
if (constrained.size == 1) {
|
||||
updateCache.add(constraint);
|
||||
sortReset(parent.children);
|
||||
} else {
|
||||
Bone child = constrained.peek().pose;
|
||||
Bone child = constrained.peek().bone;
|
||||
sortBone(child);
|
||||
|
||||
updateCache.add(constraint);
|
||||
@ -297,31 +297,31 @@ public class Skeleton {
|
||||
}
|
||||
|
||||
private void sortTransformConstraint (TransformConstraint constraint) {
|
||||
constraint.active = constraint.source.pose.active
|
||||
constraint.active = constraint.source.bone.active
|
||||
&& (!constraint.data.skinRequired || (skin != null && skin.constraints.contains(constraint.data, true)));
|
||||
if (!constraint.active) return;
|
||||
|
||||
sortBone(constraint.source.pose);
|
||||
sortBone(constraint.source.bone);
|
||||
|
||||
Object[] constrained = constraint.bones.items;
|
||||
int boneCount = constraint.bones.size;
|
||||
if (constraint.data.localSource) {
|
||||
for (int i = 0; i < boneCount; i++) {
|
||||
Bone child = ((BoneApplied)constrained[i]).pose;
|
||||
Bone child = ((BoneApplied)constrained[i]).bone;
|
||||
sortBone(child.parent);
|
||||
sortBone(child);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < boneCount; i++)
|
||||
sortBone(((BoneApplied)constrained[i]).pose);
|
||||
sortBone(((BoneApplied)constrained[i]).bone);
|
||||
}
|
||||
|
||||
updateCache.add(constraint);
|
||||
|
||||
for (int i = 0; i < boneCount; i++)
|
||||
sortReset(((BoneApplied)constrained[i]).pose.children);
|
||||
sortReset(((BoneApplied)constrained[i]).bone.children);
|
||||
for (int i = 0; i < boneCount; i++)
|
||||
((BoneApplied)constrained[i]).pose.sorted = true;
|
||||
((BoneApplied)constrained[i]).bone.sorted = true;
|
||||
}
|
||||
|
||||
private void sortPathConstraint (PathConstraint constraint) {
|
||||
@ -336,12 +336,12 @@ public class Skeleton {
|
||||
if (data.defaultSkin != null && data.defaultSkin != skin)
|
||||
sortPathConstraintAttachment(data.defaultSkin, slotIndex, slotBone);
|
||||
|
||||
sortPathConstraintAttachment(slot.attachment, slotBone);
|
||||
sortPathConstraintAttachment(slot.pose.attachment, slotBone);
|
||||
|
||||
Object[] constrained = constraint.bones.items;
|
||||
int boneCount = constraint.bones.size;
|
||||
for (int i = 0; i < boneCount; i++)
|
||||
sortBone(((BoneApplied)constrained[i]).pose);
|
||||
sortBone(((BoneApplied)constrained[i]).bone);
|
||||
|
||||
updateCache.add(constraint);
|
||||
|
||||
@ -370,13 +370,13 @@ public class Skeleton {
|
||||
int nn = pathBones[i++];
|
||||
nn += i;
|
||||
while (i < nn)
|
||||
sortBone(((BoneApplied)bones[pathBones[i++]]).pose);
|
||||
sortBone(((BoneApplied)bones[pathBones[i++]]).bone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sortPhysicsConstraint (PhysicsConstraint constraint) {
|
||||
Bone bone = constraint.bone.pose;
|
||||
Bone bone = constraint.bone.bone;
|
||||
constraint.active = bone.active
|
||||
&& (!constraint.data.skinRequired || (skin != null && skin.constraints.contains(constraint.data, true)));
|
||||
if (!constraint.active) return;
|
||||
@ -415,27 +415,12 @@ public class Skeleton {
|
||||
Object[] bones = this.bones.items;
|
||||
for (int i = 0, n = this.bones.size; i < n; i++) {
|
||||
var bone = (Bone)bones[i];
|
||||
if (!bone.active) continue;
|
||||
BoneApplied applied = bone.applied;
|
||||
applied.x = bone.x;
|
||||
applied.y = bone.y;
|
||||
applied.rotation = bone.rotation;
|
||||
applied.scaleX = bone.scaleX;
|
||||
applied.scaleY = bone.scaleY;
|
||||
applied.shearX = bone.shearX;
|
||||
applied.shearY = bone.shearY;
|
||||
applied.inherit = bone.inherit;
|
||||
if (bone.active) bone.applied.set(bone.pose);
|
||||
}
|
||||
Object[] slots = this.slots.items;
|
||||
for (int i = 0, n = this.slots.size; i < n; i++) {
|
||||
var slot = (Slot)slots[i];
|
||||
if (!slot.bone.active) continue;
|
||||
Slot applied = slot.applied;
|
||||
applied.color.set(slot.color);
|
||||
if (applied.darkColor != null) applied.darkColor.set(slot.darkColor);
|
||||
applied.attachment = slot.attachment;
|
||||
applied.sequenceIndex = slot.sequenceIndex;
|
||||
applied.deform = slot.deform;
|
||||
if (slot.bone.active) slot.applied.set(slot.pose);
|
||||
}
|
||||
// BOZO! - Reset the rest.
|
||||
|
||||
@ -455,15 +440,7 @@ public class Skeleton {
|
||||
Object[] bones = this.bones.items;
|
||||
for (int i = 1, n = this.bones.size; i < n; i++) { // Skip root bone.
|
||||
var bone = (Bone)bones[i];
|
||||
BoneApplied applied = bone.applied;
|
||||
applied.x = bone.x;
|
||||
applied.y = bone.y;
|
||||
applied.rotation = bone.rotation;
|
||||
applied.scaleX = bone.scaleX;
|
||||
applied.scaleY = bone.scaleY;
|
||||
applied.shearX = bone.shearX;
|
||||
applied.shearY = bone.shearY;
|
||||
applied.inherit = bone.inherit;
|
||||
if (bone.active) bone.applied.set(bone.pose);
|
||||
}
|
||||
// BOZO! - Reset the rest.
|
||||
|
||||
@ -493,45 +470,45 @@ public class Skeleton {
|
||||
}
|
||||
|
||||
/** Sets the bones, constraints, slots, and draw order to their setup pose values. */
|
||||
public void setToSetupPose () {
|
||||
setBonesToSetupPose();
|
||||
setSlotsToSetupPose();
|
||||
public void setupPose () {
|
||||
setupPoseBones();
|
||||
setupPoseSlots();
|
||||
}
|
||||
|
||||
/** Sets the bones and constraints to their setup pose values. */
|
||||
public void setBonesToSetupPose () {
|
||||
public void setupPoseBones () {
|
||||
Object[] bones = this.bones.items;
|
||||
for (int i = 0, n = this.bones.size; i < n; i++)
|
||||
((Bone)bones[i]).setToSetupPose();
|
||||
((Bone)bones[i]).setupPose();
|
||||
|
||||
Object[] constraints = sliders.items;
|
||||
for (int i = 0, n = sliders.size; i < n; i++)
|
||||
((Slider)constraints[i]).setToSetupPose();
|
||||
((Slider)constraints[i]).setupPose();
|
||||
|
||||
constraints = ikConstraints.items;
|
||||
for (int i = 0, n = ikConstraints.size; i < n; i++)
|
||||
((IkConstraint)constraints[i]).setToSetupPose();
|
||||
((IkConstraint)constraints[i]).setupPose();
|
||||
|
||||
constraints = transformConstraints.items;
|
||||
for (int i = 0, n = transformConstraints.size; i < n; i++)
|
||||
((TransformConstraint)constraints[i]).setToSetupPose();
|
||||
((TransformConstraint)constraints[i]).setupPose();
|
||||
|
||||
constraints = pathConstraints.items;
|
||||
for (int i = 0, n = pathConstraints.size; i < n; i++)
|
||||
((PathConstraint)constraints[i]).setToSetupPose();
|
||||
((PathConstraint)constraints[i]).setupPose();
|
||||
|
||||
constraints = physicsConstraints.items;
|
||||
for (int i = 0, n = physicsConstraints.size; i < n; i++)
|
||||
((PhysicsConstraint)constraints[i]).setToSetupPose();
|
||||
((PhysicsConstraint)constraints[i]).setupPose();
|
||||
}
|
||||
|
||||
/** Sets the slots and draw order to their setup pose values. */
|
||||
public void setSlotsToSetupPose () {
|
||||
public void setupPoseSlots () {
|
||||
Object[] slots = this.slots.items;
|
||||
int n = this.slots.size;
|
||||
arraycopy(slots, 0, drawOrder.items, 0, n);
|
||||
for (int i = 0; i < n; i++)
|
||||
((Slot)slots[i]).setToSetupPose();
|
||||
((Slot)slots[i]).setupPose();
|
||||
}
|
||||
|
||||
/** The skeleton's setup pose data. */
|
||||
@ -614,9 +591,8 @@ public class Skeleton {
|
||||
* old skin, each slot's setup mode attachment is attached from the new skin.
|
||||
* <p>
|
||||
* After changing the skin, the visible attachments can be reset to those attached in the setup pose by calling
|
||||
* {@link #setSlotsToSetupPose()}. Also, often {@link AnimationState#apply(Skeleton)} is called before the next time the
|
||||
* skeleton is rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new
|
||||
* skin. */
|
||||
* {@link #setupPoseSlots()}. Also, often {@link AnimationState#apply(Skeleton)} is called before the next time the skeleton is
|
||||
* rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new skin. */
|
||||
public void setSkin (@Null Skin newSkin) {
|
||||
if (newSkin == skin) return;
|
||||
if (newSkin != null) {
|
||||
@ -629,7 +605,7 @@ public class Skeleton {
|
||||
String name = slot.data.attachmentName;
|
||||
if (name != null) {
|
||||
Attachment attachment = newSkin.getAttachment(i, name);
|
||||
if (attachment != null) slot.setAttachment(attachment);
|
||||
if (attachment != null) slot.pose.setAttachment(attachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -663,7 +639,7 @@ public class Skeleton {
|
||||
}
|
||||
|
||||
/** A convenience method to set an attachment by finding the slot with {@link #findSlot(String)}, finding the attachment with
|
||||
* {@link #getAttachment(int, String)}, then setting the slot's {@link Slot#attachment}.
|
||||
* {@link #getAttachment(int, String)}, then setting the slot's {@link SlotPose#attachment}.
|
||||
* @param attachmentName May be null to clear the slot's attachment. */
|
||||
public void setAttachment (String slotName, @Null String attachmentName) {
|
||||
if (slotName == null) throw new IllegalArgumentException("slotName cannot be null.");
|
||||
@ -675,7 +651,7 @@ public class Skeleton {
|
||||
if (attachment == null)
|
||||
throw new IllegalArgumentException("Attachment not found: " + attachmentName + ", for slot: " + slotName);
|
||||
}
|
||||
slot.setAttachment(attachment);
|
||||
slot.pose.setAttachment(attachment);
|
||||
}
|
||||
|
||||
/** The skeleton's sliders. */
|
||||
@ -789,7 +765,7 @@ public class Skeleton {
|
||||
int verticesLength = 0;
|
||||
float[] vertices = null;
|
||||
short[] triangles = null;
|
||||
Attachment attachment = slot.attachment;
|
||||
Attachment attachment = slot.pose.attachment;
|
||||
if (attachment instanceof RegionAttachment region) {
|
||||
verticesLength = 8;
|
||||
vertices = temp.setSize(8);
|
||||
@ -933,19 +909,4 @@ 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 reset to the current pose. */
|
||||
reset,
|
||||
|
||||
/** Physics are updated and the pose from physics is applied. */
|
||||
update,
|
||||
|
||||
/** Physics are not updated but the pose from physics is applied. */
|
||||
pose
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ public class SkeletonBounds {
|
||||
for (int i = 0; i < slotCount; i++) {
|
||||
var slot = (Slot)slots[i];
|
||||
if (!slot.bone.active) continue;
|
||||
Attachment attachment = slot.attachment;
|
||||
Attachment attachment = slot.applied.attachment;
|
||||
if (attachment instanceof BoundingBoxAttachment boundingBox) {
|
||||
boundingBoxes.add(boundingBox);
|
||||
|
||||
|
||||
@ -80,10 +80,11 @@ public class SkeletonRenderer {
|
||||
for (int i = 0, n = skeleton.drawOrder.size; i < n; i++) {
|
||||
var slot = (Slot)drawOrder[i];
|
||||
if (!slot.bone.active) continue;
|
||||
Attachment attachment = slot.attachment;
|
||||
SlotPose pose = slot.getAppliedPose();
|
||||
Attachment attachment = pose.attachment;
|
||||
if (attachment instanceof RegionAttachment region) {
|
||||
region.computeWorldVertices(slot, vertices, 0, 5);
|
||||
Color color = region.getColor(), slotColor = slot.getColor();
|
||||
Color color = region.getColor(), slotColor = pose.getColor();
|
||||
float alpha = a * slotColor.a * color.a * 255;
|
||||
float multiplier = pmaColors ? alpha : 255;
|
||||
|
||||
@ -148,8 +149,9 @@ public class SkeletonRenderer {
|
||||
clipper.clipEnd(slot);
|
||||
continue;
|
||||
}
|
||||
SlotPose pose = slot.getAppliedPose();
|
||||
Texture texture = null;
|
||||
Attachment attachment = slot.attachment;
|
||||
Attachment attachment = pose.attachment;
|
||||
if (attachment instanceof RegionAttachment region) {
|
||||
verticesLength = 20;
|
||||
vertices = this.vertices.items;
|
||||
@ -179,7 +181,7 @@ public class SkeletonRenderer {
|
||||
}
|
||||
|
||||
if (texture != null) {
|
||||
Color slotColor = slot.getColor();
|
||||
Color slotColor = pose.getColor();
|
||||
float alpha = a * slotColor.a * color.a * 255;
|
||||
float multiplier = pmaColors ? alpha : 255;
|
||||
|
||||
@ -242,8 +244,9 @@ public class SkeletonRenderer {
|
||||
clipper.clipEnd(slot);
|
||||
continue;
|
||||
}
|
||||
SlotPose pose = slot.getAppliedPose();
|
||||
Texture texture = null;
|
||||
Attachment attachment = slot.attachment;
|
||||
Attachment attachment = pose.attachment;
|
||||
if (attachment instanceof RegionAttachment region) {
|
||||
verticesLength = 24;
|
||||
vertices = this.vertices.items;
|
||||
@ -273,7 +276,7 @@ public class SkeletonRenderer {
|
||||
}
|
||||
|
||||
if (texture != null) {
|
||||
Color lightColor = slot.getColor();
|
||||
Color lightColor = pose.getColor();
|
||||
float alpha = a * lightColor.a * color.a * 255;
|
||||
float multiplier = pmaColors ? alpha : 255;
|
||||
|
||||
@ -294,7 +297,7 @@ public class SkeletonRenderer {
|
||||
| (int)(blue * lightColor.b) << 16 //
|
||||
| (int)(green * lightColor.g) << 8 //
|
||||
| (int)(red * lightColor.r));
|
||||
Color darkColor = slot.getDarkColor();
|
||||
Color darkColor = pose.getDarkColor();
|
||||
float dark = darkColor == null ? 0
|
||||
: NumberUtils.intToFloatColor((int)(blue * darkColor.b) << 16 //
|
||||
| (int)(green * darkColor.g) << 8 //
|
||||
|
||||
@ -38,7 +38,6 @@ import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.FloatArray;
|
||||
|
||||
import com.esotericsoftware.spine.attachments.Attachment;
|
||||
import com.esotericsoftware.spine.attachments.BoundingBoxAttachment;
|
||||
import com.esotericsoftware.spine.attachments.ClippingAttachment;
|
||||
import com.esotericsoftware.spine.attachments.MeshAttachment;
|
||||
@ -109,8 +108,7 @@ public class SkeletonRendererDebug {
|
||||
for (int i = 0, n = slots.size; i < n; i++) {
|
||||
Slot slot = slots.get(i);
|
||||
if (!slot.bone.active) continue;
|
||||
Attachment attachment = slot.attachment;
|
||||
if (!(attachment instanceof PointAttachment point)) continue;
|
||||
if (!(slot.applied.attachment instanceof PointAttachment point)) continue;
|
||||
point.computeWorldPosition(slot.bone.applied, temp1);
|
||||
temp2.set(8, 0).rotate(point.computeWorldRotation(slot.bone.applied));
|
||||
shapes.rectLine(temp1, temp2, boneWidth / 2 * scale);
|
||||
@ -125,8 +123,7 @@ public class SkeletonRendererDebug {
|
||||
for (int i = 0, n = slots.size; i < n; i++) {
|
||||
Slot slot = slots.get(i);
|
||||
if (!slot.bone.active) continue;
|
||||
Attachment attachment = slot.attachment;
|
||||
if (attachment instanceof RegionAttachment region) {
|
||||
if (slot.pose.attachment instanceof RegionAttachment region) {
|
||||
float[] vertices = this.vertices.items;
|
||||
region.computeWorldVertices(slot, vertices, 0, 2);
|
||||
shapes.line(vertices[0], vertices[1], vertices[2], vertices[3]);
|
||||
@ -141,8 +138,7 @@ public class SkeletonRendererDebug {
|
||||
for (int i = 0, n = slots.size; i < n; i++) {
|
||||
Slot slot = slots.get(i);
|
||||
if (!slot.bone.active) continue;
|
||||
Attachment attachment = slot.attachment;
|
||||
if (!(attachment instanceof MeshAttachment mesh)) continue;
|
||||
if (!(slot.pose.attachment instanceof MeshAttachment mesh)) continue;
|
||||
float[] vertices = this.vertices.setSize(mesh.getWorldVerticesLength());
|
||||
mesh.computeWorldVertices(slot, 0, mesh.getWorldVerticesLength(), vertices, 0, 2);
|
||||
short[] triangles = mesh.getTriangles();
|
||||
@ -188,8 +184,7 @@ public class SkeletonRendererDebug {
|
||||
for (int i = 0, n = slots.size; i < n; i++) {
|
||||
Slot slot = slots.get(i);
|
||||
if (!slot.bone.active) continue;
|
||||
Attachment attachment = slot.attachment;
|
||||
if (!(attachment instanceof ClippingAttachment clip)) continue;
|
||||
if (!(slot.pose.attachment instanceof ClippingAttachment clip)) continue;
|
||||
int nn = clip.getWorldVerticesLength();
|
||||
float[] vertices = this.vertices.setSize(nn);
|
||||
clip.computeWorldVertices(slot, 0, nn, vertices, 0, 2);
|
||||
@ -204,8 +199,7 @@ public class SkeletonRendererDebug {
|
||||
for (int i = 0, n = slots.size; i < n; i++) {
|
||||
Slot slot = slots.get(i);
|
||||
if (!slot.bone.active) continue;
|
||||
Attachment attachment = slot.attachment;
|
||||
if (!(attachment instanceof PathAttachment path)) continue;
|
||||
if (!(slot.pose.attachment instanceof PathAttachment path)) continue;
|
||||
int nn = path.getWorldVerticesLength();
|
||||
float[] vertices = this.vertices.setSize(nn);
|
||||
path.computeWorldVertices(slot, 0, nn, vertices, 0, 2);
|
||||
@ -254,15 +248,13 @@ public class SkeletonRendererDebug {
|
||||
for (int i = 0, n = slots.size; i < n; i++) {
|
||||
Slot slot = slots.get(i);
|
||||
if (!slot.bone.active) continue;
|
||||
Attachment attachment = slot.attachment;
|
||||
if (!(attachment instanceof PointAttachment point)) continue;
|
||||
if (!(slot.pose.attachment instanceof PointAttachment point)) continue;
|
||||
point.computeWorldPosition(slot.bone.applied, temp1);
|
||||
shapes.circle(temp1.x, temp1.y, 3 * scale, 8);
|
||||
}
|
||||
}
|
||||
|
||||
shapes.end();
|
||||
|
||||
}
|
||||
|
||||
public ShapeRenderer getShapeRenderer () {
|
||||
|
||||
@ -157,7 +157,7 @@ public class Skin {
|
||||
Object[] slots = skeleton.slots.items;
|
||||
for (SkinEntry entry : oldSkin.attachments.orderedItems()) {
|
||||
int slotIndex = entry.slotIndex;
|
||||
var slot = (Slot)slots[slotIndex];
|
||||
SlotPose slot = ((Slot)slots[slotIndex]).getPose();
|
||||
if (slot.attachment == entry.attachment) {
|
||||
Attachment attachment = getAttachment(slotIndex, entry.name);
|
||||
if (attachment != null) slot.setAttachment(attachment);
|
||||
|
||||
@ -31,7 +31,6 @@ package com.esotericsoftware.spine;
|
||||
|
||||
import com.esotericsoftware.spine.Animation.MixBlend;
|
||||
import com.esotericsoftware.spine.Animation.MixDirection;
|
||||
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||
|
||||
/** Stores the setup pose for a {@link PhysicsConstraint}.
|
||||
* <p>
|
||||
@ -50,20 +49,20 @@ public class Slider implements Updatable {
|
||||
this.data = data;
|
||||
this.skeleton = skeleton;
|
||||
|
||||
setToSetupPose();
|
||||
setupPose();
|
||||
}
|
||||
|
||||
/** Copy constructor. */
|
||||
public Slider (Slider slider, Skeleton skeleton) {
|
||||
this(slider.data, skeleton);
|
||||
setToSetupPose();
|
||||
setupPose();
|
||||
}
|
||||
|
||||
public void update (Physics physics) {
|
||||
animation.apply(skeleton, time, time, false, null, mix, MixBlend.replace, MixDirection.in, true);
|
||||
}
|
||||
|
||||
public void setToSetupPose () {
|
||||
public void setupPose () {
|
||||
SliderData data = this.data;
|
||||
animation = data.animation;
|
||||
time = data.time;
|
||||
@ -71,7 +70,7 @@ public class Slider implements Updatable {
|
||||
}
|
||||
|
||||
/** Returns false when this constraint won't be updated by
|
||||
* {@link Skeleton#updateWorldTransform(com.esotericsoftware.spine.Skeleton.Physics)} because a skin is required and the
|
||||
* {@link Skeleton#updateWorldTransform(com.esotericsoftware.spine.Physics)} because a skin is required and the
|
||||
* {@link Skeleton#getSkin() active skin} does not contain this item.
|
||||
* @see Skin#getBones()
|
||||
* @see Skin#getConstraints()
|
||||
|
||||
@ -30,13 +30,6 @@
|
||||
package com.esotericsoftware.spine;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.utils.FloatArray;
|
||||
import com.badlogic.gdx.utils.Null;
|
||||
|
||||
import com.esotericsoftware.spine.Animation.DeformTimeline;
|
||||
import com.esotericsoftware.spine.attachments.Attachment;
|
||||
import com.esotericsoftware.spine.attachments.Sequence;
|
||||
import com.esotericsoftware.spine.attachments.VertexAttachment;
|
||||
|
||||
/** Stores a slot's current pose. Slots organize attachments for {@link Skeleton#drawOrder} purposes and provide a place to store
|
||||
* state for an attachment. State cannot be stored in an attachment itself because attachments are stateless and may be shared
|
||||
@ -44,35 +37,19 @@ import com.esotericsoftware.spine.attachments.VertexAttachment;
|
||||
public class Slot {
|
||||
final SlotData data;
|
||||
final Bone bone;
|
||||
Slot applied;
|
||||
|
||||
final Color color = new Color();
|
||||
@Null final Color darkColor;
|
||||
@Null Attachment attachment;
|
||||
int sequenceIndex;
|
||||
FloatArray deform;
|
||||
|
||||
final SlotPose pose = new SlotPose(), applied = new SlotPose();
|
||||
int attachmentState;
|
||||
|
||||
private Slot (SlotData data, Bone bone) {
|
||||
this.data = data;
|
||||
this.bone = bone;
|
||||
|
||||
darkColor = data.darkColor == null ? null : new Color();
|
||||
}
|
||||
|
||||
public Slot (SlotData data, Skeleton skeleton) {
|
||||
if (data == null) throw new IllegalArgumentException("data cannot be null.");
|
||||
if (data == null) throw new IllegalArgumentException("slot cannot be null.");
|
||||
if (skeleton == null) throw new IllegalArgumentException("skeleton cannot be null.");
|
||||
this.data = data;
|
||||
this.bone = skeleton.bones.get(data.boneData.index);
|
||||
|
||||
darkColor = data.darkColor == null ? null : new Color();
|
||||
deform = new FloatArray();
|
||||
|
||||
applied = new Slot(data, bone);
|
||||
|
||||
setToSetupPose();
|
||||
bone = skeleton.bones.get(data.boneData.index);
|
||||
if (data.darkColor != null) {
|
||||
pose.darkColor = new Color();
|
||||
applied.darkColor = new Color();
|
||||
}
|
||||
setupPose();
|
||||
}
|
||||
|
||||
/** Copy constructor. */
|
||||
@ -81,11 +58,17 @@ public class Slot {
|
||||
if (bone == null) throw new IllegalArgumentException("bone cannot be null.");
|
||||
data = slot.data;
|
||||
this.bone = bone;
|
||||
color.set(slot.color);
|
||||
darkColor = slot.darkColor == null ? null : new Color(slot.darkColor);
|
||||
attachment = slot.attachment;
|
||||
sequenceIndex = slot.sequenceIndex;
|
||||
deform = new FloatArray(slot.deform);
|
||||
if (data.darkColor != null) {
|
||||
pose.darkColor = new Color();
|
||||
applied.darkColor = new Color();
|
||||
}
|
||||
pose.set(slot.pose);
|
||||
}
|
||||
|
||||
/** Sets this slot to the setup pose. */
|
||||
public void setupPose () {
|
||||
pose.set(data);
|
||||
if (data.attachmentName != null) pose.setAttachment(bone.skeleton.getAttachment(data.index, data.attachmentName));
|
||||
}
|
||||
|
||||
/** The slot's setup pose data. */
|
||||
@ -93,6 +76,16 @@ public class Slot {
|
||||
return data;
|
||||
}
|
||||
|
||||
/** Returns the slot's pose. */
|
||||
public SlotPose getPose () {
|
||||
return pose;
|
||||
}
|
||||
|
||||
/** Returns the slot's applied pose. */
|
||||
public SlotPose getAppliedPose () {
|
||||
return applied;
|
||||
}
|
||||
|
||||
/** The bone this slot belongs to. */
|
||||
public Bone getBone () {
|
||||
return bone;
|
||||
@ -103,76 +96,6 @@ public class Slot {
|
||||
return bone.skeleton;
|
||||
}
|
||||
|
||||
/** The color used to tint the slot's attachment. If {@link #getDarkColor()} is set, this is used as the light color for two
|
||||
* color tinting. */
|
||||
public Color getColor () {
|
||||
return color;
|
||||
}
|
||||
|
||||
/** The dark color used to tint the slot's attachment for two color tinting, or null if two color tinting is not used. The dark
|
||||
* color's alpha is not used. */
|
||||
public @Null Color getDarkColor () {
|
||||
return darkColor;
|
||||
}
|
||||
|
||||
/** The current attachment for the slot, or null if the slot has no attachment. */
|
||||
public @Null Attachment getAttachment () {
|
||||
return attachment;
|
||||
}
|
||||
|
||||
/** Sets the slot's attachment and, if the attachment changed, resets {@link #sequenceIndex} and clears the {@link #deform}.
|
||||
* The deform is not cleared if the old attachment has the same {@link VertexAttachment#getTimelineAttachment()} as the
|
||||
* specified attachment. */
|
||||
public void setAttachment (@Null Attachment attachment) {
|
||||
if (this.attachment == attachment) return;
|
||||
if (!(attachment instanceof VertexAttachment newAttachment) || !(this.attachment instanceof VertexAttachment oldAttachment)
|
||||
|| newAttachment.getTimelineAttachment() != oldAttachment.getTimelineAttachment()) {
|
||||
deform.clear();
|
||||
}
|
||||
this.attachment = attachment;
|
||||
sequenceIndex = -1;
|
||||
}
|
||||
|
||||
/** The index of the texture region to display when the slot's attachment has a {@link Sequence}. -1 represents the
|
||||
* {@link Sequence#getSetupIndex()}. */
|
||||
public int getSequenceIndex () {
|
||||
return sequenceIndex;
|
||||
}
|
||||
|
||||
public void setSequenceIndex (int sequenceIndex) {
|
||||
this.sequenceIndex = sequenceIndex;
|
||||
}
|
||||
|
||||
/** Values to deform the slot's attachment. For an unweighted mesh, the entries are local positions for each vertex. For a
|
||||
* weighted mesh, the entries are an offset for each vertex which will be added to the mesh's local vertex positions.
|
||||
* <p>
|
||||
* See {@link VertexAttachment#computeWorldVertices(Slot, int, int, float[], int, int)} and {@link DeformTimeline}. */
|
||||
public FloatArray getDeform () {
|
||||
return deform;
|
||||
}
|
||||
|
||||
public void setDeform (FloatArray deform) {
|
||||
if (deform == null) throw new IllegalArgumentException("deform cannot be null.");
|
||||
this.deform = deform;
|
||||
}
|
||||
|
||||
/** Sets this slot to the setup pose. */
|
||||
public void setToSetupPose () {
|
||||
color.set(data.color);
|
||||
if (darkColor != null) darkColor.set(data.darkColor);
|
||||
if (data.attachmentName == null)
|
||||
setAttachment(null);
|
||||
else {
|
||||
attachment = null;
|
||||
setAttachment(bone.skeleton.getAttachment(data.index, data.attachmentName));
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the bone for applied pose. */
|
||||
public Slot getApplied () {
|
||||
return applied;
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
return data.name;
|
||||
}
|
||||
|
||||
@ -33,12 +33,10 @@ import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.utils.Null;
|
||||
|
||||
/** Stores the setup pose for a {@link Slot}. */
|
||||
public class SlotData {
|
||||
public class SlotData extends SlotPose {
|
||||
final int index;
|
||||
final String name;
|
||||
final BoneData boneData;
|
||||
final Color color = new Color(1, 1, 1, 1);
|
||||
@Null Color darkColor;
|
||||
@Null String attachmentName;
|
||||
BlendMode blendMode;
|
||||
|
||||
|
||||
@ -0,0 +1,111 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, 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.graphics.Color;
|
||||
import com.badlogic.gdx.utils.FloatArray;
|
||||
import com.badlogic.gdx.utils.Null;
|
||||
|
||||
import com.esotericsoftware.spine.Animation.DeformTimeline;
|
||||
import com.esotericsoftware.spine.attachments.Attachment;
|
||||
import com.esotericsoftware.spine.attachments.Sequence;
|
||||
import com.esotericsoftware.spine.attachments.VertexAttachment;
|
||||
|
||||
/** Stores a slot's pose. Slots organize attachments for {@link Skeleton#drawOrder} purposes and provide a place to store state
|
||||
* for an attachment. State cannot be stored in an attachment itself because attachments are stateless and may be shared across
|
||||
* multiple skeletons. */
|
||||
public class SlotPose {
|
||||
final Color color = new Color();
|
||||
@Null Color darkColor;
|
||||
@Null Attachment attachment;
|
||||
int sequenceIndex;
|
||||
final FloatArray deform = new FloatArray(0);
|
||||
|
||||
SlotPose () {
|
||||
}
|
||||
|
||||
public void set (SlotPose slot) {
|
||||
if (slot == null) throw new IllegalArgumentException("slot cannot be null.");
|
||||
color.set(slot.color);
|
||||
if (slot.darkColor != null) darkColor.set(slot.darkColor);
|
||||
attachment = slot.attachment;
|
||||
sequenceIndex = slot.sequenceIndex;
|
||||
deform.size = 0;
|
||||
deform.addAll(slot.deform);
|
||||
}
|
||||
|
||||
/** The color used to tint the slot's attachment. If {@link #getDarkColor()} is set, this is used as the light color for two
|
||||
* color tinting. */
|
||||
public Color getColor () {
|
||||
return color;
|
||||
}
|
||||
|
||||
/** The dark color used to tint the slot's attachment for two color tinting, or null if two color tinting is not used. The dark
|
||||
* color's alpha is not used. */
|
||||
public @Null Color getDarkColor () {
|
||||
return darkColor;
|
||||
}
|
||||
|
||||
/** The current attachment for the slot, or null if the slot has no attachment. */
|
||||
public @Null Attachment getAttachment () {
|
||||
return attachment;
|
||||
}
|
||||
|
||||
/** Sets the slot's attachment and, if the attachment changed, resets {@link #sequenceIndex} and clears the {@link #deform}.
|
||||
* The deform is not cleared if the old attachment has the same {@link VertexAttachment#getTimelineAttachment()} as the
|
||||
* specified attachment. */
|
||||
public void setAttachment (@Null Attachment attachment) {
|
||||
if (this.attachment == attachment) return;
|
||||
if (!(attachment instanceof VertexAttachment newAttachment) || !(this.attachment instanceof VertexAttachment oldAttachment)
|
||||
|| newAttachment.getTimelineAttachment() != oldAttachment.getTimelineAttachment()) {
|
||||
deform.clear();
|
||||
}
|
||||
this.attachment = attachment;
|
||||
sequenceIndex = -1;
|
||||
}
|
||||
|
||||
/** The index of the texture region to display when the slot's attachment has a {@link Sequence}. -1 represents the
|
||||
* {@link Sequence#getSetupIndex()}. */
|
||||
public int getSequenceIndex () {
|
||||
return sequenceIndex;
|
||||
}
|
||||
|
||||
public void setSequenceIndex (int sequenceIndex) {
|
||||
this.sequenceIndex = sequenceIndex;
|
||||
}
|
||||
|
||||
/** Values to deform the slot's attachment. For an unweighted mesh, the entries are local positions for each vertex. For a
|
||||
* weighted mesh, the entries are an offset for each vertex which will be added to the mesh's local vertex positions.
|
||||
* <p>
|
||||
* See {@link VertexAttachment#computeWorldVertices(Slot, int, int, float[], int, int)} and {@link DeformTimeline}. */
|
||||
public FloatArray getDeform () {
|
||||
return deform;
|
||||
}
|
||||
}
|
||||
@ -32,9 +32,7 @@ package com.esotericsoftware.spine;
|
||||
import static com.badlogic.gdx.math.MathUtils.*;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Null;
|
||||
|
||||
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||
import com.esotericsoftware.spine.TransformConstraintData.FromProperty;
|
||||
import com.esotericsoftware.spine.TransformConstraintData.ToProperty;
|
||||
|
||||
@ -70,16 +68,16 @@ public class TransformConstraint implements Updatable {
|
||||
|
||||
applied = new TransformConstraint(data, bones, source);
|
||||
|
||||
setToSetupPose();
|
||||
setupPose();
|
||||
}
|
||||
|
||||
/** Copy constructor. */
|
||||
public TransformConstraint (TransformConstraint constraint, Skeleton skeleton) {
|
||||
this(constraint.data, skeleton);
|
||||
setToSetupPose();
|
||||
setupPose();
|
||||
}
|
||||
|
||||
public void setToSetupPose () {
|
||||
public void setupPose () {
|
||||
TransformConstraintData data = this.data;
|
||||
mixRotate = data.mixRotate;
|
||||
mixX = data.mixX;
|
||||
@ -196,7 +194,7 @@ public class TransformConstraint implements Updatable {
|
||||
}
|
||||
|
||||
/** Returns false when this constraint won't be updated by
|
||||
* {@link Skeleton#updateWorldTransform(com.esotericsoftware.spine.Skeleton.Physics)} because a skin is required and the
|
||||
* {@link Skeleton#updateWorldTransform(com.esotericsoftware.spine.Physics)} because a skin is required and the
|
||||
* {@link Skeleton#getSkin() active skin} does not contain this item.
|
||||
* @see Skin#getBones()
|
||||
* @see Skin#getConstraints()
|
||||
|
||||
@ -29,8 +29,6 @@
|
||||
|
||||
package com.esotericsoftware.spine;
|
||||
|
||||
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||
|
||||
/** The interface for items updated by {@link Skeleton#updateWorldTransform(Physics)}. */
|
||||
public interface Updatable {
|
||||
/** @param physics Determines how physics and other non-deterministic updates are applied. */
|
||||
|
||||
@ -165,7 +165,7 @@ public class MeshAttachment extends VertexAttachment implements HasTextureRegion
|
||||
|
||||
/** If the attachment has a {@link #sequence}, the region may be changed. */
|
||||
public void computeWorldVertices (Slot slot, int start, int count, float[] worldVertices, int offset, int stride) {
|
||||
if (sequence != null) sequence.apply(slot, this);
|
||||
if (sequence != null) sequence.apply(slot.getAppliedPose(), this);
|
||||
super.computeWorldVertices(slot, start, count, worldVertices, offset, stride);
|
||||
}
|
||||
|
||||
|
||||
@ -36,7 +36,6 @@ import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.utils.Null;
|
||||
|
||||
import com.esotericsoftware.spine.BonePose;
|
||||
import com.esotericsoftware.spine.BoneApplied;
|
||||
import com.esotericsoftware.spine.Slot;
|
||||
|
||||
@ -177,10 +176,10 @@ public class RegionAttachment extends Attachment implements HasTextureRegion {
|
||||
* @param offset The <code>worldVertices</code> index to begin writing values.
|
||||
* @param stride The number of <code>worldVertices</code> entries between the value pairs written. */
|
||||
public void computeWorldVertices (Slot slot, float[] worldVertices, int offset, int stride) {
|
||||
if (sequence != null) sequence.apply(slot, this);
|
||||
if (sequence != null) sequence.apply(slot.getAppliedPose(), this);
|
||||
|
||||
float[] vertexOffset = this.offset;
|
||||
BoneApplied bone = slot.getBone().getApplied();
|
||||
BoneApplied bone = slot.getBone().getAppliedPose();
|
||||
float x = bone.getWorldX(), y = bone.getWorldY();
|
||||
float a = bone.getA(), b = bone.getB(), c = bone.getC(), d = bone.getD();
|
||||
float offsetX, offsetY;
|
||||
|
||||
@ -33,7 +33,7 @@ import static com.esotericsoftware.spine.utils.SpineUtils.*;
|
||||
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
|
||||
import com.esotericsoftware.spine.Slot;
|
||||
import com.esotericsoftware.spine.SlotPose;
|
||||
|
||||
public class Sequence {
|
||||
static private int nextID;
|
||||
@ -56,7 +56,7 @@ public class Sequence {
|
||||
setupIndex = other.setupIndex;
|
||||
}
|
||||
|
||||
public void apply (Slot slot, HasTextureRegion attachment) {
|
||||
public void apply (SlotPose slot, HasTextureRegion attachment) {
|
||||
int index = slot.getSequenceIndex();
|
||||
if (index == -1) index = setupIndex;
|
||||
if (index >= regions.length) index = regions.length - 1;
|
||||
|
||||
@ -34,14 +34,14 @@ import static com.esotericsoftware.spine.utils.SpineUtils.*;
|
||||
import com.badlogic.gdx.utils.FloatArray;
|
||||
import com.badlogic.gdx.utils.Null;
|
||||
|
||||
import com.esotericsoftware.spine.BonePose;
|
||||
import com.esotericsoftware.spine.BoneApplied;
|
||||
import com.esotericsoftware.spine.Bone;
|
||||
import com.esotericsoftware.spine.BoneApplied;
|
||||
import com.esotericsoftware.spine.Skeleton;
|
||||
import com.esotericsoftware.spine.Slot;
|
||||
import com.esotericsoftware.spine.SlotPose;
|
||||
|
||||
/** Base class for an attachment with vertices that are transformed by one or more bones and can be deformed by a slot's
|
||||
* {@link Slot#getDeform()}. */
|
||||
* {@link SlotPose#getDeform()}. */
|
||||
abstract public class VertexAttachment extends Attachment {
|
||||
static private int nextID;
|
||||
|
||||
@ -75,8 +75,8 @@ abstract public class VertexAttachment extends Attachment {
|
||||
worldVerticesLength = other.worldVerticesLength;
|
||||
}
|
||||
|
||||
/** Transforms the attachment's local {@link #getVertices()} to world coordinates. If the slot's {@link Slot#getDeform()} is
|
||||
* not empty, it is used to deform the vertices.
|
||||
/** Transforms the attachment's local {@link #getVertices()} to world coordinates. If the slot's {@link SlotPose#getDeform()}
|
||||
* is not empty, it is used to deform the vertices.
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
|
||||
* Runtimes Guide.
|
||||
@ -88,12 +88,12 @@ abstract public class VertexAttachment extends Attachment {
|
||||
* @param stride The number of <code>worldVertices</code> entries between the value pairs written. */
|
||||
public void computeWorldVertices (Slot slot, int start, int count, float[] worldVertices, int offset, int stride) {
|
||||
count = offset + (count >> 1) * stride;
|
||||
FloatArray deformArray = slot.getDeform();
|
||||
FloatArray deformArray = slot.getAppliedPose().getDeform();
|
||||
float[] vertices = this.vertices;
|
||||
int[] bones = this.bones;
|
||||
if (bones == null) {
|
||||
if (deformArray.size > 0) vertices = deformArray.items;
|
||||
BoneApplied bone = slot.getBone().getApplied();
|
||||
BoneApplied bone = slot.getBone().getAppliedPose();
|
||||
float x = bone.getWorldX(), y = bone.getWorldY();
|
||||
float a = bone.getA(), b = bone.getB(), c = bone.getC(), d = bone.getD();
|
||||
for (int v = start, w = offset; w < count; v += 2, w += stride) {
|
||||
@ -116,7 +116,7 @@ abstract public class VertexAttachment extends Attachment {
|
||||
int n = bones[v++];
|
||||
n += v;
|
||||
for (; v < n; v++, b += 3) {
|
||||
BoneApplied bone = ((Bone)skeletonBones[bones[v]]).getApplied();
|
||||
BoneApplied bone = ((Bone)skeletonBones[bones[v]]).getAppliedPose();
|
||||
float vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2];
|
||||
wx += (vx * bone.getA() + vy * bone.getB() + bone.getWorldX()) * weight;
|
||||
wy += (vx * bone.getC() + vy * bone.getD() + bone.getWorldY()) * weight;
|
||||
@ -131,7 +131,7 @@ abstract public class VertexAttachment extends Attachment {
|
||||
int n = bones[v++];
|
||||
n += v;
|
||||
for (; v < n; v++, b += 3, f += 2) {
|
||||
BoneApplied bone = ((Bone)skeletonBones[bones[v]]).getApplied();
|
||||
BoneApplied bone = ((Bone)skeletonBones[bones[v]]).getAppliedPose();
|
||||
float vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2];
|
||||
wx += (vx * bone.getA() + vy * bone.getB() + bone.getWorldX()) * weight;
|
||||
wy += (vx * bone.getC() + vy * bone.getD() + bone.getWorldY()) * weight;
|
||||
|
||||
@ -34,8 +34,8 @@ import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
|
||||
import com.esotericsoftware.spine.AnimationState;
|
||||
import com.esotericsoftware.spine.Physics;
|
||||
import com.esotericsoftware.spine.Skeleton;
|
||||
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||
import com.esotericsoftware.spine.SkeletonRenderer;
|
||||
|
||||
/** A scene2d actor that draws a skeleton. */
|
||||
|
||||
@ -73,7 +73,7 @@ public class SkeletonActorPool extends Pool<SkeletonActor> {
|
||||
skeleton.setScale(1, 1);
|
||||
skeleton.setSkin((Skin)null);
|
||||
skeleton.setSkin(SkeletonActorPool.this.skeletonData.getDefaultSkin());
|
||||
skeleton.setToSetupPose();
|
||||
skeleton.setupPose();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -33,8 +33,8 @@ import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.BaseDrawable;
|
||||
|
||||
import com.esotericsoftware.spine.AnimationState;
|
||||
import com.esotericsoftware.spine.Physics;
|
||||
import com.esotericsoftware.spine.Skeleton;
|
||||
import com.esotericsoftware.spine.Skeleton.Physics;
|
||||
import com.esotericsoftware.spine.SkeletonRenderer;
|
||||
|
||||
/** A scene2d drawable that draws a skeleton. The animation state and skeleton must be updated each frame, or
|
||||
|
||||
@ -52,7 +52,6 @@ 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 org.lwjgl.system.Configuration;
|
||||
|
||||
@ -260,11 +259,11 @@ public class SkeletonViewer extends ApplicationAdapter {
|
||||
skeleton.setScale(scaleX, scaleY);
|
||||
|
||||
if (ui.setupPoseButton.isChecked())
|
||||
skeleton.setToSetupPose();
|
||||
skeleton.setupPose();
|
||||
else if (ui.bonesSetupPoseButton.isChecked())
|
||||
skeleton.setBonesToSetupPose();
|
||||
skeleton.setupPoseBones();
|
||||
else if (ui.slotsSetupPoseButton.isChecked()) //
|
||||
skeleton.setSlotsToSetupPose();
|
||||
skeleton.setupPoseSlots();
|
||||
|
||||
delta = Math.min(delta, 0.032f) * ui.speedSlider.getValue();
|
||||
state.update(delta);
|
||||
|
||||
@ -370,17 +370,17 @@ class SkeletonViewerUI {
|
||||
|
||||
setupPoseButton.addListener(new ChangeListener() {
|
||||
public void changed (ChangeEvent event, Actor actor) {
|
||||
if (viewer.skeleton != null) viewer.skeleton.setToSetupPose();
|
||||
if (viewer.skeleton != null) viewer.skeleton.setupPose();
|
||||
}
|
||||
});
|
||||
bonesSetupPoseButton.addListener(new ChangeListener() {
|
||||
public void changed (ChangeEvent event, Actor actor) {
|
||||
if (viewer.skeleton != null) viewer.skeleton.setBonesToSetupPose();
|
||||
if (viewer.skeleton != null) viewer.skeleton.setupPoseBones();
|
||||
}
|
||||
});
|
||||
slotsSetupPoseButton.addListener(new ChangeListener() {
|
||||
public void changed (ChangeEvent event, Actor actor) {
|
||||
if (viewer.skeleton != null) viewer.skeleton.setSlotsToSetupPose();
|
||||
if (viewer.skeleton != null) viewer.skeleton.setupPoseSlots();
|
||||
}
|
||||
});
|
||||
|
||||
@ -547,7 +547,7 @@ class SkeletonViewerUI {
|
||||
viewer.skeleton.setSkin((Skin)null);
|
||||
else
|
||||
viewer.skeleton.setSkin(skinName);
|
||||
viewer.skeleton.setSlotsToSetupPose();
|
||||
viewer.skeleton.setupPoseSlots();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user