[libgdx] Renamed transform constraint target->source and path constraint target->slot.

This commit is contained in:
Nathan Sweet 2025-04-01 13:56:28 -04:00
parent 4eeb2b62cb
commit fcb9788e27
8 changed files with 142 additions and 143 deletions

View File

@ -52,7 +52,7 @@ public class PathConstraint implements Updatable {
final PathConstraintData data; final PathConstraintData data;
final Array<Bone> bones; final Array<Bone> bones;
Slot target; Slot slot;
float position, spacing, mixRotate, mixX, mixY; float position, spacing, mixRotate, mixX, mixY;
boolean active; boolean active;
@ -70,7 +70,7 @@ public class PathConstraint implements Updatable {
for (BoneData boneData : data.bones) for (BoneData boneData : data.bones)
bones.add(skeleton.bones.get(boneData.index)); bones.add(skeleton.bones.get(boneData.index));
target = skeleton.slots.get(data.target.index); slot = skeleton.slots.get(data.slot.index);
position = data.position; position = data.position;
spacing = data.spacing; spacing = data.spacing;
@ -101,7 +101,7 @@ public class PathConstraint implements Updatable {
/** Applies the constraint to the constrained bones. */ /** Applies the constraint to the constrained bones. */
public void update (Physics physics) { public void update (Physics physics) {
if (!(target.attachment instanceof PathAttachment pathAttachment)) return; if (!(slot.attachment instanceof PathAttachment pathAttachment)) return;
float mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY; float mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY;
if (mixRotate == 0 && mixX == 0 && mixY == 0) return; if (mixRotate == 0 && mixX == 0 && mixY == 0) return;
@ -172,7 +172,7 @@ public class PathConstraint implements Updatable {
tip = data.rotateMode == RotateMode.chain; tip = data.rotateMode == RotateMode.chain;
else { else {
tip = false; tip = false;
Bone p = target.bone; Bone p = slot.bone;
offsetRotation *= p.a * p.d - p.b * p.c > 0 ? degRad : -degRad; offsetRotation *= p.a * p.d - p.b * p.c > 0 ? degRad : -degRad;
} }
for (int i = 0, p = 3; i < boneCount; i++, p += 3) { for (int i = 0, p = 3; i < boneCount; i++, p += 3) {
@ -224,7 +224,7 @@ public class PathConstraint implements Updatable {
} }
float[] computeWorldPositions (PathAttachment path, int spacesCount, boolean tangents) { float[] computeWorldPositions (PathAttachment path, int spacesCount, boolean tangents) {
Slot target = this.target; Slot slot = this.slot;
float position = this.position; float position = this.position;
float[] spaces = this.spaces.items, out = this.positions.setSize(spacesCount * 3 + 2), world; float[] spaces = this.spaces.items, out = this.positions.setSize(spacesCount * 3 + 2), world;
boolean closed = path.getClosed(); boolean closed = path.getClosed();
@ -256,14 +256,14 @@ public class PathConstraint implements Updatable {
} else if (p < 0) { } else if (p < 0) {
if (prevCurve != BEFORE) { if (prevCurve != BEFORE) {
prevCurve = BEFORE; prevCurve = BEFORE;
path.computeWorldVertices(target, 2, 4, world, 0, 2); path.computeWorldVertices(slot, 2, 4, world, 0, 2);
} }
addBeforePosition(p, world, 0, out, o); addBeforePosition(p, world, 0, out, o);
continue; continue;
} else if (p > pathLength) { } else if (p > pathLength) {
if (prevCurve != AFTER) { if (prevCurve != AFTER) {
prevCurve = AFTER; prevCurve = AFTER;
path.computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2); path.computeWorldVertices(slot, verticesLength - 6, 4, world, 0, 2);
} }
addAfterPosition(p - pathLength, world, 0, out, o); addAfterPosition(p - pathLength, world, 0, out, o);
continue; continue;
@ -284,10 +284,10 @@ public class PathConstraint implements Updatable {
if (curve != prevCurve) { if (curve != prevCurve) {
prevCurve = curve; prevCurve = curve;
if (closed && curve == curveCount) { if (closed && curve == curveCount) {
path.computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2); path.computeWorldVertices(slot, verticesLength - 4, 4, world, 0, 2);
path.computeWorldVertices(target, 0, 4, world, 4, 2); path.computeWorldVertices(slot, 0, 4, world, 4, 2);
} else } else
path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2); path.computeWorldVertices(slot, curve * 6 + 2, 8, world, 0, 2);
} }
addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o, addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o,
tangents || (i > 0 && space < epsilon)); tangents || (i > 0 && space < epsilon));
@ -299,15 +299,15 @@ public class PathConstraint implements Updatable {
if (closed) { if (closed) {
verticesLength += 2; verticesLength += 2;
world = this.world.setSize(verticesLength); world = this.world.setSize(verticesLength);
path.computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2); path.computeWorldVertices(slot, 2, verticesLength - 4, world, 0, 2);
path.computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2); path.computeWorldVertices(slot, 0, 2, world, verticesLength - 4, 2);
world[verticesLength - 2] = world[0]; world[verticesLength - 2] = world[0];
world[verticesLength - 1] = world[1]; world[verticesLength - 1] = world[1];
} else { } else {
curveCount--; curveCount--;
verticesLength -= 4; verticesLength -= 4;
world = this.world.setSize(verticesLength); world = this.world.setSize(verticesLength);
path.computeWorldVertices(target, 2, verticesLength, world, 0, 2); path.computeWorldVertices(slot, 2, verticesLength, world, 0, 2);
} }
// Curve lengths. // Curve lengths.
@ -532,13 +532,13 @@ public class PathConstraint implements Updatable {
} }
/** The slot whose path attachment will be used to constrained the bones. */ /** The slot whose path attachment will be used to constrained the bones. */
public Slot getTarget () { public Slot getSlot () {
return target; return slot;
} }
public void setTarget (Slot target) { public void setSlot (Slot slot) {
if (target == null) throw new IllegalArgumentException("target cannot be null."); if (slot == null) throw new IllegalArgumentException("slot cannot be null.");
this.target = target; this.slot = slot;
} }
public boolean isActive () { public boolean isActive () {

View File

@ -36,7 +36,7 @@ import com.badlogic.gdx.utils.Array;
* See <a href="https://esotericsoftware.com/spine-path-constraints">Path constraints</a> in the Spine User Guide. */ * See <a href="https://esotericsoftware.com/spine-path-constraints">Path constraints</a> in the Spine User Guide. */
public class PathConstraintData extends ConstraintData { public class PathConstraintData extends ConstraintData {
final Array<BoneData> bones = new Array(); final Array<BoneData> bones = new Array();
SlotData target; SlotData slot;
PositionMode positionMode; PositionMode positionMode;
SpacingMode spacingMode; SpacingMode spacingMode;
RotateMode rotateMode; RotateMode rotateMode;
@ -53,13 +53,13 @@ public class PathConstraintData extends ConstraintData {
} }
/** The slot whose path attachment will be used to constrained the bones. */ /** The slot whose path attachment will be used to constrained the bones. */
public SlotData getTarget () { public SlotData getSlot () {
return target; return slot;
} }
public void setTarget (SlotData target) { public void setSlot (SlotData slot) {
if (target == null) throw new IllegalArgumentException("target cannot be null."); if (slot == null) throw new IllegalArgumentException("slot cannot be null.");
this.target = target; this.slot = slot;
} }
/** The mode for positioning the first bone on the path. */ /** The mode for positioning the first bone on the path. */

View File

@ -238,8 +238,7 @@ public class Skeleton {
&& (!constraint.data.skinRequired || (skin != null && skin.constraints.contains(constraint.data, true))); && (!constraint.data.skinRequired || (skin != null && skin.constraints.contains(constraint.data, true)));
if (!constraint.active) return; if (!constraint.active) return;
Bone target = constraint.target; sortBone(constraint.target);
sortBone(target);
Array<Bone> constrained = constraint.bones; Array<Bone> constrained = constraint.bones;
Bone parent = constrained.first(); Bone parent = constrained.first();
@ -259,15 +258,15 @@ public class Skeleton {
} }
private void sortTransformConstraint (TransformConstraint constraint) { private void sortTransformConstraint (TransformConstraint constraint) {
constraint.active = constraint.target.active constraint.active = constraint.source.active
&& (!constraint.data.skinRequired || (skin != null && skin.constraints.contains(constraint.data, true))); && (!constraint.data.skinRequired || (skin != null && skin.constraints.contains(constraint.data, true)));
if (!constraint.active) return; if (!constraint.active) return;
sortBone(constraint.target); sortBone(constraint.source);
Object[] constrained = constraint.bones.items; Object[] constrained = constraint.bones.items;
int boneCount = constraint.bones.size; int boneCount = constraint.bones.size;
if (constraint.data.localFrom) { if (constraint.data.localSource) {
for (int i = 0; i < boneCount; i++) { for (int i = 0; i < boneCount; i++) {
var child = (Bone)constrained[i]; var child = (Bone)constrained[i];
sortBone(child.parent); sortBone(child.parent);
@ -287,11 +286,11 @@ public class Skeleton {
} }
private void sortPathConstraint (PathConstraint constraint) { private void sortPathConstraint (PathConstraint constraint) {
constraint.active = constraint.target.bone.active constraint.active = constraint.slot.bone.active
&& (!constraint.data.skinRequired || (skin != null && skin.constraints.contains(constraint.data, true))); && (!constraint.data.skinRequired || (skin != null && skin.constraints.contains(constraint.data, true)));
if (!constraint.active) return; if (!constraint.active) return;
Slot slot = constraint.target; Slot slot = constraint.slot;
int slotIndex = slot.getData().index; int slotIndex = slot.getData().index;
Bone slotBone = slot.bone; Bone slotBone = slot.bone;
if (skin != null) sortPathConstraintAttachment(skin, slotIndex, slotBone); if (skin != null) sortPathConstraintAttachment(skin, slotIndex, slotBone);

View File

@ -280,11 +280,11 @@ public class SkeletonBinary extends SkeletonLoader {
Object[] constraintBones = data.bones.setSize(nn = input.readInt(true)); Object[] constraintBones = data.bones.setSize(nn = input.readInt(true));
for (int ii = 0; ii < nn; ii++) for (int ii = 0; ii < nn; ii++)
constraintBones[ii] = bones[input.readInt(true)]; constraintBones[ii] = bones[input.readInt(true)];
data.target = (BoneData)bones[input.readInt(true)]; data.source = (BoneData)bones[input.readInt(true)];
int flags = input.read(); int flags = input.read();
data.skinRequired = (flags & 1) != 0; data.skinRequired = (flags & 1) != 0;
data.localFrom = (flags & 2) != 0; data.localSource = (flags & 2) != 0;
data.localTo = (flags & 4) != 0; data.localTarget = (flags & 4) != 0;
data.relative = (flags & 8) != 0; data.relative = (flags & 8) != 0;
data.clamp = (flags & 16) != 0; data.clamp = (flags & 16) != 0;
Object[] froms = data.properties.setSize(nn = flags >> 5); Object[] froms = data.properties.setSize(nn = flags >> 5);
@ -336,7 +336,7 @@ public class SkeletonBinary extends SkeletonLoader {
Object[] constraintBones = data.bones.setSize(nn = input.readInt(true)); Object[] constraintBones = data.bones.setSize(nn = input.readInt(true));
for (int ii = 0; ii < nn; ii++) for (int ii = 0; ii < nn; ii++)
constraintBones[ii] = bones[input.readInt(true)]; constraintBones[ii] = bones[input.readInt(true)];
data.target = (SlotData)slots[input.readInt(true)]; data.slot = (SlotData)slots[input.readInt(true)];
int flags = input.read(); int flags = input.read();
data.positionMode = PositionMode.values[flags & 1]; data.positionMode = PositionMode.values[flags & 1];
data.spacingMode = SpacingMode.values[(flags >> 1) & 3]; data.spacingMode = SpacingMode.values[(flags >> 1) & 3];

View File

@ -252,12 +252,12 @@ public class SkeletonJson extends SkeletonLoader {
data.bones.add(bone); data.bones.add(bone);
} }
String targetName = constraintMap.getString("target"); String sourceName = constraintMap.getString("source");
data.target = skeletonData.findBone(targetName); data.source = skeletonData.findBone(sourceName);
if (data.target == null) throw new SerializationException("Transform constraint target bone not found: " + targetName); if (data.source == null) throw new SerializationException("Transform constraint source bone not found: " + sourceName);
data.localFrom = constraintMap.getBoolean("localFrom", false); data.localSource = constraintMap.getBoolean("localSource", false);
data.localTo = constraintMap.getBoolean("localTo", false); data.localTarget = constraintMap.getBoolean("localTarget", false);
data.relative = constraintMap.getBoolean("relative", false); data.relative = constraintMap.getBoolean("relative", false);
data.clamp = constraintMap.getBoolean("clamp", false); data.clamp = constraintMap.getBoolean("clamp", false);
@ -312,9 +312,9 @@ public class SkeletonJson extends SkeletonLoader {
data.bones.add(bone); data.bones.add(bone);
} }
String targetName = constraintMap.getString("target"); String slotName = constraintMap.getString("slot");
data.target = skeletonData.findSlot(targetName); data.slot = skeletonData.findSlot(slotName);
if (data.target == null) throw new SerializationException("Path target slot not found: " + targetName); if (data.slot == null) throw new SerializationException("Path slot not found: " + slotName);
data.positionMode = PositionMode.valueOf(constraintMap.getString("positionMode", "percent")); data.positionMode = PositionMode.valueOf(constraintMap.getString("positionMode", "percent"));
data.spacingMode = SpacingMode.valueOf(constraintMap.getString("spacingMode", "length")); data.spacingMode = SpacingMode.valueOf(constraintMap.getString("spacingMode", "length"));

View File

@ -39,13 +39,13 @@ import com.esotericsoftware.spine.TransformConstraintData.FromProperty;
import com.esotericsoftware.spine.TransformConstraintData.ToProperty; import com.esotericsoftware.spine.TransformConstraintData.ToProperty;
/** Stores the current pose for a transform constraint. A transform constraint adjusts the world transform of the constrained /** Stores the current pose for a transform constraint. A transform constraint adjusts the world transform of the constrained
* bones to match that of the target bone. * bones to match that of the source bone.
* <p> * <p>
* See <a href="https://esotericsoftware.com/spine-transform-constraints">Transform constraints</a> in the Spine User Guide. */ * See <a href="https://esotericsoftware.com/spine-transform-constraints">Transform constraints</a> in the Spine User Guide. */
public class TransformConstraint implements Updatable { public class TransformConstraint implements Updatable {
final TransformConstraintData data; final TransformConstraintData data;
final Array<Bone> bones; final Array<Bone> bones;
Bone target; Bone source;
float mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY; float mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY;
boolean active; boolean active;
@ -60,7 +60,7 @@ public class TransformConstraint implements Updatable {
for (BoneData boneData : data.bones) for (BoneData boneData : data.bones)
bones.add(skeleton.bones.get(boneData.index)); bones.add(skeleton.bones.get(boneData.index));
target = skeleton.bones.get(data.target.index); source = skeleton.bones.get(data.source.index);
mixRotate = data.mixRotate; mixRotate = data.mixRotate;
mixX = data.mixX; mixX = data.mixX;
@ -96,8 +96,8 @@ public class TransformConstraint implements Updatable {
public void update (Physics physics) { public void update (Physics physics) {
if (mixRotate == 0 && mixX == 0 && mixY == 0 && mixScaleX == 0 && mixScaleY == 0 && mixShearY == 0) return; if (mixRotate == 0 && mixX == 0 && mixY == 0 && mixScaleX == 0 && mixScaleY == 0 && mixShearY == 0) return;
boolean localFrom = data.localFrom, localTo = data.localTo, relative = data.relative, clamp = data.clamp; boolean localFrom = data.localSource, localTarget = data.localTarget, relative = data.relative, clamp = data.clamp;
Bone target = this.target; Bone source = this.source;
Object[] fromItems = data.properties.items; Object[] fromItems = data.properties.items;
int fn = data.properties.size; int fn = data.properties.size;
Object[] bones = this.bones.items; Object[] bones = this.bones.items;
@ -107,7 +107,7 @@ public class TransformConstraint implements Updatable {
var from = (FromProperty)fromItems[f]; var from = (FromProperty)fromItems[f];
float mix = from.mix(this); float mix = from.mix(this);
if (mix != 0) { if (mix != 0) {
float value = from.value(target, localFrom) - from.offset; float value = from.value(source, localFrom) - from.offset;
Object[] toItems = from.to.items; Object[] toItems = from.to.items;
for (int t = 0, tn = from.to.size; t < tn; t++) { for (int t = 0, tn = from.to.size; t < tn; t++) {
var to = (ToProperty)toItems[t]; var to = (ToProperty)toItems[t];
@ -118,11 +118,11 @@ public class TransformConstraint implements Updatable {
else else
clamped = clamp(clamped, to.max, to.offset); clamped = clamp(clamped, to.max, to.offset);
} }
to.apply(bone, clamped, localTo, relative, mix); to.apply(bone, clamped, localTarget, relative, mix);
} }
} }
} }
if (localTo) if (localTarget)
bone.update(null); bone.update(null);
else else
bone.updateAppliedTransform(); bone.updateAppliedTransform();
@ -134,14 +134,14 @@ public class TransformConstraint implements Updatable {
return bones; return bones;
} }
/** The target bone whose world transform will be copied to the constrained bones. */ /** The bone whose world transform will be copied to the constrained bones. */
public Bone getTarget () { public Bone getSource () {
return target; return source;
} }
public void setTarget (Bone target) { public void setSource (Bone source) {
if (target == null) throw new IllegalArgumentException("target cannot be null."); if (source == null) throw new IllegalArgumentException("source cannot be null.");
this.target = target; this.source = source;
} }
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. */ /** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. */

View File

@ -38,9 +38,9 @@ import com.badlogic.gdx.utils.Array;
* See <a href="https://esotericsoftware.com/spine-transform-constraints">Transform constraints</a> in the Spine User Guide. */ * See <a href="https://esotericsoftware.com/spine-transform-constraints">Transform constraints</a> in the Spine User Guide. */
public class TransformConstraintData extends ConstraintData { public class TransformConstraintData extends ConstraintData {
final Array<BoneData> bones = new Array(); final Array<BoneData> bones = new Array();
BoneData target; BoneData source;
float mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY; float mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY;
boolean localFrom, localTo, relative, clamp; boolean localSource, localTarget, relative, clamp;
final Array<FromProperty> properties = new Array(); final Array<FromProperty> properties = new Array();
public TransformConstraintData (String name) { public TransformConstraintData (String name) {
@ -52,14 +52,14 @@ public class TransformConstraintData extends ConstraintData {
return bones; return bones;
} }
/** The target bone whose world transform will be copied to the constrained bones. */ /** The bone whose world transform will be copied to the constrained bones. */
public BoneData getTarget () { public BoneData getSource () {
return target; return source;
} }
public void setTarget (BoneData target) { public void setSource (BoneData source) {
if (target == null) throw new IllegalArgumentException("target cannot be null."); if (source == null) throw new IllegalArgumentException("source cannot be null.");
this.target = target; this.source = source;
} }
/** The mapping of transform properties to other transform properties. */ /** The mapping of transform properties to other transform properties. */
@ -121,25 +121,25 @@ public class TransformConstraintData extends ConstraintData {
this.mixShearY = mixShearY; this.mixShearY = mixShearY;
} }
/** Reads the target bone's local transform instead of its world transform. */ /** Reads the source bone's local transform instead of its world transform. */
public boolean getLocalFrom () { public boolean getLocalSource () {
return localFrom; return localSource;
} }
public void setLocalFrom (boolean localFrom) { public void setLocalSource (boolean localSource) {
this.localFrom = localFrom; this.localSource = localSource;
} }
/** Sets the constrained bones' local transforms instead of their world transforms. */ /** Sets the constrained bones' local transforms instead of their world transforms. */
public boolean getLocalTo () { public boolean getLocalTarget () {
return localTo; return localTarget;
} }
public void setLocalTo (boolean localTo) { public void setLocalTarget (boolean localTarget) {
this.localTo = localTo; this.localTarget = localTarget;
} }
/** Adds the target bone transform to the constrained bones instead of setting it absolutely. */ /** Adds the source bone transform to the constrained bones instead of setting it absolutely. */
public boolean getRelative () { public boolean getRelative () {
return relative; return relative;
} }
@ -165,11 +165,11 @@ public class TransformConstraintData extends ConstraintData {
/** Constrained properties. */ /** Constrained properties. */
public final Array<ToProperty> to = new Array(); public final Array<ToProperty> to = new Array();
/** Reads this property from the specified bone. */
abstract public float value (Bone target, boolean local);
/** Reads the mix for this property from the specified constraint. */ /** Reads the mix for this property from the specified constraint. */
abstract public float mix (TransformConstraint constraint); abstract public float mix (TransformConstraint constraint);
/** Reads this property from the specified bone. */
abstract public float value (Bone source, boolean local);
} }
/** Constrained property for a {@link TransformConstraint}. */ /** Constrained property for a {@link TransformConstraint}. */
@ -184,26 +184,26 @@ public class TransformConstraintData extends ConstraintData {
public float scale; public float scale;
/** Applies the value to this property. */ /** Applies the value to this property. */
abstract public void apply (Bone bone, float value, boolean local, boolean relative, float mix); abstract public void apply (Bone target, float value, boolean local, boolean relative, float mix);
} }
static public class FromRotate extends FromProperty { static public class FromRotate extends FromProperty {
public float value (Bone target, boolean local) {
return local ? target.arotation : atan2(target.c, target.a) * radDeg;
}
public float mix (TransformConstraint constraint) { public float mix (TransformConstraint constraint) {
return constraint.mixRotate; return constraint.mixRotate;
} }
public float value (Bone source, boolean local) {
return local ? source.arotation : atan2(source.c, source.a) * radDeg;
}
} }
static public class ToRotate extends ToProperty { static public class ToRotate extends ToProperty {
public void apply (Bone bone, float value, boolean local, boolean relative, float mix) { public void apply (Bone target, float value, boolean local, boolean relative, float mix) {
if (local) { if (local) {
if (!relative) value -= bone.arotation; if (!relative) value -= target.arotation;
bone.arotation += value * mix; target.arotation += value * mix;
} else { } else {
float a = bone.a, b = bone.b, c = bone.c, d = bone.d; float a = target.a, b = target.b, c = target.c, d = target.d;
value *= degRad; value *= degRad;
if (!relative) value -= atan2(c, a); if (!relative) value -= atan2(c, a);
if (value > PI) if (value > PI)
@ -212,142 +212,142 @@ public class TransformConstraintData extends ConstraintData {
value += PI2; value += PI2;
value *= mix; value *= mix;
float cos = cos(value), sin = sin(value); float cos = cos(value), sin = sin(value);
bone.a = cos * a - sin * c; target.a = cos * a - sin * c;
bone.b = cos * b - sin * d; target.b = cos * b - sin * d;
bone.c = sin * a + cos * c; target.c = sin * a + cos * c;
bone.d = sin * b + cos * d; target.d = sin * b + cos * d;
} }
} }
} }
static public class FromX extends FromProperty { static public class FromX extends FromProperty {
public float value (Bone target, boolean local) {
return local ? target.ax : target.worldX;
}
public float mix (TransformConstraint constraint) { public float mix (TransformConstraint constraint) {
return constraint.mixX; return constraint.mixX;
} }
public float value (Bone source, boolean local) {
return local ? source.ax : source.worldX;
}
} }
static public class ToX extends ToProperty { static public class ToX extends ToProperty {
public void apply (Bone bone, float value, boolean local, boolean relative, float mix) { public void apply (Bone target, float value, boolean local, boolean relative, float mix) {
if (local) { if (local) {
if (!relative) value -= bone.ax; if (!relative) value -= target.ax;
bone.ax += value * mix; target.ax += value * mix;
} else { } else {
if (!relative) value -= bone.worldX; if (!relative) value -= target.worldX;
bone.worldX += value * mix; target.worldX += value * mix;
} }
} }
} }
static public class FromY extends FromProperty { static public class FromY extends FromProperty {
public float value (Bone target, boolean local) {
return local ? target.ay : target.worldY;
}
public float mix (TransformConstraint constraint) { public float mix (TransformConstraint constraint) {
return constraint.mixY; return constraint.mixY;
} }
public float value (Bone source, boolean local) {
return local ? source.ay : source.worldY;
}
} }
static public class ToY extends ToProperty { static public class ToY extends ToProperty {
public void apply (Bone bone, float value, boolean local, boolean relative, float mix) { public void apply (Bone target, float value, boolean local, boolean relative, float mix) {
if (local) { if (local) {
if (!relative) value -= bone.ay; if (!relative) value -= target.ay;
bone.ay += value * mix; target.ay += value * mix;
} else { } else {
if (!relative) value -= bone.worldY; if (!relative) value -= target.worldY;
bone.worldY += value * mix; target.worldY += value * mix;
} }
} }
} }
static public class FromScaleX extends FromProperty { static public class FromScaleX extends FromProperty {
public float value (Bone target, boolean local) {
return local ? target.ascaleX : (float)Math.sqrt(target.a * target.a + target.c * target.c);
}
public float mix (TransformConstraint constraint) { public float mix (TransformConstraint constraint) {
return constraint.mixScaleX; return constraint.mixScaleX;
} }
public float value (Bone source, boolean local) {
return local ? source.ascaleX : (float)Math.sqrt(source.a * source.a + source.c * source.c);
}
} }
static public class ToScaleX extends ToProperty { static public class ToScaleX extends ToProperty {
public void apply (Bone bone, float value, boolean local, boolean relative, float mix) { public void apply (Bone target, float value, boolean local, boolean relative, float mix) {
if (local) { if (local) {
if (relative) if (relative)
bone.ascaleX *= 1 + ((value - 1) * mix); target.ascaleX *= 1 + ((value - 1) * mix);
else if (bone.ascaleX != 0) // else if (target.ascaleX != 0) //
bone.ascaleX = 1 + (value / bone.ascaleX - 1) * mix; target.ascaleX = 1 + (value / target.ascaleX - 1) * mix;
} else { } else {
float s; float s;
if (relative) if (relative)
s = 1 + (value - 1) * mix; s = 1 + (value - 1) * mix;
else { else {
s = (float)Math.sqrt(bone.a * bone.a + bone.c * bone.c); s = (float)Math.sqrt(target.a * target.a + target.c * target.c);
if (s != 0) s = 1 + (value / s - 1) * mix; if (s != 0) s = 1 + (value / s - 1) * mix;
} }
bone.a *= s; target.a *= s;
bone.c *= s; target.c *= s;
} }
} }
} }
static public class FromScaleY extends FromProperty { static public class FromScaleY extends FromProperty {
public float value (Bone target, boolean local) {
return local ? target.ascaleY : (float)Math.sqrt(target.b * target.b + target.d * target.d);
}
public float mix (TransformConstraint constraint) { public float mix (TransformConstraint constraint) {
return constraint.mixScaleY; return constraint.mixScaleY;
} }
public float value (Bone source, boolean local) {
return local ? source.ascaleY : (float)Math.sqrt(source.b * source.b + source.d * source.d);
}
} }
static public class ToScaleY extends ToProperty { static public class ToScaleY extends ToProperty {
public void apply (Bone bone, float value, boolean local, boolean relative, float mix) { public void apply (Bone target, float value, boolean local, boolean relative, float mix) {
if (local) { if (local) {
if (relative) if (relative)
bone.ascaleY *= 1 + ((value - 1) * mix); target.ascaleY *= 1 + ((value - 1) * mix);
else if (bone.ascaleY != 0) // else if (target.ascaleY != 0) //
bone.ascaleY = 1 + (value / bone.ascaleY - 1) * mix; target.ascaleY = 1 + (value / target.ascaleY - 1) * mix;
} else { } else {
float s; float s;
if (relative) if (relative)
s = 1 + (value - 1) * mix; s = 1 + (value - 1) * mix;
else { else {
s = (float)Math.sqrt(bone.b * bone.b + bone.d * bone.d); s = (float)Math.sqrt(target.b * target.b + target.d * target.d);
if (s != 0) s = 1 + (value / s - 1) * mix; if (s != 0) s = 1 + (value / s - 1) * mix;
} }
bone.b *= s; target.b *= s;
bone.d *= s; target.d *= s;
} }
} }
} }
static public class FromShearY extends FromProperty { static public class FromShearY extends FromProperty {
public float value (Bone target, boolean local) {
return local ? target.ashearY : (atan2(target.d, target.b) - atan2(target.c, target.a)) * radDeg - 90;
}
public float mix (TransformConstraint constraint) { public float mix (TransformConstraint constraint) {
return constraint.mixShearY; return constraint.mixShearY;
} }
public float value (Bone source, boolean local) {
return local ? source.ashearY : (atan2(source.d, source.b) - atan2(source.c, source.a)) * radDeg - 90;
}
} }
static public class ToShearY extends ToProperty { static public class ToShearY extends ToProperty {
public void apply (Bone bone, float value, boolean local, boolean relative, float mix) { public void apply (Bone target, float value, boolean local, boolean relative, float mix) {
if (local) { if (local) {
if (!relative) value -= bone.ashearY; if (!relative) value -= target.ashearY;
bone.ashearY += value * mix; target.ashearY += value * mix;
} else { } else {
float b = bone.b, d = bone.d, by = atan2(d, b); float b = target.b, d = target.d, by = atan2(d, b);
value = (value + 90) * degRad; value = (value + 90) * degRad;
if (relative) if (relative)
value -= PI / 2; value -= PI / 2;
else { else {
value -= by - atan2(bone.c, bone.a); value -= by - atan2(target.c, target.a);
if (value > PI) if (value > PI)
value -= PI2; value -= PI2;
else if (value < -PI) // else if (value < -PI) //
@ -355,8 +355,8 @@ public class TransformConstraintData extends ConstraintData {
} }
value = by + value * mix; value = by + value * mix;
float s = (float)Math.sqrt(b * b + d * d); float s = (float)Math.sqrt(b * b + d * d);
bone.b = cos(value) * s; target.b = cos(value) * s;
bone.d = sin(value) * s; target.d = sin(value) * s;
} }
} }
} }

View File

@ -34,8 +34,8 @@ import com.badlogic.gdx.scenes.scene2d.utils.BaseDrawable;
import com.esotericsoftware.spine.AnimationState; import com.esotericsoftware.spine.AnimationState;
import com.esotericsoftware.spine.Skeleton; import com.esotericsoftware.spine.Skeleton;
import com.esotericsoftware.spine.SkeletonRenderer;
import com.esotericsoftware.spine.Skeleton.Physics; 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 /** A scene2d drawable that draws a skeleton. The animation state and skeleton must be updated each frame, or
* {@link #update(float)} called each frame. */ * {@link #update(float)} called each frame. */