mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-05 14:54:53 +08:00
[libgdx] Pose classes for all the remaining constraints.
This commit is contained in:
parent
08af7407b3
commit
c8069fa852
@ -2072,9 +2072,9 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a transform constraint's {@link TransformConstraint#getMixRotate()}, {@link TransformConstraint#getMixX()},
|
||||
* {@link TransformConstraint#getMixY()}, {@link TransformConstraint#getMixScaleX()},
|
||||
* {@link TransformConstraint#getMixScaleY()}, and {@link TransformConstraint#getMixShearY()}. */
|
||||
/** Changes a transform constraint's {@link TransformConstraintPose#getMixRotate()}, {@link TransformConstraintPose#getMixX()},
|
||||
* {@link TransformConstraintPose#getMixY()}, {@link TransformConstraintPose#getMixScaleX()},
|
||||
* {@link TransformConstraintPose#getMixScaleY()}, and {@link TransformConstraintPose#getMixShearY()}. */
|
||||
static public class TransformConstraintTimeline extends CurveTimeline {
|
||||
static public final int ENTRIES = 7;
|
||||
static private final int ROTATE = 1, X = 2, Y = 3, SCALEX = 4, SCALEY = 5, SHEARY = 6;
|
||||
@ -2116,27 +2116,27 @@ public class Animation {
|
||||
|
||||
TransformConstraint constraint = skeleton.transformConstraints.get(constraintIndex);
|
||||
if (!constraint.active) return;
|
||||
if (appliedPose) constraint = constraint.applied;
|
||||
TransformConstraintPose pose = appliedPose ? constraint.applied : constraint.pose;
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) {
|
||||
TransformConstraintData data = constraint.data;
|
||||
TransformConstraintPose setup = constraint.data.setup;
|
||||
switch (blend) {
|
||||
case setup:
|
||||
constraint.mixRotate = data.mixRotate;
|
||||
constraint.mixX = data.mixX;
|
||||
constraint.mixY = data.mixY;
|
||||
constraint.mixScaleX = data.mixScaleX;
|
||||
constraint.mixScaleY = data.mixScaleY;
|
||||
constraint.mixShearY = data.mixShearY;
|
||||
pose.mixRotate = setup.mixRotate;
|
||||
pose.mixX = setup.mixX;
|
||||
pose.mixY = setup.mixY;
|
||||
pose.mixScaleX = setup.mixScaleX;
|
||||
pose.mixScaleY = setup.mixScaleY;
|
||||
pose.mixShearY = setup.mixShearY;
|
||||
return;
|
||||
case first:
|
||||
constraint.mixRotate += (data.mixRotate - constraint.mixRotate) * alpha;
|
||||
constraint.mixX += (data.mixX - constraint.mixX) * alpha;
|
||||
constraint.mixY += (data.mixY - constraint.mixY) * alpha;
|
||||
constraint.mixScaleX += (data.mixScaleX - constraint.mixScaleX) * alpha;
|
||||
constraint.mixScaleY += (data.mixScaleY - constraint.mixScaleY) * alpha;
|
||||
constraint.mixShearY += (data.mixShearY - constraint.mixShearY) * alpha;
|
||||
pose.mixRotate += (setup.mixRotate - pose.mixRotate) * alpha;
|
||||
pose.mixX += (setup.mixX - pose.mixX) * alpha;
|
||||
pose.mixY += (setup.mixY - pose.mixY) * alpha;
|
||||
pose.mixScaleX += (setup.mixScaleX - pose.mixScaleX) * alpha;
|
||||
pose.mixScaleY += (setup.mixScaleY - pose.mixScaleY) * alpha;
|
||||
pose.mixShearY += (setup.mixShearY - pose.mixShearY) * alpha;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -2178,25 +2178,25 @@ public class Animation {
|
||||
}
|
||||
|
||||
if (blend == setup) {
|
||||
TransformConstraintData data = constraint.data;
|
||||
constraint.mixRotate = data.mixRotate + (rotate - data.mixRotate) * alpha;
|
||||
constraint.mixX = data.mixX + (x - data.mixX) * alpha;
|
||||
constraint.mixY = data.mixY + (y - data.mixY) * alpha;
|
||||
constraint.mixScaleX = data.mixScaleX + (scaleX - data.mixScaleX) * alpha;
|
||||
constraint.mixScaleY = data.mixScaleY + (scaleY - data.mixScaleY) * alpha;
|
||||
constraint.mixShearY = data.mixShearY + (shearY - data.mixShearY) * alpha;
|
||||
TransformConstraintPose setup = constraint.data.setup;
|
||||
pose.mixRotate = setup.mixRotate + (rotate - setup.mixRotate) * alpha;
|
||||
pose.mixX = setup.mixX + (x - setup.mixX) * alpha;
|
||||
pose.mixY = setup.mixY + (y - setup.mixY) * alpha;
|
||||
pose.mixScaleX = setup.mixScaleX + (scaleX - setup.mixScaleX) * alpha;
|
||||
pose.mixScaleY = setup.mixScaleY + (scaleY - setup.mixScaleY) * alpha;
|
||||
pose.mixShearY = setup.mixShearY + (shearY - setup.mixShearY) * alpha;
|
||||
} else {
|
||||
constraint.mixRotate += (rotate - constraint.mixRotate) * alpha;
|
||||
constraint.mixX += (x - constraint.mixX) * alpha;
|
||||
constraint.mixY += (y - constraint.mixY) * alpha;
|
||||
constraint.mixScaleX += (scaleX - constraint.mixScaleX) * alpha;
|
||||
constraint.mixScaleY += (scaleY - constraint.mixScaleY) * alpha;
|
||||
constraint.mixShearY += (shearY - constraint.mixShearY) * alpha;
|
||||
pose.mixRotate += (rotate - pose.mixRotate) * alpha;
|
||||
pose.mixX += (x - pose.mixX) * alpha;
|
||||
pose.mixY += (y - pose.mixY) * alpha;
|
||||
pose.mixScaleX += (scaleX - pose.mixScaleX) * alpha;
|
||||
pose.mixScaleY += (scaleY - pose.mixScaleY) * alpha;
|
||||
pose.mixShearY += (shearY - pose.mixShearY) * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a path constraint's {@link PathConstraint#getPosition()}. */
|
||||
/** Changes a path constraint's {@link PathConstraintPose#getPosition()}. */
|
||||
static public class PathConstraintPositionTimeline extends CurveTimeline1 {
|
||||
final int constraintIndex;
|
||||
|
||||
@ -2216,13 +2216,13 @@ public class Animation {
|
||||
|
||||
PathConstraint constraint = skeleton.pathConstraints.get(constraintIndex);
|
||||
if (constraint.active) {
|
||||
if (appliedPose) constraint = constraint.applied;
|
||||
constraint.position = getAbsoluteValue(time, alpha, blend, constraint.position, constraint.data.position);
|
||||
PathConstraintPose pose = appliedPose ? constraint.applied : constraint.pose;
|
||||
pose.position = getAbsoluteValue(time, alpha, blend, pose.position, constraint.data.setup.position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a path constraint's {@link PathConstraint#getSpacing()}. */
|
||||
/** Changes a path constraint's {@link PathConstraintPose#getSpacing()}. */
|
||||
static public class PathConstraintSpacingTimeline extends CurveTimeline1 {
|
||||
final int constraintIndex;
|
||||
|
||||
@ -2242,14 +2242,14 @@ public class Animation {
|
||||
|
||||
PathConstraint constraint = skeleton.pathConstraints.get(constraintIndex);
|
||||
if (constraint.active) {
|
||||
if (appliedPose) constraint = constraint.applied;
|
||||
constraint.spacing = getAbsoluteValue(time, alpha, blend, constraint.spacing, constraint.data.spacing);
|
||||
PathConstraintPose pose = appliedPose ? constraint.applied : constraint.pose;
|
||||
pose.spacing = getAbsoluteValue(time, alpha, blend, pose.spacing, constraint.data.setup.spacing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a path constraint's {@link PathConstraint#getMixRotate()}, {@link PathConstraint#getMixX()}, and
|
||||
* {@link PathConstraint#getMixY()}. */
|
||||
/** Changes a path constraint's {@link PathConstraintPose#getMixRotate()}, {@link PathConstraintPose#getMixX()}, and
|
||||
* {@link PathConstraintPose#getMixY()}. */
|
||||
static public class PathConstraintMixTimeline extends CurveTimeline {
|
||||
static public final int ENTRIES = 4;
|
||||
static private final int ROTATE = 1, X = 2, Y = 3;
|
||||
@ -2287,21 +2287,21 @@ public class Animation {
|
||||
|
||||
PathConstraint constraint = skeleton.pathConstraints.get(constraintIndex);
|
||||
if (!constraint.active) return;
|
||||
if (appliedPose) constraint = constraint.applied;
|
||||
PathConstraintPose pose = appliedPose ? constraint.applied : constraint.pose;
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) {
|
||||
PathConstraintData data = constraint.data;
|
||||
PathConstraintPose setup = constraint.data.setup;
|
||||
switch (blend) {
|
||||
case setup:
|
||||
constraint.mixRotate = data.mixRotate;
|
||||
constraint.mixX = data.mixX;
|
||||
constraint.mixY = data.mixY;
|
||||
pose.mixRotate = setup.mixRotate;
|
||||
pose.mixX = setup.mixX;
|
||||
pose.mixY = setup.mixY;
|
||||
return;
|
||||
case first:
|
||||
constraint.mixRotate += (data.mixRotate - constraint.mixRotate) * alpha;
|
||||
constraint.mixX += (data.mixX - constraint.mixX) * alpha;
|
||||
constraint.mixY += (data.mixY - constraint.mixY) * alpha;
|
||||
pose.mixRotate += (setup.mixRotate - pose.mixRotate) * alpha;
|
||||
pose.mixX += (setup.mixX - pose.mixX) * alpha;
|
||||
pose.mixY += (setup.mixY - pose.mixY) * alpha;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -2331,14 +2331,14 @@ public class Animation {
|
||||
}
|
||||
|
||||
if (blend == setup) {
|
||||
PathConstraintData data = constraint.data;
|
||||
constraint.mixRotate = data.mixRotate + (rotate - data.mixRotate) * alpha;
|
||||
constraint.mixX = data.mixX + (x - data.mixX) * alpha;
|
||||
constraint.mixY = data.mixY + (y - data.mixY) * alpha;
|
||||
PathConstraintPose setup = constraint.data.setup;
|
||||
pose.mixRotate = setup.mixRotate + (rotate - setup.mixRotate) * alpha;
|
||||
pose.mixX = setup.mixX + (x - setup.mixX) * alpha;
|
||||
pose.mixY = setup.mixY + (y - setup.mixY) * alpha;
|
||||
} else {
|
||||
constraint.mixRotate += (rotate - constraint.mixRotate) * alpha;
|
||||
constraint.mixX += (x - constraint.mixX) * alpha;
|
||||
constraint.mixY += (y - constraint.mixY) * alpha;
|
||||
pose.mixRotate += (rotate - pose.mixRotate) * alpha;
|
||||
pose.mixX += (x - pose.mixX) * alpha;
|
||||
pose.mixY += (y - pose.mixY) * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2370,44 +2370,38 @@ public class Animation {
|
||||
for (int i = 0, n = skeleton.physicsConstraints.size; i < n; i++) {
|
||||
constraint = (PhysicsConstraint)constraints[i];
|
||||
if (constraint.active && global(constraint.data)) {
|
||||
if (appliedPose) constraint = constraint.applied;
|
||||
set(constraint, getAbsoluteValue(time, alpha, blend, get(constraint), setup(constraint), value));
|
||||
PhysicsConstraintPose pose = appliedPose ? constraint.applied : constraint.pose;
|
||||
set(pose, getAbsoluteValue(time, alpha, blend, get(pose), get(constraint.data.setup), value));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
constraint = skeleton.physicsConstraints.get(constraintIndex);
|
||||
if (constraint.active) {
|
||||
if (appliedPose) constraint = constraint.applied;
|
||||
set(constraint, getAbsoluteValue(time, alpha, blend, get(constraint), setup(constraint)));
|
||||
PhysicsConstraintPose pose = appliedPose ? constraint.applied : constraint.pose;
|
||||
set(pose, getAbsoluteValue(time, alpha, blend, get(pose), get(constraint.data.setup)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract protected float setup (PhysicsConstraint constraint);
|
||||
abstract protected float get (PhysicsConstraintPose pose);
|
||||
|
||||
abstract protected float get (PhysicsConstraint constraint);
|
||||
|
||||
abstract protected void set (PhysicsConstraint constraint, float value);
|
||||
abstract protected void set (PhysicsConstraintPose pose, float value);
|
||||
|
||||
abstract protected boolean global (PhysicsConstraintData constraint);
|
||||
}
|
||||
|
||||
/** Changes a physics constraint's {@link PhysicsConstraint#getInertia()}. */
|
||||
/** Changes a physics constraint's {@link PhysicsConstraintPose#getInertia()}. */
|
||||
static public class PhysicsConstraintInertiaTimeline extends PhysicsConstraintTimeline {
|
||||
public PhysicsConstraintInertiaTimeline (int frameCount, int bezierCount, int physicsConstraintIndex) {
|
||||
super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintInertia);
|
||||
}
|
||||
|
||||
protected float setup (PhysicsConstraint constraint) {
|
||||
return constraint.data.inertia;
|
||||
protected float get (PhysicsConstraintPose pose) {
|
||||
return pose.inertia;
|
||||
}
|
||||
|
||||
protected float get (PhysicsConstraint constraint) {
|
||||
return constraint.inertia;
|
||||
}
|
||||
|
||||
protected void set (PhysicsConstraint constraint, float value) {
|
||||
constraint.inertia = value;
|
||||
protected void set (PhysicsConstraintPose pose, float value) {
|
||||
pose.inertia = value;
|
||||
}
|
||||
|
||||
protected boolean global (PhysicsConstraintData constraint) {
|
||||
@ -2415,22 +2409,18 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a physics constraint's {@link PhysicsConstraint#getStrength()}. */
|
||||
/** Changes a physics constraint's {@link PhysicsConstraintPose#getStrength()}. */
|
||||
static public class PhysicsConstraintStrengthTimeline extends PhysicsConstraintTimeline {
|
||||
public PhysicsConstraintStrengthTimeline (int frameCount, int bezierCount, int physicsConstraintIndex) {
|
||||
super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintStrength);
|
||||
}
|
||||
|
||||
protected float setup (PhysicsConstraint constraint) {
|
||||
return constraint.data.strength;
|
||||
protected float get (PhysicsConstraintPose pose) {
|
||||
return pose.strength;
|
||||
}
|
||||
|
||||
protected float get (PhysicsConstraint constraint) {
|
||||
return constraint.strength;
|
||||
}
|
||||
|
||||
protected void set (PhysicsConstraint constraint, float value) {
|
||||
constraint.strength = value;
|
||||
protected void set (PhysicsConstraintPose pose, float value) {
|
||||
pose.strength = value;
|
||||
}
|
||||
|
||||
protected boolean global (PhysicsConstraintData constraint) {
|
||||
@ -2438,22 +2428,18 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a physics constraint's {@link PhysicsConstraint#getDamping()}. */
|
||||
/** Changes a physics constraint's {@link PhysicsConstraintPose#getDamping()}. */
|
||||
static public class PhysicsConstraintDampingTimeline extends PhysicsConstraintTimeline {
|
||||
public PhysicsConstraintDampingTimeline (int frameCount, int bezierCount, int physicsConstraintIndex) {
|
||||
super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintDamping);
|
||||
}
|
||||
|
||||
protected float setup (PhysicsConstraint constraint) {
|
||||
return constraint.data.damping;
|
||||
protected float get (PhysicsConstraintPose pose) {
|
||||
return pose.damping;
|
||||
}
|
||||
|
||||
protected float get (PhysicsConstraint constraint) {
|
||||
return constraint.damping;
|
||||
}
|
||||
|
||||
protected void set (PhysicsConstraint constraint, float value) {
|
||||
constraint.damping = value;
|
||||
protected void set (PhysicsConstraintPose pose, float value) {
|
||||
pose.damping = value;
|
||||
}
|
||||
|
||||
protected boolean global (PhysicsConstraintData constraint) {
|
||||
@ -2461,22 +2447,18 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a physics constraint's {@link PhysicsConstraint#getMassInverse()}. The timeline values are not inverted. */
|
||||
/** Changes a physics constraint's {@link PhysicsConstraintPose#getMassInverse()}. The timeline values are not inverted. */
|
||||
static public class PhysicsConstraintMassTimeline extends PhysicsConstraintTimeline {
|
||||
public PhysicsConstraintMassTimeline (int frameCount, int bezierCount, int physicsConstraintIndex) {
|
||||
super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintMass);
|
||||
}
|
||||
|
||||
protected float setup (PhysicsConstraint constraint) {
|
||||
return 1 / constraint.data.massInverse;
|
||||
protected float get (PhysicsConstraintPose pose) {
|
||||
return 1 / pose.massInverse;
|
||||
}
|
||||
|
||||
protected float get (PhysicsConstraint constraint) {
|
||||
return 1 / constraint.massInverse;
|
||||
}
|
||||
|
||||
protected void set (PhysicsConstraint constraint, float value) {
|
||||
constraint.massInverse = 1 / value;
|
||||
protected void set (PhysicsConstraintPose pose, float value) {
|
||||
pose.massInverse = 1 / value;
|
||||
}
|
||||
|
||||
protected boolean global (PhysicsConstraintData constraint) {
|
||||
@ -2484,22 +2466,18 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a physics constraint's {@link PhysicsConstraint#getWind()}. */
|
||||
/** Changes a physics constraint's {@link PhysicsConstraintPose#getWind()}. */
|
||||
static public class PhysicsConstraintWindTimeline extends PhysicsConstraintTimeline {
|
||||
public PhysicsConstraintWindTimeline (int frameCount, int bezierCount, int physicsConstraintIndex) {
|
||||
super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintWind);
|
||||
}
|
||||
|
||||
protected float setup (PhysicsConstraint constraint) {
|
||||
return constraint.data.wind;
|
||||
protected float get (PhysicsConstraintPose pose) {
|
||||
return pose.wind;
|
||||
}
|
||||
|
||||
protected float get (PhysicsConstraint constraint) {
|
||||
return constraint.wind;
|
||||
}
|
||||
|
||||
protected void set (PhysicsConstraint constraint, float value) {
|
||||
constraint.wind = value;
|
||||
protected void set (PhysicsConstraintPose pose, float value) {
|
||||
pose.wind = value;
|
||||
}
|
||||
|
||||
protected boolean global (PhysicsConstraintData constraint) {
|
||||
@ -2507,22 +2485,18 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a physics constraint's {@link PhysicsConstraint#getGravity()}. */
|
||||
/** Changes a physics constraint's {@link PhysicsConstraintPose#getGravity()}. */
|
||||
static public class PhysicsConstraintGravityTimeline extends PhysicsConstraintTimeline {
|
||||
public PhysicsConstraintGravityTimeline (int frameCount, int bezierCount, int physicsConstraintIndex) {
|
||||
super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintGravity);
|
||||
}
|
||||
|
||||
protected float setup (PhysicsConstraint constraint) {
|
||||
return constraint.data.gravity;
|
||||
protected float get (PhysicsConstraintPose pose) {
|
||||
return pose.gravity;
|
||||
}
|
||||
|
||||
protected float get (PhysicsConstraint constraint) {
|
||||
return constraint.gravity;
|
||||
}
|
||||
|
||||
protected void set (PhysicsConstraint constraint, float value) {
|
||||
constraint.gravity = value;
|
||||
protected void set (PhysicsConstraintPose pose, float value) {
|
||||
pose.gravity = value;
|
||||
}
|
||||
|
||||
protected boolean global (PhysicsConstraintData constraint) {
|
||||
@ -2530,22 +2504,18 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a physics constraint's {@link PhysicsConstraint#getMix()}. */
|
||||
/** Changes a physics constraint's {@link PhysicsConstraintPose#getMix()}. */
|
||||
static public class PhysicsConstraintMixTimeline extends PhysicsConstraintTimeline {
|
||||
public PhysicsConstraintMixTimeline (int frameCount, int bezierCount, int physicsConstraintIndex) {
|
||||
super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintMix);
|
||||
}
|
||||
|
||||
protected float setup (PhysicsConstraint constraint) {
|
||||
return constraint.data.mix;
|
||||
protected float get (PhysicsConstraintPose pose) {
|
||||
return pose.mix;
|
||||
}
|
||||
|
||||
protected float get (PhysicsConstraint constraint) {
|
||||
return constraint.mix;
|
||||
}
|
||||
|
||||
protected void set (PhysicsConstraint constraint, float value) {
|
||||
constraint.mix = value;
|
||||
protected void set (PhysicsConstraintPose pose, float value) {
|
||||
pose.mix = value;
|
||||
}
|
||||
|
||||
protected boolean global (PhysicsConstraintData constraint) {
|
||||
@ -2601,17 +2571,13 @@ public class Animation {
|
||||
if (time < frames[0]) return;
|
||||
|
||||
if (lastTime < frames[0] || time >= frames[search(frames, lastTime) + 1]) {
|
||||
if (constraint != null) {
|
||||
if (appliedPose) constraint = constraint.applied;
|
||||
if (constraint != null)
|
||||
constraint.reset();
|
||||
} else {
|
||||
else {
|
||||
Object[] constraints = skeleton.physicsConstraints.items;
|
||||
for (int i = 0, n = skeleton.physicsConstraints.size; i < n; i++) {
|
||||
constraint = (PhysicsConstraint)constraints[i];
|
||||
if (constraint.active) {
|
||||
if (appliedPose) constraint = constraint.applied;
|
||||
constraint.reset();
|
||||
}
|
||||
if (constraint.active) constraint.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ public class IkConstraint implements Updatable {
|
||||
/** Copy constructor. */
|
||||
public IkConstraint (IkConstraint constraint, Skeleton skeleton) {
|
||||
this(constraint.data, skeleton);
|
||||
setupPose();
|
||||
pose.set(constraint.pose);
|
||||
}
|
||||
|
||||
public void setupPose () {
|
||||
@ -72,15 +72,15 @@ public class IkConstraint implements Updatable {
|
||||
|
||||
/** Applies the constraint to the constrained bones. */
|
||||
public void update (Physics physics) {
|
||||
IkConstraintPose pose = applied;
|
||||
if (pose.mix == 0) return;
|
||||
IkConstraintPose a = applied;
|
||||
if (a.mix == 0) return;
|
||||
BoneApplied target = this.target;
|
||||
Object[] bones = this.bones.items;
|
||||
switch (this.bones.size) {
|
||||
case 1 -> apply((BoneApplied)bones[0], target.worldX, target.worldY, pose.compress, pose.stretch, data.uniform, pose.mix);
|
||||
case 1 -> apply((BoneApplied)bones[0], target.worldX, target.worldY, a.compress, a.stretch, data.uniform, a.mix);
|
||||
case 2 -> //
|
||||
apply((BoneApplied)bones[0], (BoneApplied)bones[1], target.worldX, target.worldY, pose.bendDirection, pose.stretch,
|
||||
data.uniform, pose.softness, pose.mix);
|
||||
apply((BoneApplied)bones[0], (BoneApplied)bones[1], target.worldX, target.worldY, a.bendDirection, a.stretch,
|
||||
data.uniform, a.softness, a.mix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -35,15 +35,19 @@ import com.badlogic.gdx.utils.Array;
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-ik-constraints">IK constraints</a> in the Spine User Guide. */
|
||||
public class IkConstraintData extends ConstraintData {
|
||||
final IkConstraintPose setup = new IkConstraintPose();
|
||||
final Array<BoneData> bones = new Array();
|
||||
BoneData target;
|
||||
final IkConstraintPose setup = new IkConstraintPose();
|
||||
boolean uniform;
|
||||
|
||||
public IkConstraintData (String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public IkConstraintPose getSetupPose () {
|
||||
return setup;
|
||||
}
|
||||
|
||||
/** The bones that are constrained by this IK constraint. */
|
||||
public Array<BoneData> getBones () {
|
||||
return bones;
|
||||
@ -59,10 +63,6 @@ public class IkConstraintData extends ConstraintData {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public IkConstraintPose getSetupPose () {
|
||||
return setup;
|
||||
}
|
||||
|
||||
/** When true and {@link IkConstraintPose#getCompress()} or {@link IkConstraintPose#getStretch()} is used, the bone is scaled
|
||||
* on both the X and Y axes. */
|
||||
public boolean getUniform () {
|
||||
|
||||
@ -52,11 +52,9 @@ public class PathConstraint implements Updatable {
|
||||
final PathConstraintData data;
|
||||
final Array<BoneApplied> bones;
|
||||
Slot slot;
|
||||
PathConstraint applied;
|
||||
final PathConstraintPose pose = new PathConstraintPose(), applied = new PathConstraintPose();
|
||||
boolean active;
|
||||
|
||||
float position, spacing, mixRotate, mixX, mixY;
|
||||
|
||||
private final FloatArray spaces = new FloatArray(), positions = new FloatArray();
|
||||
private final FloatArray world = new FloatArray(), curves = new FloatArray(), lengths = new FloatArray();
|
||||
private final float[] segments = new float[10];
|
||||
@ -78,31 +76,25 @@ public class PathConstraint implements Updatable {
|
||||
|
||||
slot = skeleton.slots.get(data.slot.index);
|
||||
|
||||
applied = new PathConstraint(data, bones, slot);
|
||||
|
||||
setupPose();
|
||||
}
|
||||
|
||||
/** Copy constructor. */
|
||||
public PathConstraint (PathConstraint constraint, Skeleton skeleton) {
|
||||
this(constraint.data, skeleton);
|
||||
setupPose();
|
||||
pose.set(constraint.pose);
|
||||
}
|
||||
|
||||
public void setupPose () {
|
||||
PathConstraintData data = this.data;
|
||||
position = data.position;
|
||||
spacing = data.spacing;
|
||||
mixRotate = data.mixRotate;
|
||||
mixX = data.mixX;
|
||||
mixY = data.mixY;
|
||||
pose.set(data.setup);
|
||||
}
|
||||
|
||||
/** Applies the constraint to the constrained bones. */
|
||||
public void update (Physics physics) {
|
||||
if (!(slot.applied.attachment instanceof PathAttachment pathAttachment)) return;
|
||||
|
||||
float mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY;
|
||||
PathConstraintPose pose = applied;
|
||||
float mixRotate = pose.mixRotate, mixX = pose.mixX, mixY = pose.mixY;
|
||||
if (mixRotate == 0 && mixX == 0 && mixY == 0) return;
|
||||
|
||||
PathConstraintData data = this.data;
|
||||
@ -110,7 +102,7 @@ public class PathConstraint implements Updatable {
|
||||
int boneCount = this.bones.size, spacesCount = tangents ? boneCount : boneCount + 1;
|
||||
Object[] bones = this.bones.items;
|
||||
float[] spaces = this.spaces.setSize(spacesCount), lengths = scale ? this.lengths.setSize(boneCount) : null;
|
||||
float spacing = this.spacing;
|
||||
float spacing = pose.spacing;
|
||||
|
||||
switch (data.spacingMode) {
|
||||
case percent -> {
|
||||
@ -224,7 +216,7 @@ public class PathConstraint implements Updatable {
|
||||
|
||||
float[] computeWorldPositions (PathAttachment path, int spacesCount, boolean tangents) {
|
||||
Slot slot = this.slot;
|
||||
float position = this.position;
|
||||
float position = applied.position;
|
||||
float[] spaces = this.spaces.items, out = this.positions.setSize(spacesCount * 3 + 2), world;
|
||||
boolean closed = path.getClosed();
|
||||
int verticesLength = path.getWorldVerticesLength(), curveCount = verticesLength / 6, prevCurve = NONE;
|
||||
@ -480,51 +472,6 @@ public class PathConstraint implements Updatable {
|
||||
}
|
||||
}
|
||||
|
||||
/** The position along the path. */
|
||||
public float getPosition () {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setPosition (float position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/** The spacing between bones. */
|
||||
public float getSpacing () {
|
||||
return spacing;
|
||||
}
|
||||
|
||||
public void setSpacing (float spacing) {
|
||||
this.spacing = spacing;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. */
|
||||
public float getMixRotate () {
|
||||
return mixRotate;
|
||||
}
|
||||
|
||||
public void setMixRotate (float mixRotate) {
|
||||
this.mixRotate = mixRotate;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. */
|
||||
public float getMixX () {
|
||||
return mixX;
|
||||
}
|
||||
|
||||
public void setMixX (float mixX) {
|
||||
this.mixX = mixX;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. */
|
||||
public float getMixY () {
|
||||
return mixY;
|
||||
}
|
||||
|
||||
public void setMixY (float mixY) {
|
||||
this.mixY = mixY;
|
||||
}
|
||||
|
||||
/** The bones that will be modified by this path constraint. */
|
||||
public Array<BoneApplied> getBones () {
|
||||
return bones;
|
||||
@ -540,6 +487,14 @@ public class PathConstraint implements Updatable {
|
||||
this.slot = slot;
|
||||
}
|
||||
|
||||
public PathConstraintPose getPose () {
|
||||
return pose;
|
||||
}
|
||||
|
||||
public PathConstraintPose getAppliedPose () {
|
||||
return applied;
|
||||
}
|
||||
|
||||
/** Returns false when this constraint 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.
|
||||
|
||||
@ -35,18 +35,22 @@ import com.badlogic.gdx.utils.Array;
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-path-constraints">Path constraints</a> in the Spine User Guide. */
|
||||
public class PathConstraintData extends ConstraintData {
|
||||
final PathConstraintPose setup = new PathConstraintPose();
|
||||
final Array<BoneData> bones = new Array();
|
||||
SlotData slot;
|
||||
PositionMode positionMode;
|
||||
SpacingMode spacingMode;
|
||||
RotateMode rotateMode;
|
||||
float offsetRotation;
|
||||
float position, spacing, mixRotate, mixX, mixY;
|
||||
|
||||
public PathConstraintData (String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public PathConstraintPose getSetupPose () {
|
||||
return setup;
|
||||
}
|
||||
|
||||
/** The bones that will be modified by this path constraint. */
|
||||
public Array<BoneData> getBones () {
|
||||
return bones;
|
||||
@ -101,51 +105,6 @@ public class PathConstraintData extends ConstraintData {
|
||||
this.offsetRotation = offsetRotation;
|
||||
}
|
||||
|
||||
/** The position along the path. */
|
||||
public float getPosition () {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setPosition (float position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/** The spacing between bones. */
|
||||
public float getSpacing () {
|
||||
return spacing;
|
||||
}
|
||||
|
||||
public void setSpacing (float spacing) {
|
||||
this.spacing = spacing;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. */
|
||||
public float getMixRotate () {
|
||||
return mixRotate;
|
||||
}
|
||||
|
||||
public void setMixRotate (float mixRotate) {
|
||||
this.mixRotate = mixRotate;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. */
|
||||
public float getMixX () {
|
||||
return mixX;
|
||||
}
|
||||
|
||||
public void setMixX (float mixX) {
|
||||
this.mixX = mixX;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. */
|
||||
public float getMixY () {
|
||||
return mixY;
|
||||
}
|
||||
|
||||
public void setMixY (float mixY) {
|
||||
this.mixY = mixY;
|
||||
}
|
||||
|
||||
/** Controls how the first bone is positioned along the path.
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-path-constraints#Position-mode">Position mode</a> in the Spine User
|
||||
|
||||
@ -0,0 +1,88 @@
|
||||
/******************************************************************************
|
||||
* 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;
|
||||
|
||||
/** Stores a pose for a path constraint. */
|
||||
public class PathConstraintPose {
|
||||
float position, spacing, mixRotate, mixX, mixY;
|
||||
|
||||
public void set (PathConstraintPose pose) {
|
||||
position = pose.position;
|
||||
spacing = pose.spacing;
|
||||
mixRotate = pose.mixRotate;
|
||||
mixX = pose.mixX;
|
||||
mixY = pose.mixY;
|
||||
}
|
||||
|
||||
/** The position along the path. */
|
||||
public float getPosition () {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setPosition (float position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/** The spacing between bones. */
|
||||
public float getSpacing () {
|
||||
return spacing;
|
||||
}
|
||||
|
||||
public void setSpacing (float spacing) {
|
||||
this.spacing = spacing;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. */
|
||||
public float getMixRotate () {
|
||||
return mixRotate;
|
||||
}
|
||||
|
||||
public void setMixRotate (float mixRotate) {
|
||||
this.mixRotate = mixRotate;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. */
|
||||
public float getMixX () {
|
||||
return mixX;
|
||||
}
|
||||
|
||||
public void setMixX (float mixX) {
|
||||
this.mixX = mixX;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. */
|
||||
public float getMixY () {
|
||||
return mixY;
|
||||
}
|
||||
|
||||
public void setMixY (float mixY) {
|
||||
this.mixY = mixY;
|
||||
}
|
||||
}
|
||||
@ -38,11 +38,9 @@ public class PhysicsConstraint implements Updatable {
|
||||
final PhysicsConstraintData data;
|
||||
final Skeleton skeleton;
|
||||
BoneApplied bone;
|
||||
PhysicsConstraint applied;
|
||||
final PhysicsConstraintPose pose = new PhysicsConstraintPose(), applied = new PhysicsConstraintPose();
|
||||
boolean active;
|
||||
|
||||
float inertia, strength, damping, massInverse, wind, gravity, mix;
|
||||
|
||||
boolean reset = true;
|
||||
float ux, uy, cx, cy, tx, ty;
|
||||
float xOffset, xVelocity;
|
||||
@ -65,15 +63,13 @@ public class PhysicsConstraint implements Updatable {
|
||||
|
||||
bone = skeleton.bones.get(data.bone.index).applied;
|
||||
|
||||
applied = new PhysicsConstraint(data, skeleton, bone);
|
||||
|
||||
setupPose();
|
||||
}
|
||||
|
||||
/** Copy constructor. */
|
||||
public PhysicsConstraint (PhysicsConstraint constraint, Skeleton skeleton) {
|
||||
this(constraint.data, skeleton);
|
||||
setupPose();
|
||||
pose.set(constraint.pose);
|
||||
}
|
||||
|
||||
public void reset () {
|
||||
@ -91,14 +87,7 @@ public class PhysicsConstraint implements Updatable {
|
||||
}
|
||||
|
||||
public void setupPose () {
|
||||
PhysicsConstraintData data = this.data;
|
||||
inertia = data.inertia;
|
||||
strength = data.strength;
|
||||
damping = data.damping;
|
||||
massInverse = data.massInverse;
|
||||
wind = data.wind;
|
||||
gravity = data.gravity;
|
||||
mix = data.mix;
|
||||
pose.set(data.setup);
|
||||
}
|
||||
|
||||
/** Translates the physics constraint so next {@link #update(Physics)} forces are applied as if the bone moved an additional
|
||||
@ -120,7 +109,8 @@ public class PhysicsConstraint implements Updatable {
|
||||
|
||||
/** Applies the constraint to the constrained bones. */
|
||||
public void update (Physics physics) {
|
||||
float mix = this.mix;
|
||||
PhysicsConstraintPose pose = applied;
|
||||
float mix = pose.mix;
|
||||
if (mix == 0) return;
|
||||
|
||||
boolean x = data.x > 0, y = data.y > 0, rotateOrShearX = data.rotate > 0 || data.shearX > 0, scaleX = data.scaleX > 0;
|
||||
@ -145,7 +135,7 @@ public class PhysicsConstraint implements Updatable {
|
||||
ux = bx;
|
||||
uy = by;
|
||||
} else {
|
||||
float a = remaining, i = inertia, t = data.step, f = skeleton.data.referenceScale, d = -1;
|
||||
float a = remaining, i = pose.inertia, t = data.step, f = skeleton.data.referenceScale, d = -1;
|
||||
float qx = data.limit * delta, qy = qx * Math.abs(skeleton.scaleY);
|
||||
qx *= Math.abs(skeleton.scaleX);
|
||||
if (x || y) {
|
||||
@ -160,8 +150,9 @@ public class PhysicsConstraint implements Updatable {
|
||||
uy = by;
|
||||
}
|
||||
if (a >= t) {
|
||||
d = (float)Math.pow(damping, 60 * t);
|
||||
float m = massInverse * t, e = strength, w = wind * f * skeleton.scaleX, g = gravity * f * skeleton.scaleY;
|
||||
d = (float)Math.pow(pose.damping, 60 * t);
|
||||
float m = pose.massInverse * t, e = pose.strength, w = pose.wind * f * skeleton.scaleX,
|
||||
g = pose.gravity * f * skeleton.scaleY;
|
||||
do {
|
||||
if (x) {
|
||||
xVelocity += (w - xOffset * e) * m;
|
||||
@ -209,8 +200,8 @@ public class PhysicsConstraint implements Updatable {
|
||||
}
|
||||
a = remaining;
|
||||
if (a >= t) {
|
||||
if (d == -1) d = (float)Math.pow(damping, 60 * t);
|
||||
float m = massInverse * t, e = strength, w = wind, g = gravity, h = l / f;
|
||||
if (d == -1) d = (float)Math.pow(pose.damping, 60 * t);
|
||||
float m = pose.massInverse * t, e = pose.strength, w = pose.wind, g = pose.gravity, h = l / f;
|
||||
while (true) {
|
||||
a -= t;
|
||||
if (scaleX) {
|
||||
@ -283,6 +274,15 @@ public class PhysicsConstraint implements Updatable {
|
||||
bone.updateLocalTransform();
|
||||
}
|
||||
|
||||
/** The physics constraint's setup pose data. */
|
||||
public PhysicsConstraintData getData () {
|
||||
return data;
|
||||
}
|
||||
|
||||
public Skeleton getSkeleton () {
|
||||
return skeleton;
|
||||
}
|
||||
|
||||
/** The bone constrained by this physics constraint. */
|
||||
public BoneApplied getBone () {
|
||||
return bone;
|
||||
@ -292,61 +292,12 @@ public class PhysicsConstraint implements Updatable {
|
||||
this.bone = bone;
|
||||
}
|
||||
|
||||
public float getInertia () {
|
||||
return inertia;
|
||||
public PhysicsConstraintPose getPose () {
|
||||
return pose;
|
||||
}
|
||||
|
||||
public void setInertia (float inertia) {
|
||||
this.inertia = inertia;
|
||||
}
|
||||
|
||||
public float getStrength () {
|
||||
return strength;
|
||||
}
|
||||
|
||||
public void setStrength (float strength) {
|
||||
this.strength = strength;
|
||||
}
|
||||
|
||||
public float getDamping () {
|
||||
return damping;
|
||||
}
|
||||
|
||||
public void setDamping (float damping) {
|
||||
this.damping = damping;
|
||||
}
|
||||
|
||||
public float getMassInverse () {
|
||||
return massInverse;
|
||||
}
|
||||
|
||||
public void setMassInverse (float massInverse) {
|
||||
this.massInverse = massInverse;
|
||||
}
|
||||
|
||||
public float getWind () {
|
||||
return wind;
|
||||
}
|
||||
|
||||
public void setWind (float wind) {
|
||||
this.wind = wind;
|
||||
}
|
||||
|
||||
public float getGravity () {
|
||||
return gravity;
|
||||
}
|
||||
|
||||
public void setGravity (float gravity) {
|
||||
this.gravity = gravity;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained poses. */
|
||||
public float getMix () {
|
||||
return mix;
|
||||
}
|
||||
|
||||
public void setMix (float mix) {
|
||||
this.mix = mix;
|
||||
public PhysicsConstraintPose getAppliedPose () {
|
||||
return applied;
|
||||
}
|
||||
|
||||
/** Returns false when this constraint won't be updated by
|
||||
@ -360,11 +311,6 @@ public class PhysicsConstraint implements Updatable {
|
||||
return active;
|
||||
}
|
||||
|
||||
/** The physics constraint's setup pose data. */
|
||||
public PhysicsConstraintData getData () {
|
||||
return data;
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
return data.name;
|
||||
}
|
||||
|
||||
@ -33,15 +33,19 @@ package com.esotericsoftware.spine;
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-physics-constraints">Physics constraints</a> in the Spine User Guide. */
|
||||
public class PhysicsConstraintData extends ConstraintData {
|
||||
final PhysicsConstraintPose setup = new PhysicsConstraintPose();
|
||||
BoneData bone;
|
||||
float x, y, rotate, scaleX, shearX, limit;
|
||||
float step, inertia, strength, damping, massInverse, wind, gravity, mix;
|
||||
float x, y, rotate, scaleX, shearX, limit, step;
|
||||
boolean inertiaGlobal, strengthGlobal, dampingGlobal, massGlobal, windGlobal, gravityGlobal, mixGlobal;
|
||||
|
||||
public PhysicsConstraintData (String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public PhysicsConstraintPose getSetupPose () {
|
||||
return setup;
|
||||
}
|
||||
|
||||
/** The bone constrained by this physics constraint. */
|
||||
public BoneData getBone () {
|
||||
return bone;
|
||||
@ -107,63 +111,6 @@ public class PhysicsConstraintData extends ConstraintData {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public float getInertia () {
|
||||
return inertia;
|
||||
}
|
||||
|
||||
public void setInertia (float inertia) {
|
||||
this.inertia = inertia;
|
||||
}
|
||||
|
||||
public float getStrength () {
|
||||
return strength;
|
||||
}
|
||||
|
||||
public void setStrength (float strength) {
|
||||
this.strength = strength;
|
||||
}
|
||||
|
||||
public float getDamping () {
|
||||
return damping;
|
||||
}
|
||||
|
||||
public void setDamping (float damping) {
|
||||
this.damping = damping;
|
||||
}
|
||||
|
||||
public float getMassInverse () {
|
||||
return massInverse;
|
||||
}
|
||||
|
||||
public void setMassInverse (float massInverse) {
|
||||
this.massInverse = massInverse;
|
||||
}
|
||||
|
||||
public float getWind () {
|
||||
return wind;
|
||||
}
|
||||
|
||||
public void setWind (float wind) {
|
||||
this.wind = wind;
|
||||
}
|
||||
|
||||
public float getGravity () {
|
||||
return gravity;
|
||||
}
|
||||
|
||||
public void setGravity (float gravity) {
|
||||
this.gravity = gravity;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained poses. */
|
||||
public float getMix () {
|
||||
return mix;
|
||||
}
|
||||
|
||||
public void setMix (float mix) {
|
||||
this.mix = mix;
|
||||
}
|
||||
|
||||
public boolean getInertiaGlobal () {
|
||||
return inertiaGlobal;
|
||||
}
|
||||
|
||||
@ -0,0 +1,102 @@
|
||||
/******************************************************************************
|
||||
* 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;
|
||||
|
||||
/** Stores a pose for a physics constraint. */
|
||||
public class PhysicsConstraintPose {
|
||||
float inertia, strength, damping, massInverse, wind, gravity, mix;
|
||||
|
||||
public void set (PhysicsConstraintPose pose) {
|
||||
inertia = pose.inertia;
|
||||
strength = pose.strength;
|
||||
damping = pose.damping;
|
||||
massInverse = pose.massInverse;
|
||||
wind = pose.wind;
|
||||
gravity = pose.gravity;
|
||||
mix = pose.mix;
|
||||
}
|
||||
|
||||
public float getInertia () {
|
||||
return inertia;
|
||||
}
|
||||
|
||||
public void setInertia (float inertia) {
|
||||
this.inertia = inertia;
|
||||
}
|
||||
|
||||
public float getStrength () {
|
||||
return strength;
|
||||
}
|
||||
|
||||
public void setStrength (float strength) {
|
||||
this.strength = strength;
|
||||
}
|
||||
|
||||
public float getDamping () {
|
||||
return damping;
|
||||
}
|
||||
|
||||
public void setDamping (float damping) {
|
||||
this.damping = damping;
|
||||
}
|
||||
|
||||
public float getMassInverse () {
|
||||
return massInverse;
|
||||
}
|
||||
|
||||
public void setMassInverse (float massInverse) {
|
||||
this.massInverse = massInverse;
|
||||
}
|
||||
|
||||
public float getWind () {
|
||||
return wind;
|
||||
}
|
||||
|
||||
public void setWind (float wind) {
|
||||
this.wind = wind;
|
||||
}
|
||||
|
||||
public float getGravity () {
|
||||
return gravity;
|
||||
}
|
||||
|
||||
public void setGravity (float gravity) {
|
||||
this.gravity = gravity;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained poses. */
|
||||
public float getMix () {
|
||||
return mix;
|
||||
}
|
||||
|
||||
public void setMix (float mix) {
|
||||
this.mix = mix;
|
||||
}
|
||||
}
|
||||
@ -38,7 +38,6 @@ import com.badlogic.gdx.utils.FloatArray;
|
||||
import com.badlogic.gdx.utils.Null;
|
||||
|
||||
import com.esotericsoftware.spine.Animation.BoneTimeline;
|
||||
import com.esotericsoftware.spine.Animation.Timeline;
|
||||
import com.esotericsoftware.spine.Skin.SkinEntry;
|
||||
import com.esotericsoftware.spine.attachments.Attachment;
|
||||
import com.esotericsoftware.spine.attachments.ClippingAttachment;
|
||||
@ -256,21 +255,24 @@ public class Skeleton {
|
||||
constraint.active = !constraint.data.skinRequired || (skin != null && skin.constraints.contains(constraint.data, true));
|
||||
if (!constraint.active) return;
|
||||
|
||||
Object[] timelines = constraint.data.animation.timelines.items;
|
||||
int timelineCount = constraint.data.animation.timelines.size;
|
||||
|
||||
Object[] bones = this.bones.items;
|
||||
for (Timeline timeline : constraint.animation.timelines)
|
||||
if (timeline instanceof BoneTimeline boneTimeline) sortBone((Bone)bones[boneTimeline.getBoneIndex()]);
|
||||
for (int i = 0; i < timelineCount; i++)
|
||||
if (timelines[i] instanceof BoneTimeline boneTimeline) sortBone((Bone)bones[boneTimeline.getBoneIndex()]);
|
||||
|
||||
updateCache.add(constraint);
|
||||
|
||||
for (Timeline timeline : constraint.animation.timelines) {
|
||||
if (timeline instanceof BoneTimeline boneTimeline) {
|
||||
for (int i = 0; i < timelineCount; i++) {
|
||||
if (timelines[i] instanceof BoneTimeline boneTimeline) {
|
||||
var bone = (Bone)bones[boneTimeline.getBoneIndex()];
|
||||
sortReset(bone.children);
|
||||
bone.sorted = false;
|
||||
}
|
||||
}
|
||||
for (Timeline timeline : constraint.animation.timelines)
|
||||
if (timeline instanceof BoneTimeline boneTimeline) sortBone((Bone)bones[boneTimeline.getBoneIndex()]);
|
||||
for (int i = 0; i < timelineCount; i++)
|
||||
if (timelines[i] instanceof BoneTimeline boneTimeline) sortBone((Bone)bones[boneTimeline.getBoneIndex()]);
|
||||
}
|
||||
|
||||
private void sortIkConstraint (IkConstraint constraint) {
|
||||
@ -347,9 +349,9 @@ public class Skeleton {
|
||||
updateCache.add(constraint);
|
||||
|
||||
for (int i = 0; i < boneCount; i++)
|
||||
sortReset(((Bone)constrained[i]).children);
|
||||
sortReset(((BoneApplied)constrained[i]).bone.children);
|
||||
for (int i = 0; i < boneCount; i++)
|
||||
((Bone)constrained[i]).sorted = true;
|
||||
((BoneApplied)constrained[i]).bone.sorted = true;
|
||||
}
|
||||
|
||||
private void sortPathConstraintAttachment (Skin skin, int slotIndex, Bone slotBone) {
|
||||
@ -371,7 +373,7 @@ public class Skeleton {
|
||||
int nn = pathBones[i++];
|
||||
nn += i;
|
||||
while (i < nn)
|
||||
sortBone(((BoneApplied)bones[pathBones[i++]]).bone);
|
||||
sortBone((Bone)bones[pathBones[i++]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -428,8 +430,26 @@ public class Skeleton {
|
||||
var constraint = (IkConstraint)objects[i];
|
||||
if (constraint.active) constraint.applied.set(constraint.pose);
|
||||
}
|
||||
|
||||
// BOZO! - Reset the rest.
|
||||
objects = pathConstraints.items;
|
||||
for (int i = 0, n = pathConstraints.size; i < n; i++) {
|
||||
var constraint = (PathConstraint)objects[i];
|
||||
if (constraint.active) constraint.applied.set(constraint.pose);
|
||||
}
|
||||
objects = transformConstraints.items;
|
||||
for (int i = 0, n = transformConstraints.size; i < n; i++) {
|
||||
var constraint = (TransformConstraint)objects[i];
|
||||
if (constraint.active) constraint.applied.set(constraint.pose);
|
||||
}
|
||||
objects = physicsConstraints.items;
|
||||
for (int i = 0, n = physicsConstraints.size; i < n; i++) {
|
||||
var constraint = (PhysicsConstraint)objects[i];
|
||||
if (constraint.active) constraint.applied.set(constraint.pose);
|
||||
}
|
||||
objects = sliders.items;
|
||||
for (int i = 0, n = sliders.size; i < n; i++) {
|
||||
var constraint = (Slider)objects[i];
|
||||
if (constraint.active) constraint.applied.set(constraint.pose);
|
||||
}
|
||||
|
||||
Object[] updateCache = this.updateCache.items;
|
||||
for (int i = 0, n = this.updateCache.size; i < n; i++)
|
||||
@ -444,12 +464,41 @@ public class Skeleton {
|
||||
public void updateWorldTransform (Physics physics, BoneApplied parent) {
|
||||
if (parent == null) throw new IllegalArgumentException("parent cannot be null.");
|
||||
|
||||
Object[] bones = this.bones.items;
|
||||
for (int i = 1, n = this.bones.size; i < n; i++) { // Skip root bone.
|
||||
var bone = (Bone)bones[i];
|
||||
Object[] objects = this.bones.items;
|
||||
for (int i = 0, n = this.bones.size; i < n; i++) {
|
||||
var bone = (Bone)objects[i];
|
||||
if (bone.active) bone.applied.set(bone.pose);
|
||||
}
|
||||
// BOZO! - Reset the rest.
|
||||
objects = this.slots.items;
|
||||
for (int i = 0, n = this.slots.size; i < n; i++) {
|
||||
var slot = (Slot)objects[i];
|
||||
if (slot.bone.active) slot.applied.set(slot.pose);
|
||||
}
|
||||
objects = ikConstraints.items;
|
||||
for (int i = 0, n = ikConstraints.size; i < n; i++) {
|
||||
var constraint = (IkConstraint)objects[i];
|
||||
if (constraint.active) constraint.applied.set(constraint.pose);
|
||||
}
|
||||
objects = pathConstraints.items;
|
||||
for (int i = 0, n = pathConstraints.size; i < n; i++) {
|
||||
var constraint = (PathConstraint)objects[i];
|
||||
if (constraint.active) constraint.applied.set(constraint.pose);
|
||||
}
|
||||
objects = transformConstraints.items;
|
||||
for (int i = 0, n = transformConstraints.size; i < n; i++) {
|
||||
var constraint = (TransformConstraint)objects[i];
|
||||
if (constraint.active) constraint.applied.set(constraint.pose);
|
||||
}
|
||||
objects = physicsConstraints.items;
|
||||
for (int i = 0, n = physicsConstraints.size; i < n; i++) {
|
||||
var constraint = (PhysicsConstraint)objects[i];
|
||||
if (constraint.active) constraint.applied.set(constraint.pose);
|
||||
}
|
||||
objects = sliders.items;
|
||||
for (int i = 0, n = sliders.size; i < n; i++) {
|
||||
var constraint = (Slider)objects[i];
|
||||
if (constraint.active) constraint.applied.set(constraint.pose);
|
||||
}
|
||||
|
||||
// Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection.
|
||||
BoneApplied rootBone = getRootBone().applied;
|
||||
|
||||
@ -343,12 +343,13 @@ public class SkeletonBinary extends SkeletonLoader {
|
||||
if ((flags & 16) != 0) data.offsetScaleY = input.readFloat();
|
||||
if ((flags & 32) != 0) data.offsetShearY = input.readFloat();
|
||||
flags = input.read();
|
||||
if ((flags & 1) != 0) data.mixRotate = input.readFloat();
|
||||
if ((flags & 2) != 0) data.mixX = input.readFloat();
|
||||
if ((flags & 4) != 0) data.mixY = input.readFloat();
|
||||
if ((flags & 8) != 0) data.mixScaleX = input.readFloat();
|
||||
if ((flags & 16) != 0) data.mixScaleY = input.readFloat();
|
||||
if ((flags & 32) != 0) data.mixShearY = input.readFloat();
|
||||
TransformConstraintPose setup = data.getSetupPose();
|
||||
if ((flags & 1) != 0) setup.mixRotate = input.readFloat();
|
||||
if ((flags & 2) != 0) setup.mixX = input.readFloat();
|
||||
if ((flags & 4) != 0) setup.mixY = input.readFloat();
|
||||
if ((flags & 8) != 0) setup.mixScaleX = input.readFloat();
|
||||
if ((flags & 16) != 0) setup.mixScaleY = input.readFloat();
|
||||
if ((flags & 32) != 0) setup.mixShearY = input.readFloat();
|
||||
o[i] = data;
|
||||
}
|
||||
|
||||
@ -367,13 +368,14 @@ public class SkeletonBinary extends SkeletonLoader {
|
||||
data.spacingMode = SpacingMode.values[(flags >> 1) & 3];
|
||||
data.rotateMode = RotateMode.values[(flags >> 3) & 3];
|
||||
if ((flags & 128) != 0) data.offsetRotation = input.readFloat();
|
||||
data.position = input.readFloat();
|
||||
if (data.positionMode == PositionMode.fixed) data.position *= scale;
|
||||
data.spacing = input.readFloat();
|
||||
if (data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed) data.spacing *= scale;
|
||||
data.mixRotate = input.readFloat();
|
||||
data.mixX = input.readFloat();
|
||||
data.mixY = input.readFloat();
|
||||
PathConstraintPose setup = data.setup;
|
||||
setup.position = input.readFloat();
|
||||
if (data.positionMode == PositionMode.fixed) setup.position *= scale;
|
||||
setup.spacing = input.readFloat();
|
||||
if (data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed) setup.spacing *= scale;
|
||||
setup.mixRotate = input.readFloat();
|
||||
setup.mixX = input.readFloat();
|
||||
setup.mixY = input.readFloat();
|
||||
o[i] = data;
|
||||
}
|
||||
|
||||
@ -392,12 +394,13 @@ public class SkeletonBinary extends SkeletonLoader {
|
||||
if ((flags & 32) != 0) data.shearX = input.readFloat();
|
||||
data.limit = ((flags & 64) != 0 ? input.readFloat() : 5000) * scale;
|
||||
data.step = 1f / input.readUnsignedByte();
|
||||
data.inertia = input.readFloat();
|
||||
data.strength = input.readFloat();
|
||||
data.damping = input.readFloat();
|
||||
data.massInverse = (flags & 128) != 0 ? input.readFloat() : 1;
|
||||
data.wind = input.readFloat();
|
||||
data.gravity = input.readFloat();
|
||||
PhysicsConstraintPose setup = data.getSetupPose();
|
||||
setup.inertia = input.readFloat();
|
||||
setup.strength = input.readFloat();
|
||||
setup.damping = input.readFloat();
|
||||
setup.massInverse = (flags & 128) != 0 ? input.readFloat() : 1;
|
||||
setup.wind = input.readFloat();
|
||||
setup.gravity = input.readFloat();
|
||||
flags = input.read();
|
||||
if ((flags & 1) != 0) data.inertiaGlobal = true;
|
||||
if ((flags & 2) != 0) data.strengthGlobal = true;
|
||||
@ -406,7 +409,7 @@ public class SkeletonBinary extends SkeletonLoader {
|
||||
if ((flags & 16) != 0) data.windGlobal = true;
|
||||
if ((flags & 32) != 0) data.gravityGlobal = true;
|
||||
if ((flags & 64) != 0) data.mixGlobal = true;
|
||||
data.mix = (flags & 128) != 0 ? input.readFloat() : 1;
|
||||
setup.mix = (flags & 128) != 0 ? input.readFloat() : 1;
|
||||
o[i] = data;
|
||||
}
|
||||
|
||||
|
||||
@ -330,12 +330,13 @@ public class SkeletonJson extends SkeletonLoader {
|
||||
data.offsetScaleY = constraintMap.getFloat("scaleY", 0);
|
||||
data.offsetShearY = constraintMap.getFloat("shearY", 0);
|
||||
|
||||
if (rotate) data.mixRotate = constraintMap.getFloat("mixRotate", 1);
|
||||
if (x) data.mixX = constraintMap.getFloat("mixX", 1);
|
||||
if (y) data.mixY = constraintMap.getFloat("mixY", data.mixX);
|
||||
if (scaleX) data.mixScaleX = constraintMap.getFloat("mixScaleX", 1);
|
||||
if (scaleY) data.mixScaleY = constraintMap.getFloat("mixScaleY", data.mixScaleX);
|
||||
if (shearY) data.mixShearY = constraintMap.getFloat("mixShearY", 1);
|
||||
TransformConstraintPose setup = data.setup;
|
||||
if (rotate) setup.mixRotate = constraintMap.getFloat("mixRotate", 1);
|
||||
if (x) setup.mixX = constraintMap.getFloat("mixX", 1);
|
||||
if (y) setup.mixY = constraintMap.getFloat("mixY", setup.mixX);
|
||||
if (scaleX) setup.mixScaleX = constraintMap.getFloat("mixScaleX", 1);
|
||||
if (scaleY) setup.mixScaleY = constraintMap.getFloat("mixScaleY", setup.mixScaleX);
|
||||
if (shearY) setup.mixShearY = constraintMap.getFloat("mixShearY", 1);
|
||||
|
||||
skeletonData.transformConstraints.add(data);
|
||||
}
|
||||
@ -360,13 +361,14 @@ public class SkeletonJson extends SkeletonLoader {
|
||||
data.spacingMode = SpacingMode.valueOf(constraintMap.getString("spacingMode", "length"));
|
||||
data.rotateMode = RotateMode.valueOf(constraintMap.getString("rotateMode", "tangent"));
|
||||
data.offsetRotation = constraintMap.getFloat("rotation", 0);
|
||||
data.position = constraintMap.getFloat("position", 0);
|
||||
if (data.positionMode == PositionMode.fixed) data.position *= scale;
|
||||
data.spacing = constraintMap.getFloat("spacing", 0);
|
||||
if (data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed) data.spacing *= scale;
|
||||
data.mixRotate = constraintMap.getFloat("mixRotate", 1);
|
||||
data.mixX = constraintMap.getFloat("mixX", 1);
|
||||
data.mixY = constraintMap.getFloat("mixY", 1);
|
||||
PathConstraintPose setup = data.setup;
|
||||
setup.position = constraintMap.getFloat("position", 0);
|
||||
if (data.positionMode == PositionMode.fixed) setup.position *= scale;
|
||||
setup.spacing = constraintMap.getFloat("spacing", 0);
|
||||
if (data.spacingMode == SpacingMode.length || data.spacingMode == SpacingMode.fixed) setup.spacing *= scale;
|
||||
setup.mixRotate = constraintMap.getFloat("mixRotate", 1);
|
||||
setup.mixX = constraintMap.getFloat("mixX", 1);
|
||||
setup.mixY = constraintMap.getFloat("mixY", 1);
|
||||
|
||||
skeletonData.pathConstraints.add(data);
|
||||
}
|
||||
@ -388,13 +390,14 @@ public class SkeletonJson extends SkeletonLoader {
|
||||
data.shearX = constraintMap.getFloat("shearX", 0);
|
||||
data.limit = constraintMap.getFloat("limit", 5000) * scale;
|
||||
data.step = 1f / constraintMap.getInt("fps", 60);
|
||||
data.inertia = constraintMap.getFloat("inertia", 1);
|
||||
data.strength = constraintMap.getFloat("strength", 100);
|
||||
data.damping = constraintMap.getFloat("damping", 1);
|
||||
data.massInverse = 1 / constraintMap.getFloat("mass", 1);
|
||||
data.wind = constraintMap.getFloat("wind", 0);
|
||||
data.gravity = constraintMap.getFloat("gravity", 0);
|
||||
data.mix = constraintMap.getFloat("mix", 1);
|
||||
PhysicsConstraintPose setup = data.getSetupPose();
|
||||
setup.inertia = constraintMap.getFloat("inertia", 1);
|
||||
setup.strength = constraintMap.getFloat("strength", 100);
|
||||
setup.damping = constraintMap.getFloat("damping", 1);
|
||||
setup.massInverse = 1 / constraintMap.getFloat("mass", 1);
|
||||
setup.wind = constraintMap.getFloat("wind", 0);
|
||||
setup.gravity = constraintMap.getFloat("gravity", 0);
|
||||
setup.mix = constraintMap.getFloat("mix", 1);
|
||||
data.inertiaGlobal = constraintMap.getBoolean("inertiaGlobal", false);
|
||||
data.strengthGlobal = constraintMap.getBoolean("strengthGlobal", false);
|
||||
data.dampingGlobal = constraintMap.getBoolean("dampingGlobal", false);
|
||||
|
||||
@ -38,8 +38,7 @@ import com.esotericsoftware.spine.Animation.MixDirection;
|
||||
public class Slider implements Updatable {
|
||||
final SliderData data;
|
||||
final Skeleton skeleton;
|
||||
Animation animation;
|
||||
float time, mix;
|
||||
final SliderPose pose = new SliderPose(), applied = new SliderPose();
|
||||
|
||||
boolean active;
|
||||
|
||||
@ -59,14 +58,20 @@ public class Slider implements Updatable {
|
||||
}
|
||||
|
||||
public void update (Physics physics) {
|
||||
animation.apply(skeleton, time, time, false, null, mix, MixBlend.replace, MixDirection.in, true);
|
||||
SliderPose pose = applied;
|
||||
data.animation.apply(skeleton, pose.time, pose.time, false, null, pose.mix, MixBlend.replace, MixDirection.in, true);
|
||||
}
|
||||
|
||||
public void setupPose () {
|
||||
SliderData data = this.data;
|
||||
animation = data.animation;
|
||||
time = data.time;
|
||||
mix = data.mix;
|
||||
pose.set(data.setup);
|
||||
}
|
||||
|
||||
public SliderPose getPose () {
|
||||
return pose;
|
||||
}
|
||||
|
||||
public SliderPose getAppliedPose () {
|
||||
return applied;
|
||||
}
|
||||
|
||||
/** Returns false when this constraint won't be updated by
|
||||
@ -80,27 +85,7 @@ public class Slider implements Updatable {
|
||||
return active;
|
||||
}
|
||||
|
||||
public Animation getAnimation () {
|
||||
return animation;
|
||||
}
|
||||
|
||||
public void setAnimation (Animation animation) {
|
||||
this.animation = animation;
|
||||
}
|
||||
|
||||
public float getTime () {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime (float time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public float getMix () {
|
||||
return mix;
|
||||
}
|
||||
|
||||
public void setMix (float mix) {
|
||||
this.mix = mix;
|
||||
public String toString () {
|
||||
return data.name;
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,13 +33,17 @@ package com.esotericsoftware.spine;
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-physics-constraints">Physics constraints</a> in the Spine User Guide. */
|
||||
public class SliderData extends ConstraintData {
|
||||
final SliderPose setup = new SliderPose();
|
||||
Animation animation;
|
||||
float time, mix;
|
||||
|
||||
public SliderData (String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public SliderPose getSetupPose () {
|
||||
return setup;
|
||||
}
|
||||
|
||||
public Animation getAnimation () {
|
||||
return animation;
|
||||
}
|
||||
@ -47,20 +51,4 @@ public class SliderData extends ConstraintData {
|
||||
public void setAnimation (Animation animation) {
|
||||
this.animation = animation;
|
||||
}
|
||||
|
||||
public float getTime () {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime (float time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public float getMix () {
|
||||
return mix;
|
||||
}
|
||||
|
||||
public void setMix (float mix) {
|
||||
this.mix = mix;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
/******************************************************************************
|
||||
* 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;
|
||||
|
||||
/** Stores a pose for a slider. */
|
||||
public class SliderPose {
|
||||
float time, mix;
|
||||
|
||||
public void set (SliderPose pose) {
|
||||
time = pose.time;
|
||||
mix = pose.mix;
|
||||
}
|
||||
|
||||
|
||||
public float getTime () {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime (float time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public float getMix () {
|
||||
return mix;
|
||||
}
|
||||
|
||||
public void setMix (float mix) {
|
||||
this.mix = mix;
|
||||
}
|
||||
}
|
||||
@ -44,11 +44,9 @@ public class TransformConstraint implements Updatable {
|
||||
final TransformConstraintData data;
|
||||
final Array<BoneApplied> bones;
|
||||
BoneApplied source;
|
||||
TransformConstraint applied;
|
||||
final TransformConstraintPose pose = new TransformConstraintPose(), applied = new TransformConstraintPose();
|
||||
boolean active;
|
||||
|
||||
float mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY;
|
||||
|
||||
public TransformConstraint (TransformConstraintData data, Array<BoneApplied> bones, BoneApplied source) {
|
||||
this.data = data;
|
||||
this.bones = bones;
|
||||
@ -66,30 +64,24 @@ public class TransformConstraint implements Updatable {
|
||||
|
||||
source = skeleton.bones.get(data.source.index).applied;
|
||||
|
||||
applied = new TransformConstraint(data, bones, source);
|
||||
|
||||
setupPose();
|
||||
}
|
||||
|
||||
/** Copy constructor. */
|
||||
public TransformConstraint (TransformConstraint constraint, Skeleton skeleton) {
|
||||
this(constraint.data, skeleton);
|
||||
setupPose();
|
||||
pose.set(constraint.pose);
|
||||
}
|
||||
|
||||
public void setupPose () {
|
||||
TransformConstraintData data = this.data;
|
||||
mixRotate = data.mixRotate;
|
||||
mixX = data.mixX;
|
||||
mixY = data.mixY;
|
||||
mixScaleX = data.mixScaleX;
|
||||
mixScaleY = data.mixScaleY;
|
||||
mixShearY = data.mixShearY;
|
||||
pose.set(data.setup);
|
||||
}
|
||||
|
||||
/** Applies the constraint to the constrained bones. */
|
||||
public void update (Physics physics) {
|
||||
if (mixRotate == 0 && mixX == 0 && mixY == 0 && mixScaleX == 0 && mixScaleY == 0 && mixShearY == 0) return;
|
||||
TransformConstraintPose pose = applied;
|
||||
if (pose.mixRotate == 0 && pose.mixX == 0 && pose.mixY == 0 && pose.mixScaleX == 0 && pose.mixScaleY == 0
|
||||
&& pose.mixShearY == 0) return;
|
||||
|
||||
TransformConstraintData data = this.data;
|
||||
boolean localFrom = data.localSource, localTarget = data.localTarget, additive = data.additive, clamp = data.clamp;
|
||||
@ -105,7 +97,7 @@ public class TransformConstraint implements Updatable {
|
||||
Object[] toItems = from.to.items;
|
||||
for (int t = 0, tn = from.to.size; t < tn; t++) {
|
||||
var to = (ToProperty)toItems[t];
|
||||
if (to.mix(this) != 0) {
|
||||
if (to.mix(pose) != 0) {
|
||||
float clamped = to.offset + value * to.scale;
|
||||
if (clamp) {
|
||||
if (to.offset < to.max)
|
||||
@ -113,7 +105,7 @@ public class TransformConstraint implements Updatable {
|
||||
else
|
||||
clamped = clamp(clamped, to.max, to.offset);
|
||||
}
|
||||
to.apply(this, bone, clamped, localTarget, additive);
|
||||
to.apply(pose, bone, clamped, localTarget, additive);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -139,58 +131,12 @@ public class TransformConstraint implements Updatable {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. */
|
||||
public float getMixRotate () {
|
||||
return mixRotate;
|
||||
public TransformConstraintPose getPose () {
|
||||
return pose;
|
||||
}
|
||||
|
||||
public void setMixRotate (float mixRotate) {
|
||||
this.mixRotate = mixRotate;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. */
|
||||
public float getMixX () {
|
||||
return mixX;
|
||||
}
|
||||
|
||||
public void setMixX (float mixX) {
|
||||
this.mixX = mixX;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. */
|
||||
public float getMixY () {
|
||||
return mixY;
|
||||
}
|
||||
|
||||
public void setMixY (float mixY) {
|
||||
this.mixY = mixY;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained scale X. */
|
||||
public float getMixScaleX () {
|
||||
return mixScaleX;
|
||||
}
|
||||
|
||||
public void setMixScaleX (float mixScaleX) {
|
||||
this.mixScaleX = mixScaleX;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained scale X. */
|
||||
public float getMixScaleY () {
|
||||
return mixScaleY;
|
||||
}
|
||||
|
||||
public void setMixScaleY (float mixScaleY) {
|
||||
this.mixScaleY = mixScaleY;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained shear Y. */
|
||||
public float getMixShearY () {
|
||||
return mixShearY;
|
||||
}
|
||||
|
||||
public void setMixShearY (float mixShearY) {
|
||||
this.mixShearY = mixShearY;
|
||||
public TransformConstraintPose getAppliedPose () {
|
||||
return applied;
|
||||
}
|
||||
|
||||
/** Returns false when this constraint won't be updated by
|
||||
|
||||
@ -37,9 +37,9 @@ import com.badlogic.gdx.utils.Array;
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-transform-constraints">Transform constraints</a> in the Spine User Guide. */
|
||||
public class TransformConstraintData extends ConstraintData {
|
||||
final TransformConstraintPose setup = new TransformConstraintPose();
|
||||
final Array<BoneData> bones = new Array();
|
||||
BoneData source;
|
||||
float mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY;
|
||||
float offsetRotation, offsetX, offsetY, offsetScaleX, offsetScaleY, offsetShearY;
|
||||
boolean localSource, localTarget, additive, clamp;
|
||||
final Array<FromProperty> properties = new Array();
|
||||
@ -48,6 +48,10 @@ public class TransformConstraintData extends ConstraintData {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public TransformConstraintPose getSetupPose () {
|
||||
return setup;
|
||||
}
|
||||
|
||||
/** The bones that will be modified by this transform constraint. */
|
||||
public Array<BoneData> getBones () {
|
||||
return bones;
|
||||
@ -63,65 +67,6 @@ public class TransformConstraintData extends ConstraintData {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
/** The mapping of transform properties to other transform properties. */
|
||||
public Array<FromProperty> getProperties () {
|
||||
return properties;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. */
|
||||
public float getMixRotate () {
|
||||
return mixRotate;
|
||||
}
|
||||
|
||||
public void setMixRotate (float mixRotate) {
|
||||
this.mixRotate = mixRotate;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. */
|
||||
public float getMixX () {
|
||||
return mixX;
|
||||
}
|
||||
|
||||
public void setMixX (float mixX) {
|
||||
this.mixX = mixX;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. */
|
||||
public float getMixY () {
|
||||
return mixY;
|
||||
}
|
||||
|
||||
public void setMixY (float mixY) {
|
||||
this.mixY = mixY;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained scale X. */
|
||||
public float getMixScaleX () {
|
||||
return mixScaleX;
|
||||
}
|
||||
|
||||
public void setMixScaleX (float mixScaleX) {
|
||||
this.mixScaleX = mixScaleX;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained scale Y. */
|
||||
public float getMixScaleY () {
|
||||
return mixScaleY;
|
||||
}
|
||||
|
||||
public void setMixScaleY (float mixScaleY) {
|
||||
this.mixScaleY = mixScaleY;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained shear Y. */
|
||||
public float getMixShearY () {
|
||||
return mixShearY;
|
||||
}
|
||||
|
||||
public void setMixShearY (float mixShearY) {
|
||||
this.mixShearY = mixShearY;
|
||||
}
|
||||
|
||||
/** An offset added to the constrained bone rotation. */
|
||||
public float getOffsetRotation () {
|
||||
return offsetRotation;
|
||||
@ -212,6 +157,11 @@ public class TransformConstraintData extends ConstraintData {
|
||||
this.clamp = clamp;
|
||||
}
|
||||
|
||||
/** The mapping of transform properties to other transform properties. */
|
||||
public Array<FromProperty> getProperties () {
|
||||
return properties;
|
||||
}
|
||||
|
||||
/** Source property for a {@link TransformConstraint}. */
|
||||
static abstract public class FromProperty {
|
||||
/** The value of this property that corresponds to {@link ToProperty#offset}. */
|
||||
@ -235,11 +185,11 @@ public class TransformConstraintData extends ConstraintData {
|
||||
/** The scale of the {@link FromProperty} value in relation to this property. */
|
||||
public float scale;
|
||||
|
||||
/** Reads the mix for this property from the specified constraint. */
|
||||
abstract public float mix (TransformConstraint constraint);
|
||||
/** Reads the mix for this property from the specified pose. */
|
||||
abstract public float mix (TransformConstraintPose pose);
|
||||
|
||||
/** Applies the value to this property. */
|
||||
abstract public void apply (TransformConstraint constraint, BoneApplied bone, float value, boolean local, boolean additive);
|
||||
abstract public void apply (TransformConstraintPose pose, BoneApplied bone, float value, boolean local, boolean additive);
|
||||
}
|
||||
|
||||
static public class FromRotate extends FromProperty {
|
||||
@ -253,14 +203,14 @@ public class TransformConstraintData extends ConstraintData {
|
||||
}
|
||||
|
||||
static public class ToRotate extends ToProperty {
|
||||
public float mix (TransformConstraint constraint) {
|
||||
return constraint.mixRotate;
|
||||
public float mix (TransformConstraintPose pose) {
|
||||
return pose.mixRotate;
|
||||
}
|
||||
|
||||
public void apply (TransformConstraint constraint, BoneApplied bone, float value, boolean local, boolean additive) {
|
||||
public void apply (TransformConstraintPose pose, BoneApplied bone, float value, boolean local, boolean additive) {
|
||||
if (local) {
|
||||
if (!additive) value -= bone.rotation;
|
||||
bone.rotation += value * constraint.mixRotate;
|
||||
bone.rotation += value * pose.mixRotate;
|
||||
} else {
|
||||
float a = bone.a, b = bone.b, c = bone.c, d = bone.d;
|
||||
value *= degRad;
|
||||
@ -269,7 +219,7 @@ public class TransformConstraintData extends ConstraintData {
|
||||
value -= PI2;
|
||||
else if (value < -PI) //
|
||||
value += PI2;
|
||||
value *= constraint.mixRotate;
|
||||
value *= pose.mixRotate;
|
||||
float cos = cos(value), sin = sin(value);
|
||||
bone.a = cos * a - sin * c;
|
||||
bone.b = cos * b - sin * d;
|
||||
@ -286,17 +236,17 @@ public class TransformConstraintData extends ConstraintData {
|
||||
}
|
||||
|
||||
static public class ToX extends ToProperty {
|
||||
public float mix (TransformConstraint constraint) {
|
||||
return constraint.mixX;
|
||||
public float mix (TransformConstraintPose pose) {
|
||||
return pose.mixX;
|
||||
}
|
||||
|
||||
public void apply (TransformConstraint constraint, BoneApplied bone, float value, boolean local, boolean additive) {
|
||||
public void apply (TransformConstraintPose pose, BoneApplied bone, float value, boolean local, boolean additive) {
|
||||
if (local) {
|
||||
if (!additive) value -= bone.x;
|
||||
bone.x += value * constraint.mixX;
|
||||
bone.x += value * pose.mixX;
|
||||
} else {
|
||||
if (!additive) value -= bone.worldX;
|
||||
bone.worldX += value * constraint.mixX;
|
||||
bone.worldX += value * pose.mixX;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -308,17 +258,17 @@ public class TransformConstraintData extends ConstraintData {
|
||||
}
|
||||
|
||||
static public class ToY extends ToProperty {
|
||||
public float mix (TransformConstraint constraint) {
|
||||
return constraint.mixY;
|
||||
public float mix (TransformConstraintPose pose) {
|
||||
return pose.mixY;
|
||||
}
|
||||
|
||||
public void apply (TransformConstraint constraint, BoneApplied bone, float value, boolean local, boolean additive) {
|
||||
public void apply (TransformConstraintPose pose, BoneApplied bone, float value, boolean local, boolean additive) {
|
||||
if (local) {
|
||||
if (!additive) value -= bone.y;
|
||||
bone.y += value * constraint.mixY;
|
||||
bone.y += value * pose.mixY;
|
||||
} else {
|
||||
if (!additive) value -= bone.worldY;
|
||||
bone.worldY += value * constraint.mixY;
|
||||
bone.worldY += value * pose.mixY;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -330,23 +280,23 @@ public class TransformConstraintData extends ConstraintData {
|
||||
}
|
||||
|
||||
static public class ToScaleX extends ToProperty {
|
||||
public float mix (TransformConstraint constraint) {
|
||||
return constraint.mixScaleX;
|
||||
public float mix (TransformConstraintPose pose) {
|
||||
return pose.mixScaleX;
|
||||
}
|
||||
|
||||
public void apply (TransformConstraint constraint, BoneApplied bone, float value, boolean local, boolean additive) {
|
||||
public void apply (TransformConstraintPose pose, BoneApplied bone, float value, boolean local, boolean additive) {
|
||||
if (local) {
|
||||
if (additive)
|
||||
bone.scaleX *= 1 + ((value - 1) * constraint.mixScaleX);
|
||||
bone.scaleX *= 1 + ((value - 1) * pose.mixScaleX);
|
||||
else if (bone.scaleX != 0) //
|
||||
bone.scaleX = 1 + (value / bone.scaleX - 1) * constraint.mixScaleX;
|
||||
bone.scaleX = 1 + (value / bone.scaleX - 1) * pose.mixScaleX;
|
||||
} else {
|
||||
float s;
|
||||
if (additive)
|
||||
s = 1 + (value - 1) * constraint.mixScaleX;
|
||||
s = 1 + (value - 1) * pose.mixScaleX;
|
||||
else {
|
||||
s = (float)Math.sqrt(bone.a * bone.a + bone.c * bone.c);
|
||||
if (s != 0) s = 1 + (value / s - 1) * constraint.mixScaleX;
|
||||
if (s != 0) s = 1 + (value / s - 1) * pose.mixScaleX;
|
||||
}
|
||||
bone.a *= s;
|
||||
bone.c *= s;
|
||||
@ -361,23 +311,23 @@ public class TransformConstraintData extends ConstraintData {
|
||||
}
|
||||
|
||||
static public class ToScaleY extends ToProperty {
|
||||
public float mix (TransformConstraint constraint) {
|
||||
return constraint.mixScaleY;
|
||||
public float mix (TransformConstraintPose pose) {
|
||||
return pose.mixScaleY;
|
||||
}
|
||||
|
||||
public void apply (TransformConstraint constraint, BoneApplied bone, float value, boolean local, boolean additive) {
|
||||
public void apply (TransformConstraintPose pose, BoneApplied bone, float value, boolean local, boolean additive) {
|
||||
if (local) {
|
||||
if (additive)
|
||||
bone.scaleY *= 1 + ((value - 1) * constraint.mixScaleY);
|
||||
bone.scaleY *= 1 + ((value - 1) * pose.mixScaleY);
|
||||
else if (bone.scaleY != 0) //
|
||||
bone.scaleY = 1 + (value / bone.scaleY - 1) * constraint.mixScaleY;
|
||||
bone.scaleY = 1 + (value / bone.scaleY - 1) * pose.mixScaleY;
|
||||
} else {
|
||||
float s;
|
||||
if (additive)
|
||||
s = 1 + (value - 1) * constraint.mixScaleY;
|
||||
s = 1 + (value - 1) * pose.mixScaleY;
|
||||
else {
|
||||
s = (float)Math.sqrt(bone.b * bone.b + bone.d * bone.d);
|
||||
if (s != 0) s = 1 + (value / s - 1) * constraint.mixScaleY;
|
||||
if (s != 0) s = 1 + (value / s - 1) * pose.mixScaleY;
|
||||
}
|
||||
bone.b *= s;
|
||||
bone.d *= s;
|
||||
@ -393,14 +343,14 @@ public class TransformConstraintData extends ConstraintData {
|
||||
}
|
||||
|
||||
static public class ToShearY extends ToProperty {
|
||||
public float mix (TransformConstraint constraint) {
|
||||
return constraint.mixShearY;
|
||||
public float mix (TransformConstraintPose pose) {
|
||||
return pose.mixShearY;
|
||||
}
|
||||
|
||||
public void apply (TransformConstraint constraint, BoneApplied bone, float value, boolean local, boolean additive) {
|
||||
public void apply (TransformConstraintPose pose, BoneApplied bone, float value, boolean local, boolean additive) {
|
||||
if (local) {
|
||||
if (!additive) value -= bone.shearY;
|
||||
bone.shearY += value * constraint.mixShearY;
|
||||
bone.shearY += value * pose.mixShearY;
|
||||
} else {
|
||||
float b = bone.b, d = bone.d, by = atan2(d, b);
|
||||
value = (value + 90) * degRad;
|
||||
@ -413,7 +363,7 @@ public class TransformConstraintData extends ConstraintData {
|
||||
else if (value < -PI) //
|
||||
value += PI2;
|
||||
}
|
||||
value = by + value * constraint.mixShearY;
|
||||
value = by + value * pose.mixShearY;
|
||||
float s = (float)Math.sqrt(b * b + d * d);
|
||||
bone.b = cos(value) * s;
|
||||
bone.d = sin(value) * s;
|
||||
|
||||
@ -0,0 +1,98 @@
|
||||
/******************************************************************************
|
||||
* 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;
|
||||
|
||||
/** Stores a pose for a transform constraint. */
|
||||
public class TransformConstraintPose {
|
||||
float mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY;
|
||||
|
||||
public void set (TransformConstraintPose pose) {
|
||||
mixRotate = pose.mixRotate;
|
||||
mixX = pose.mixX;
|
||||
mixY = pose.mixY;
|
||||
mixScaleX = pose.mixScaleX;
|
||||
mixScaleY = pose.mixScaleY;
|
||||
mixShearY = pose.mixShearY;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. */
|
||||
public float getMixRotate () {
|
||||
return mixRotate;
|
||||
}
|
||||
|
||||
public void setMixRotate (float mixRotate) {
|
||||
this.mixRotate = mixRotate;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. */
|
||||
public float getMixX () {
|
||||
return mixX;
|
||||
}
|
||||
|
||||
public void setMixX (float mixX) {
|
||||
this.mixX = mixX;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. */
|
||||
public float getMixY () {
|
||||
return mixY;
|
||||
}
|
||||
|
||||
public void setMixY (float mixY) {
|
||||
this.mixY = mixY;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained scale X. */
|
||||
public float getMixScaleX () {
|
||||
return mixScaleX;
|
||||
}
|
||||
|
||||
public void setMixScaleX (float mixScaleX) {
|
||||
this.mixScaleX = mixScaleX;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained scale X. */
|
||||
public float getMixScaleY () {
|
||||
return mixScaleY;
|
||||
}
|
||||
|
||||
public void setMixScaleY (float mixScaleY) {
|
||||
this.mixScaleY = mixScaleY;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained shear Y. */
|
||||
public float getMixShearY () {
|
||||
return mixShearY;
|
||||
}
|
||||
|
||||
public void setMixShearY (float mixShearY) {
|
||||
this.mixShearY = mixShearY;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user