[libgdx] Animation/AnimationState clean up, javadocs.

This commit is contained in:
Nathan Sweet 2026-03-23 01:54:09 -04:00
parent 2f12895884
commit 39fe4692db
22 changed files with 278 additions and 180 deletions

View File

@ -64,7 +64,8 @@ public class Animation {
setTimelines(timelines);
}
/** If the returned array or the timelines it contains are modified, {@link #setTimelines(Array)} must be called. */
/** If this list or the timelines it contains are modified, the timelines must be set again to recompute the animation's bone
* indices and timeline property IDs. */
public Array<Timeline> getTimelines () {
return timelines;
}
@ -87,15 +88,17 @@ public class Animation {
bones.shrink();
}
/** Returns true if this animation contains a timeline with any of the specified property IDs. */
/** Returns true if this animation contains a timeline with any of the specified property IDs.
* <p>
* See {@link Timeline#getPropertyIds()}. */
public boolean hasTimeline (String[] propertyIds) {
for (String id : propertyIds)
if (timelineIds.contains(id)) return true;
return false;
}
/** The duration of the animation in seconds, which is usually the highest time of all frames in the timeline. The duration is
* used to know when it has completed and when it should loop back to the start. */
/** The duration of the animation in seconds, which is usually the highest time of all frames in the timelines. The duration is
* used to know when the animation has completed and, for animations that repeat, when it should loop back to the start. */
public float getDuration () {
return duration;
}
@ -104,13 +107,16 @@ public class Animation {
this.duration = duration;
}
/** {@link Skeleton#getBones()} indices that this animation's timelines modify.
* <p>
* See {@link BoneTimeline#getBoneIndex()}. */
public IntArray getBones () {
return bones;
}
/** Applies the animation's timelines to the specified skeleton.
* <p>
* See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, boolean, boolean, boolean, boolean)}.
* See {@link Timeline#apply(Skeleton, float, float, Array, float, boolean, boolean, boolean, boolean)}.
* @param skeleton The skeleton the animation is applied to. This provides access to the bones, slots, and other skeleton
* components the timelines may change.
* @param lastTime The last time in seconds this animation was applied. Some timelines trigger only at discrete times, in which
@ -130,7 +136,7 @@ public class Animation {
* @param add If true, for timelines that support it, their values are added to the setup or current values (depending on
* <code>fromSetup</code>).
* @param out True when the animation is mixing out, else it is mixing in. Used by timelines that perform instant transitions.
* @param appliedPose True to modify the {@link Posed#getAppliedPose()}, else modify the {@link Posed#getPose()}. */
* @param appliedPose True to modify the {@link Posed#getAppliedPose()}, else the {@link Posed#getPose()} is modified. */
public void apply (Skeleton skeleton, float lastTime, float time, boolean loop, @Null Array<Event> events, float alpha,
boolean fromSetup, boolean add, boolean out, boolean appliedPose) {
if (skeleton == null) throw new IllegalArgumentException("skeleton cannot be null.");
@ -145,7 +151,9 @@ public class Animation {
timelines[i].apply(skeleton, lastTime, time, events, alpha, fromSetup, add, out, appliedPose);
}
/** The animation's name, which is unique across all animations in the skeleton. */
/** The animation's name, unique across all animations in the skeleton.
* <p>
* See {@link SkeletonData#findAnimation(String)}. */
public String getName () {
return name;
}
@ -190,16 +198,17 @@ public class Animation {
return frames;
}
/** The number of entries stored per frame. */
/** The number of values stored per frame. */
public int getFrameEntries () {
return 1;
}
/** The number of frames for this timeline. */
/** The number of frames in this timeline. */
public int getFrameCount () {
return frames.length / getFrameEntries();
}
/** The duration of the timeline in seconds, which is usually the highest time of all frames in the timeline. */
public float getDuration () {
return frames[frames.length - getFrameEntries()];
}
@ -217,7 +226,7 @@ public class Animation {
/** Applies this timeline to the skeleton.
* @param skeleton The skeleton the timeline is applied to. This provides access to the bones, slots, and other skeleton
* components the timelines may change.
* @param lastTime The last time in seconds this timline was applied. Some timelines trigger only at discrete times, in
* @param lastTime The last time in seconds this timeline was applied. Some timelines trigger only at discrete times, in
* which case all keys are triggered between <code>lastTime</code> (exclusive) and <code>time</code> (inclusive).
* Pass -1 the first time a timeline is applied to ensure frame 0 is triggered.
* @param time The time in seconds the skeleton is being posed for. Timelines find the frame before and after this time and
@ -232,8 +241,9 @@ public class Animation {
* timeline values, no change is made before the first frame.
* @param add If true, for timelines that support it, their values are added to the setup or current values (depending on
* <code>fromSetup</code>).
* @param out True when the animation is mixing out, else it is mixing in.
* @param appliedPose True to modify the {@link Posed#getAppliedPose()}, else modify the {@link Posed#getPose()}. */
* @param out True when the animation is mixing out, else it is mixing in. Used by timelines that perform instant
* transitions.
* @param appliedPose True to modify the {@link Posed#getAppliedPose()}, else the {@link Posed#getPose()} is modified. */
abstract public void apply (Skeleton skeleton, float lastTime, float time, @Null Array<Event> events, float alpha,
boolean fromSetup, boolean add, boolean out, boolean appliedPose);
@ -258,7 +268,7 @@ public class Animation {
}
}
/** An interface for timelines that change the property of a slot. */
/** An interface for timelines that change a slot's properties. */
static public interface SlotTimeline {
/** The index of the slot in {@link Skeleton#getSlots()} that will be changed when this timeline is applied. */
public int getSlotIndex ();
@ -266,7 +276,9 @@ public class Animation {
/** The base class for timelines that interpolate between frame values using stepped, linear, or a Bezier curve. */
static abstract public class CurveTimeline extends Timeline {
static public final int LINEAR = 0, STEPPED = 1, BEZIER = 2, BEZIER_SIZE = 18;
static public final int LINEAR = 0, STEPPED = 1, BEZIER = 2;
/** The number of values stored for each 10 segment Bezier curve. */
static public final int BEZIER_SIZE = 18;
float[] curves;
@ -367,7 +379,7 @@ public class Animation {
}
}
/** The base class for a {@link CurveTimeline} that sets one property. */
/** The base class for a {@link CurveTimeline} that sets one property with a curve. */
static abstract public class CurveTimeline1 extends CurveTimeline {
static public final int ENTRIES = 2;
static final int VALUE = 1;
@ -413,24 +425,48 @@ public class Animation {
};
}
/** Returns the interpolated value for properties relative to the setup value. The timeline value is added to the setup
* value, rather than replacing it.
* <p>
* See {@link Timeline#apply(Skeleton, float, float, Array, float, boolean, boolean, boolean, boolean)}.
* @param current The current value for the property.
* @param setup The setup value for the property. */
public float getRelativeValue (float time, float alpha, boolean fromSetup, boolean add, float current, float setup) {
if (time < frames[0]) return fromSetup ? setup : current;
float value = getCurveValue(time);
return fromSetup ? setup + value * alpha : current + (add ? value : value + setup - current) * alpha;
}
/** Returns the interpolated value for properties set as absolute values. The timeline value replaces the setup value,
* rather than being relative to it.
* <p>
* See {@link Timeline#apply(Skeleton, float, float, Array, float, boolean, boolean, boolean, boolean)}.
* @param current The current value for the property.
* @param setup The setup value for the property. */
public float getAbsoluteValue (float time, float alpha, boolean fromSetup, boolean add, float current, float setup) {
if (time < frames[0]) return fromSetup ? setup : current;
float value = getCurveValue(time);
return fromSetup ? setup + (value - setup) * alpha : current + (add ? value : value - current) * alpha;
}
/** Returns the interpolated value for properties set as absolute values, using the specified timeline value rather than
* calling {@link #getCurveValue(float)}.
* <p>
* See {@link Timeline#apply(Skeleton, float, float, Array, float, boolean, boolean, boolean, boolean)}.
* @param current The current value for the property.
* @param setup The setup value for the property.
* @param value The timeline value to apply. */
public float getAbsoluteValue (float time, float alpha, boolean fromSetup, boolean add, float current, float setup,
float value) {
if (time < frames[0]) return fromSetup ? setup : current;
return fromSetup ? setup + (value - setup) * alpha : current + (add ? value : value - current) * alpha;
}
/** Returns the interpolated value for scale properties. The timeline and setup values are multiplied and sign adjusted.
* <p>
* See {@link Timeline#apply(Skeleton, float, float, Array, float, boolean, boolean, boolean, boolean)}.
* @param current The current value for the property.
* @param setup The setup value for the property. */
public float getScaleValue (float time, float alpha, boolean fromSetup, boolean add, boolean out, float current,
float setup) {
if (time < frames[0]) return fromSetup ? setup : current;
@ -444,12 +480,13 @@ public class Animation {
}
}
/** An interface for timelines that change the property of a bone. */
/** An interface for timelines that change a bone's properties. */
static public interface BoneTimeline {
/** The index of the bone in {@link Skeleton#getBones()} that will be changed when this timeline is applied. */
/** The index of the bone in {@link Skeleton#getBones()} that is changed by this timeline. */
public int getBoneIndex ();
}
/** The base class for timelines that change 1 bone property with a curve. */
static abstract public class BoneTimeline1 extends CurveTimeline1 implements BoneTimeline {
final int boneIndex;
@ -473,7 +510,7 @@ public class Animation {
boolean out);
}
/** The base class for a {@link CurveTimeline} that is a {@link BoneTimeline} and sets two properties. */
/** The base class for timelines that change two bone properties with a curve. */
static abstract public class BoneTimeline2 extends CurveTimeline implements BoneTimeline {
static public final int ENTRIES = 3;
static final int VALUE1 = 1, VALUE2 = 2;
@ -515,7 +552,7 @@ public class Animation {
boolean out);
}
/** Changes a bone's local {@link BoneLocal#getRotation()}. */
/** Changes {@link BoneLocal#getRotation()}. */
static public class RotateTimeline extends BoneTimeline1 {
public RotateTimeline (int frameCount, int bezierCount, int boneIndex) {
super(frameCount, bezierCount, boneIndex, Property.rotate);
@ -527,7 +564,7 @@ public class Animation {
}
}
/** Changes a bone's local {@link BoneLocal#getX()} and {@link BoneLocal#getY()}. */
/** Changes {@link BoneLocal#getX()} and {@link BoneLocal#getY()}. */
static public class TranslateTimeline extends BoneTimeline2 {
public TranslateTimeline (int frameCount, int bezierCount, int boneIndex) {
super(frameCount, bezierCount, boneIndex, Property.x, Property.y);
@ -578,7 +615,7 @@ public class Animation {
}
}
/** Changes a bone's local {@link BoneLocal#getX()}. */
/** Changes {@link BoneLocal#getX()}. */
static public class TranslateXTimeline extends BoneTimeline1 {
public TranslateXTimeline (int frameCount, int bezierCount, int boneIndex) {
super(frameCount, bezierCount, boneIndex, Property.x);
@ -590,7 +627,7 @@ public class Animation {
}
}
/** Changes a bone's local {@link BoneLocal#getY()}. */
/** Changes {@link BoneLocal#getY()}. */
static public class TranslateYTimeline extends BoneTimeline1 {
public TranslateYTimeline (int frameCount, int bezierCount, int boneIndex) {
super(frameCount, bezierCount, boneIndex, Property.y);
@ -602,7 +639,7 @@ public class Animation {
}
}
/** Changes a bone's local {@link BoneLocal#getScaleX()} and {@link BoneLocal#getScaleY()}. */
/** Changes {@link BoneLocal#getScaleX()} and {@link BoneLocal#getScaleY()}. */
static public class ScaleTimeline extends BoneTimeline2 {
public ScaleTimeline (int frameCount, int bezierCount, int boneIndex) {
super(frameCount, bezierCount, boneIndex, Property.scaleX, Property.scaleY);
@ -670,7 +707,7 @@ public class Animation {
}
}
/** Changes a bone's local {@link BoneLocal#getScaleX()}. */
/** Changes {@link BoneLocal#getScaleX()}. */
static public class ScaleXTimeline extends BoneTimeline1 {
public ScaleXTimeline (int frameCount, int bezierCount, int boneIndex) {
super(frameCount, bezierCount, boneIndex, Property.scaleX);
@ -682,7 +719,7 @@ public class Animation {
}
}
/** Changes a bone's local {@link BoneLocal#getScaleY()}. */
/** Changes {@link BoneLocal#getScaleY()}. */
static public class ScaleYTimeline extends BoneTimeline1 {
public ScaleYTimeline (int frameCount, int bezierCount, int boneIndex) {
super(frameCount, bezierCount, boneIndex, Property.scaleY);
@ -694,7 +731,7 @@ public class Animation {
}
}
/** Changes a bone's local {@link BoneLocal#getShearX()} and {@link BoneLocal#getShearY()}. */
/** Changes {@link BoneLocal#getShearX()} and {@link BoneLocal#getShearY()}. */
static public class ShearTimeline extends BoneTimeline2 {
public ShearTimeline (int frameCount, int bezierCount, int boneIndex) {
super(frameCount, bezierCount, boneIndex, Property.shearX, Property.shearY);
@ -745,7 +782,7 @@ public class Animation {
}
}
/** Changes a bone's local {@link BoneLocal#getShearX()}. */
/** Changes {@link BoneLocal#getShearX()}. */
static public class ShearXTimeline extends BoneTimeline1 {
public ShearXTimeline (int frameCount, int bezierCount, int boneIndex) {
super(frameCount, bezierCount, boneIndex, Property.shearX);
@ -757,7 +794,7 @@ public class Animation {
}
}
/** Changes a bone's local {@link BoneLocal#getShearY()}. */
/** Changes {@link BoneLocal#getShearY()}. */
static public class ShearYTimeline extends BoneTimeline1 {
public ShearYTimeline (int frameCount, int bezierCount, int boneIndex) {
super(frameCount, bezierCount, boneIndex, Property.shearY);
@ -769,7 +806,7 @@ public class Animation {
}
}
/** Changes a bone's {@link BoneLocal#getInherit()}. */
/** Changes {@link BoneLocal#getInherit()}. */
static public class InheritTimeline extends Timeline implements BoneTimeline {
static public final int ENTRIES = 2;
static private final int INHERIT = 1;
@ -817,6 +854,7 @@ public class Animation {
}
}
/** The base class for timelines that change any number of slot properties with a curve. */
static abstract public class SlotCurveTimeline extends CurveTimeline implements SlotTimeline {
final int slotIndex;
@ -838,7 +876,7 @@ public class Animation {
abstract protected void apply (Slot slot, SlotPose pose, float time, float alpha, boolean fromSetup, boolean add);
}
/** Changes a slot's {@link SlotPose#getColor()}. */
/** Changes {@link SlotPose#getColor()}. */
static public class RGBATimeline extends SlotCurveTimeline {
static public final int ENTRIES = 5;
static private final int R = 1, G = 2, B = 3, A = 4;
@ -915,7 +953,7 @@ public class Animation {
}
}
/** Changes the RGB for a slot's {@link SlotPose#getColor()}. */
/** Changes RGB for a slot's {@link SlotPose#getColor()}. */
static public class RGBTimeline extends SlotCurveTimeline {
static public final int ENTRIES = 4;
static private final int R = 1, G = 2, B = 3;
@ -995,7 +1033,7 @@ public class Animation {
}
}
/** Changes the alpha for a slot's {@link SlotPose#getColor()}. */
/** Changes alpha for a slot's {@link SlotPose#getColor()}. */
static public class AlphaTimeline extends CurveTimeline1 implements SlotTimeline {
final int slotIndex;
@ -1033,7 +1071,7 @@ public class Animation {
}
}
/** Changes a slot's {@link SlotPose#getColor()} and {@link SlotPose#getDarkColor()} for two color tinting. */
/** Changes {@link SlotPose#getColor()} and {@link SlotPose#getDarkColor()} for two color tinting. */
static public class RGBA2Timeline extends SlotCurveTimeline {
static public final int ENTRIES = 8;
static private final int R = 1, G = 2, B = 3, A = 4, R2 = 5, G2 = 6, B2 = 7;
@ -1144,7 +1182,7 @@ public class Animation {
}
}
/** Changes the RGB for a slot's {@link SlotPose#getColor()} and {@link SlotPose#getDarkColor()} for two color tinting. */
/** Changes RGB for a slot's {@link SlotPose#getColor()} and {@link SlotPose#getDarkColor()} for two color tinting. */
static public class RGB2Timeline extends SlotCurveTimeline {
static public final int ENTRIES = 7;
static private final int R = 1, G = 2, B = 3, R2 = 4, G2 = 5, B2 = 6;
@ -1256,7 +1294,7 @@ public class Animation {
}
}
/** Changes a slot's {@link SlotPose#getAttachment()}. */
/** Changes {@link SlotPose#getAttachment()}. */
static public class AttachmentTimeline extends Timeline implements SlotTimeline {
final int slotIndex;
final String[] attachmentNames;
@ -1306,7 +1344,7 @@ public class Animation {
}
}
/** Changes a slot's {@link SlotPose#getDeform()} to deform a {@link VertexAttachment}. */
/** Changes {@link SlotPose#getDeform()} to deform a {@link VertexAttachment}. */
static public class DeformTimeline extends SlotCurveTimeline {
final VertexAttachment attachment;
private final float[][] vertices;
@ -1516,7 +1554,7 @@ public class Animation {
}
}
/** Changes a slot's {@link SlotPose#getSequenceIndex()} for an attachment's {@link Sequence}. */
/** Changes {@link SlotPose#getSequenceIndex()} for an attachment's {@link Sequence}. */
static public class SequenceTimeline extends Timeline implements SlotTimeline {
static public final int ENTRIES = 3;
static private final int MODE = 1, DELAY = 2;
@ -1665,7 +1703,7 @@ public class Animation {
}
}
/** Changes a skeleton's {@link Skeleton#getDrawOrder()}. */
/** Changes {@link Skeleton#getDrawOrder()}. */
static public class DrawOrderTimeline extends Timeline {
static final String propertyID = Integer.toString(Property.drawOrder.ordinal());
static private final String[] propertyIds = {propertyID};
@ -1715,7 +1753,7 @@ public class Animation {
}
}
/** Changes a subset of a skeleton's {@link Skeleton#getDrawOrder()}. */
/** Changes a subset of {@link Skeleton#getDrawOrder()}. */
static public class DrawOrderFolderTimeline extends Timeline {
private final int[] slots;
private final boolean[] inFolder;
@ -1808,7 +1846,7 @@ public class Animation {
public int getConstraintIndex ();
}
/** Changes an IK constraint's {@link IkConstraintPose#getMix()}, {@link IkConstraintPose#getSoftness()},
/** Changes {@link IkConstraintPose#getMix()}, {@link IkConstraintPose#getSoftness()},
* {@link IkConstraintPose#getBendDirection()}, {@link IkConstraintPose#getStretch()}, and
* {@link IkConstraintPose#getCompress()}. */
static public class IkConstraintTimeline extends CurveTimeline implements ConstraintTimeline {
@ -1902,7 +1940,7 @@ public class Animation {
}
}
/** Changes a transform constraint's {@link TransformConstraintPose#getMixRotate()}, {@link TransformConstraintPose#getMixX()},
/** Changes {@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 implements ConstraintTimeline {
@ -2016,6 +2054,7 @@ public class Animation {
}
}
/** The base class for timelines that change 1 constraint property with a curve. */
static abstract public class ConstraintTimeline1 extends CurveTimeline1 implements ConstraintTimeline {
final int constraintIndex;
@ -2029,7 +2068,7 @@ public class Animation {
}
}
/** Changes a path constraint's {@link PathConstraintPose#getPosition()}. */
/** Changes {@link PathConstraintPose#getPosition()}. */
static public class PathConstraintPositionTimeline extends ConstraintTimeline1 {
public PathConstraintPositionTimeline (int frameCount, int bezierCount, int constraintIndex) {
super(frameCount, bezierCount, constraintIndex, Property.pathConstraintPosition);
@ -2046,7 +2085,7 @@ public class Animation {
}
}
/** Changes a path constraint's {@link PathConstraintPose#getSpacing()}. */
/** Changes {@link PathConstraintPose#getSpacing()}. */
static public class PathConstraintSpacingTimeline extends ConstraintTimeline1 {
public PathConstraintSpacingTimeline (int frameCount, int bezierCount, int constraintIndex) {
super(frameCount, bezierCount, constraintIndex, Property.pathConstraintSpacing);
@ -2062,7 +2101,7 @@ public class Animation {
}
}
/** Changes a path constraint's {@link PathConstraintPose#getMixRotate()}, {@link PathConstraintPose#getMixX()}, and
/** Changes {@link PathConstraintPose#getMixRotate()}, {@link PathConstraintPose#getMixX()}, and
* {@link PathConstraintPose#getMixY()}. */
static public class PathConstraintMixTimeline extends CurveTimeline implements ConstraintTimeline {
static public final int ENTRIES = 4;
@ -2186,7 +2225,7 @@ public class Animation {
abstract protected boolean global (PhysicsConstraintData constraint);
}
/** Changes a physics constraint's {@link PhysicsConstraintPose#getInertia()}. */
/** Changes {@link PhysicsConstraintPose#getInertia()}. */
static public class PhysicsConstraintInertiaTimeline extends PhysicsConstraintTimeline {
public PhysicsConstraintInertiaTimeline (int frameCount, int bezierCount, int constraintIndex) {
super(frameCount, bezierCount, constraintIndex, Property.physicsConstraintInertia);
@ -2205,7 +2244,7 @@ public class Animation {
}
}
/** Changes a physics constraint's {@link PhysicsConstraintPose#getStrength()}. */
/** Changes {@link PhysicsConstraintPose#getStrength()}. */
static public class PhysicsConstraintStrengthTimeline extends PhysicsConstraintTimeline {
public PhysicsConstraintStrengthTimeline (int frameCount, int bezierCount, int constraintIndex) {
super(frameCount, bezierCount, constraintIndex, Property.physicsConstraintStrength);
@ -2224,7 +2263,7 @@ public class Animation {
}
}
/** Changes a physics constraint's {@link PhysicsConstraintPose#getDamping()}. */
/** Changes {@link PhysicsConstraintPose#getDamping()}. */
static public class PhysicsConstraintDampingTimeline extends PhysicsConstraintTimeline {
public PhysicsConstraintDampingTimeline (int frameCount, int bezierCount, int constraintIndex) {
super(frameCount, bezierCount, constraintIndex, Property.physicsConstraintDamping);
@ -2243,7 +2282,7 @@ public class Animation {
}
}
/** Changes a physics constraint's {@link PhysicsConstraintPose#getMassInverse()}. The timeline values are not inverted. */
/** Changes {@link PhysicsConstraintPose#getMassInverse()}. The timeline values are not inverted. */
static public class PhysicsConstraintMassTimeline extends PhysicsConstraintTimeline {
public PhysicsConstraintMassTimeline (int frameCount, int bezierCount, int constraintIndex) {
super(frameCount, bezierCount, constraintIndex, Property.physicsConstraintMass);
@ -2262,7 +2301,7 @@ public class Animation {
}
}
/** Changes a physics constraint's {@link PhysicsConstraintPose#getWind()}. */
/** Changes {@link PhysicsConstraintPose#getWind()}. */
static public class PhysicsConstraintWindTimeline extends PhysicsConstraintTimeline {
public PhysicsConstraintWindTimeline (int frameCount, int bezierCount, int constraintIndex) {
super(frameCount, bezierCount, constraintIndex, Property.physicsConstraintWind);
@ -2282,7 +2321,7 @@ public class Animation {
}
}
/** Changes a physics constraint's {@link PhysicsConstraintPose#getGravity()}. */
/** Changes {@link PhysicsConstraintPose#getGravity()}. */
static public class PhysicsConstraintGravityTimeline extends PhysicsConstraintTimeline {
public PhysicsConstraintGravityTimeline (int frameCount, int bezierCount, int constraintIndex) {
super(frameCount, bezierCount, constraintIndex, Property.physicsConstraintGravity);
@ -2302,7 +2341,7 @@ public class Animation {
}
}
/** Changes a physics constraint's {@link PhysicsConstraintPose#getMix()}. */
/** Changes {@link PhysicsConstraintPose#getMix()}. */
static public class PhysicsConstraintMixTimeline extends PhysicsConstraintTimeline {
public PhysicsConstraintMixTimeline (int frameCount, int bezierCount, int constraintIndex) {
super(frameCount, bezierCount, constraintIndex, Property.physicsConstraintMix);
@ -2382,7 +2421,7 @@ public class Animation {
}
}
/** Changes a slider's {@link SliderPose#getTime()}. */
/** Changes {@link SliderPose#getTime()}. */
static public class SliderTimeline extends ConstraintTimeline1 {
public SliderTimeline (int frameCount, int bezierCount, int constraintIndex) {
super(frameCount, bezierCount, constraintIndex, Property.sliderTime);
@ -2399,7 +2438,7 @@ public class Animation {
}
}
/** Changes a slider's {@link SliderPose#getMix()}. */
/** Changes {@link SliderPose#getMix()}. */
static public class SliderMixTimeline extends ConstraintTimeline1 {
public SliderMixTimeline (int frameCount, int bezierCount, int constraintIndex) {
super(frameCount, bezierCount, constraintIndex, Property.sliderMix);

View File

@ -297,9 +297,8 @@ public class AnimationState {
Array<Event> events = null;
if (from.reverse)
applyTime = from.animation.duration - applyTime;
else {
if (mix < from.eventThreshold) events = this.events;
}
else if (mix < from.eventThreshold) //
events = this.events;
int[] timelineMode = from.timelineMode.items;
TrackEntry[] timelineHoldMix = from.timelineHoldMix.items;
boolean add = from.additive, shortestRotation = add || from.shortestRotation;
@ -472,8 +471,8 @@ public class AnimationState {
/** Removes all animations from all tracks, leaving skeletons in their current pose.
* <p>
* It may be desired to use {@link AnimationState#setEmptyAnimations(float)} to mix the skeletons back to the setup pose,
* rather than leaving them in their current pose. */
* Usually you want to use {@link #setEmptyAnimations(float)} to mix the skeletons back to the setup pose, rather than leaving
* them in their current pose. */
public void clearTracks () {
boolean oldDrainDisabled = queue.drainDisabled;
queue.drainDisabled = true;
@ -486,8 +485,8 @@ public class AnimationState {
/** Removes all animations from the track, leaving skeletons in their current pose.
* <p>
* It may be desired to use {@link AnimationState#setEmptyAnimation(int, float)} to mix the skeletons back to the setup pose,
* rather than leaving them in their current pose. */
* Usually you want to use {@link #setEmptyAnimation(int, float)} to mix the skeletons back to the setup pose, rather than
* leaving them in their current pose. */
public void clearTrack (int trackIndex) {
if (trackIndex < 0) throw new IllegalArgumentException("trackIndex must be >= 0.");
if (trackIndex >= tracks.size) return;
@ -586,8 +585,8 @@ public class AnimationState {
/** Adds an animation to be played after the current or last queued animation for a track. If the track has no entries, this is
* equivalent to calling {@link #setAnimation(int, Animation, boolean)}.
* @param delay If > 0, sets {@link TrackEntry#getDelay()}. If <= 0, the delay set is the duration of the previous track entry
* minus any mix duration (from the {@link AnimationStateData}) plus the specified <code>delay</code> (ie the mix
* ends at (<code>delay</code> = 0) or before (<code>delay</code> < 0) the previous track entry duration). If the
* minus any mix duration (from {@link #data}) plus the specified <code>delay</code> (ie the mix ends at (when
* <code>delay</code> = 0) or before (when <code>delay</code> < 0) the previous track entry duration). If the
* previous entry is looping, its next loop completion is used instead of its duration.
* @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
* after the {@link AnimationStateListener#dispose(TrackEntry)} event occurs. */
@ -624,7 +623,7 @@ public class AnimationState {
* {@link #setEmptyAnimations(float)}, or {@link #addEmptyAnimation(int, float, float)}. Mixing to an empty animation causes
* the previous animation to be applied less and less over the mix duration. Properties keyed in the previous animation
* transition to the value from lower tracks or to the setup pose value if no lower tracks key the property. A mix duration of
* 0 still mixes out over one frame.
* 0 still needs to be applied one more time to mix out, so the the properties it was animating are reverted.
* <p>
* Mixing in is done by first setting an empty animation, then adding an animation using
* {@link #addAnimation(int, Animation, boolean, float)} with the desired delay (an empty animation has a duration of 0) and on
@ -649,9 +648,9 @@ public class AnimationState {
* <a href='https://esotericsoftware.com/spine-applying-animations/#Empty-animations'>Empty animations</a> in the Spine
* Runtimes Guide.
* @param delay If > 0, sets {@link TrackEntry#getDelay()}. If <= 0, the delay set is the duration of the previous track entry
* minus any mix duration plus the specified <code>delay</code> (ie the mix ends at (<code>delay</code> = 0) or
* before (<code>delay</code> < 0) the previous track entry duration). If the previous entry is looping, its next
* loop completion is used instead of its duration.
* minus any mix duration plus the specified <code>delay</code> (ie the mix ends at (when <code>delay</code> = 0) or
* before (when <code>delay</code> < 0) the previous track entry duration). If the previous entry is looping, its
* next loop completion is used instead of its duration.
* @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
* after the {@link AnimationStateListener#dispose(TrackEntry)} event occurs. */
public TrackEntry addEmptyAnimation (int trackIndex, float mixDuration, float delay) {
@ -827,7 +826,7 @@ public class AnimationState {
/** Multiplier for the delta time when the animation state is updated, causing time for all animations and mixes to play slower
* or faster. Defaults to 1.
* <p>
* See TrackEntry {@link TrackEntry#getTimeScale()} for affecting a single animation. */
* See {@link TrackEntry#getTimeScale()} to affect a single animation. */
public float getTimeScale () {
return timeScale;
}
@ -846,7 +845,7 @@ public class AnimationState {
this.data = data;
}
/** The list of tracks that have had animations, which may contain null entries for tracks that currently have no animation. */
/** The list of tracks that have had animations. May contain null entries for tracks that currently have no animation. */
public Array<TrackEntry> getTracks () {
return tracks;
}
@ -924,8 +923,7 @@ public class AnimationState {
/** Seconds to postpone playing the animation. Must be >= 0. When this track entry is the current track entry,
* <code>delay</code> postpones incrementing the {@link #getTrackTime()}. When this track entry is queued,
* <code>delay</code> is the time from the start of the previous animation to when this track entry will become the current
* track entry (ie when the previous track entry {@link TrackEntry#getTrackTime()} >= this track entry's
* <code>delay</code>).
* track entry (ie when the previous track entry {@link #getTrackTime()} >= this track entry's <code>delay</code>).
* <p>
* {@link #getTimeScale()} affects the delay.
* <p>
@ -957,7 +955,7 @@ public class AnimationState {
* is reached, no other animations are queued for playback, and mixing from any previous animations is complete, then the
* properties keyed by the animation are set to the setup pose and the track is cleared.
* <p>
* It may be desired to use {@link AnimationState#addEmptyAnimation(int, float, float)} rather than have the animation
* Usually you want to use {@link AnimationState#addEmptyAnimation(int, float, float)} rather than have the animation
* abruptly cease being applied. */
public float getTrackEnd () {
return trackEnd;
@ -967,9 +965,11 @@ public class AnimationState {
this.trackEnd = trackEnd;
}
/** If this track entry is non-looping, the track time in seconds when {@link #getAnimationEnd()} is reached, or the current
* {@link #getTrackTime()} if it has already been reached. If this track entry is looping, the track time when this
* animation will reach its next {@link #getAnimationEnd()} (the next loop completion). */
/** If this track entry is non-looping, this is the track time in seconds when {@link #getAnimationEnd()} is reached, or the
* current {@link #getTrackTime()} if it has already been reached.
* <p>
* If this track entry is looping, this is the track time when this animation will reach its next {@link #getAnimationEnd()}
* (the next loop completion). */
public float getTrackComplete () {
float duration = animationEnd - animationStart;
if (duration != 0) {
@ -1018,7 +1018,7 @@ public class AnimationState {
* <code>animationTime</code> is equal to the <code>animationStart</code> time.
* <p>
* The <code>animationTime</code> is between {@link #getAnimationStart()} and {@link #getAnimationEnd()}, except if this
* track entry is non-looping and {@link #getAnimationEnd()} is >= to the animation {@link Animation#duration}, then
* track entry is non-looping and {@link #getAnimationEnd()} is >= to the {@link Animation#duration}, then
* <code>animationTime</code> continues to increase past {@link #getAnimationEnd()}. */
public float getAnimationTime () {
if (loop) {
@ -1039,10 +1039,10 @@ public class AnimationState {
* match the animation speed.
* <p>
* When using {@link AnimationState#addAnimation(int, Animation, boolean, float)} with a <code>delay</code> <= 0, the
* {@link #getDelay()} is set using the mix duration from the {@link AnimationStateData}, assuming time scale to be 1. If
* the time scale is not 1, the delay may need to be adjusted.
* {@link #getDelay()} is set using the mix duration from {@link AnimationState#data}, assuming time scale to be 1. If the
* time scale is not 1, the delay may need to be adjusted.
* <p>
* See AnimationState {@link AnimationState#getTimeScale()} for affecting all animations. */
* See {@link AnimationState#getTimeScale()} to affect all animations. */
public float getTimeScale () {
return timeScale;
}
@ -1054,7 +1054,7 @@ public class AnimationState {
/** The listener for events generated by this track entry, or null.
* <p>
* A track entry returned from {@link AnimationState#setAnimation(int, Animation, boolean)} is already the current animation
* for the track, so the track entry listener {@link AnimationStateListener#start(TrackEntry)} will not be called. */
* for the track, so the callback for {@link AnimationStateListener#start(TrackEntry)} will not be called. */
public @Null AnimationStateListener getListener () {
return listener;
}
@ -1063,12 +1063,12 @@ public class AnimationState {
this.listener = listener;
}
/** Values < 1 mix this animation with the skeleton's current pose (usually the pose resulting from lower tracks). Defaults
* to 1, which overwrites the skeleton's current pose with this animation.
/** Values < 1 mix this animation with the skeleton's current pose (either the setup pose or the pose from lower tracks).
* Defaults to 1, which overwrites the skeleton's current pose with this animation.
* <p>
* Typically track 0 is used to completely pose the skeleton, then alpha is used on higher tracks. It doesn't make sense to
* use alpha on track 0 if the skeleton pose is from the last frame render.
* @see #getAlphaAttachmentThreshold() */
* Alpha should be 1 on track 0.
* <p>
* See {@link #getAlphaAttachmentThreshold()}. */
public float getAlpha () {
return alpha;
}
@ -1088,8 +1088,9 @@ public class AnimationState {
this.eventThreshold = eventThreshold;
}
/** When {@link #getAlpha()} is greater than <code>alphaAttachmentThreshold</code>, attachment timelines are applied.
* Defaults to 0, so attachment timelines are always applied. */
/** When the computed alpha is greater than <code>alphaAttachmentThreshold</code>, attachment timelines are applied. The
* computed alpha includes {@link #getAlpha()} and the mix percentage. Defaults to 0, so attachment timelines are always
* applied. */
public float getAlphaAttachmentThreshold () {
return alphaAttachmentThreshold;
}
@ -1153,8 +1154,8 @@ public class AnimationState {
return trackTime >= animationEnd - animationStart;
}
/** Seconds from 0 to the {@link #getMixDuration()} when mixing from the previous animation to this animation. May be
* slightly more than <code>mixDuration</code> when the mix is complete. */
/** Seconds elapsed from 0 to the {@link #getMixDuration()} when mixing from the previous animation to this animation. May
* be slightly more than <code>mixDuration</code> when the mix is complete. */
public float getMixTime () {
return mixTime;
}
@ -1163,23 +1164,32 @@ public class AnimationState {
this.mixTime = mixTime;
}
/** Seconds for mixing from the previous animation to this animation. Defaults to the value provided by AnimationStateData
/** Seconds for mixing from the previous animation to this animation. Defaults to the value provided by
* {@link AnimationStateData#getMix(Animation, Animation)} based on the animation before this animation (if any).
* <p>
* A mix duration of 0 still mixes out over one frame to provide the track entry being mixed out a chance to revert the
* properties it was animating. A mix duration of 0 can be set at any time to end the mix on the next
* {@link AnimationState#update(float) update}.
* A mix duration of 0 still needs to be applied one more time to mix out, so the the properties it was animating are
* reverted. A mix duration of 0 can be set at any time to end the mix on the next {@link AnimationState#update(float)
* update}.
* <p>
* The <code>mixDuration</code> can be set manually rather than use the value from
* {@link AnimationStateData#getMix(Animation, Animation)}. In that case, the <code>mixDuration</code> can be set for a new
* track entry only before {@link AnimationState#update(float)} is next called.
* <p>
* When using {@link AnimationState#addAnimation(int, Animation, boolean, float)} with a <code>delay</code> <= 0, the
* {@link #getDelay()} is set using the mix duration from the {@link AnimationStateData}. If <code>mixDuration</code> is set
* afterward, the delay may need to be adjusted. For example:<br>
* <code>entry.delay = entry.previous.getTrackComplete() - entry.mixDuration;</code><br>
* Alternatively, {@link #setMixDuration(float, float)} can be used to recompute the delay:<br>
* <code>entry.setMixDuration(0.25f, 0);</code> */
* {@link #getDelay()} is set using the mix duration from {@link AnimationState#data}. If <code>mixDuration</code> is set
* afterward, the delay needs to be adjusted:
*
* <pre>
* entry.mixDuration = 0.25;<br>
* entry.delay = entry.previous.getTrackComplete() - entry.mixDuration + 0;
* </pre>
*
* Alternatively, use {@link #setMixDuration(float, float)} to set both the mix duration and recompute the delay:<br>
*
* <pre>
* entry.setMixDuration(0.25f, 0); // mixDuration, delay
* </pre>
*/
public float getMixDuration () {
return mixDuration;
}
@ -1189,18 +1199,19 @@ public class AnimationState {
}
/** Sets both {@link #getMixDuration()} and {@link #getDelay()}.
* @param delay If > 0, sets {@link TrackEntry#getDelay()}. If <= 0, the delay set is the duration of the previous track
* entry minus the specified mix duration plus the specified <code>delay</code> (ie the mix ends at
* (<code>delay</code> = 0) or before (<code>delay</code> < 0) the previous track entry duration). If the previous
* entry is looping, its next loop completion is used instead of its duration. */
* @param delay If > 0, sets {@link #getDelay()}. If <= 0, the delay set is the duration of the previous track entry minus
* the specified mix duration plus the specified <code>delay</code> (ie the mix ends at (when <code>delay</code> =
* 0) or before (when <code>delay</code> < 0) the previous track entry duration). If the previous entry is
* looping, its next loop completion is used instead of its duration. */
public void setMixDuration (float mixDuration, float delay) {
this.mixDuration = mixDuration;
if (delay <= 0) delay = previous == null ? 0 : Math.max(delay + previous.getTrackComplete() - mixDuration, 0);
this.delay = delay;
}
/** When true, timelines in this animation that support additive are added to the setup or current pose. Additive can be set
* for a new track entry only before {@link AnimationState#apply(Skeleton)} is next called. */
/** When true, timelines in this animation that support additive have their values added to the setup or current pose values
* instead of replacing them. Additive can be set for a new track entry only before {@link AnimationState#apply(Skeleton)}
* is next called. */
public boolean getAdditive () {
return additive;
}
@ -1209,14 +1220,14 @@ public class AnimationState {
this.additive = additive;
}
/** The track entry for the previous animation when mixing from the previous animation to this animation, or null if no
* mixing is currently occurring. When mixing from multiple animations, <code>mixingFrom</code> makes up a linked list. */
/** The track entry for the previous animation when mixing to this animation, or null if no mixing is currently occurring.
* When mixing from multiple animations, <code>mixingFrom</code> makes up a doubly linked list. */
public @Null TrackEntry getMixingFrom () {
return mixingFrom;
}
/** The track entry for the next animation when mixing from this animation to the next animation, or null if no mixing is
* currently occurring. When mixing to multiple animations, <code>mixingTo</code> makes up a linked list. */
/** The track entry for the next animation when mixing from this animation, or null if no mixing is currently occurring.
* When mixing to multiple animations, <code>mixingTo</code> makes up a doubly linked list. */
public @Null TrackEntry getMixingTo () {
return mixingTo;
}
@ -1248,18 +1259,21 @@ public class AnimationState {
* shortest rotation direction may change during the mix.
* <p>
* If false, the shortest rotation direction is remembered when the mix starts and the same direction is used for the rest
* of the mix. Defaults to false. */
* of the mix. Defaults to false.
* <p>
* See {@link #resetRotationDirections()}. */
public boolean getShortestRotation () {
return shortestRotation;
}
/** Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the
* long way around when using {@link #getAlpha()} and starting animations on other tracks.
/** When {@link #shortestRotation} is false, this clears the directions for mixing this entry's rotation. This can be useful
* to avoid bones rotating the long way around when using {@link #getAlpha()} and starting animations on other tracks.
* <p>
* Mixing involves finding a rotation between two others, which has two possible solutions: the short way or the long way
* around. The two rotations likely change over time, so which direction is the short or long way also changes. If the short
* way was always chosen, bones would flip to the other side when that direction became the long way. TrackEntry chooses the
* short way the first time it is applied and remembers that direction. */
* Mixing involves finding a rotation between two others. There are two possible solutions: the short or the long way
* around. When the two rotations change over time, which direction is the short or long way can also change. If the short
* way was always chosen, bones flip to the other side when that direction became the long way. TrackEntry chooses the short
* way the first time it is applied and remembers that direction. Resetting that direction makes it choose a new short way
* on the next apply. */
public void resetRotationDirections () {
timelinesRotation.clear();
}
@ -1268,7 +1282,7 @@ public class AnimationState {
this.reverse = reverse;
}
/** If true, the animation will be applied in reverse. Events are not fired when an animation is applied in reverse. */
/** If true, the animation will be applied in reverse and events will not be fired. */
public boolean getReverse () {
return reverse;
}
@ -1388,7 +1402,7 @@ public class AnimationState {
* TrackEntry events are collected during {@link AnimationState#update(float)} and {@link AnimationState#apply(Skeleton)} and
* fired only after those methods are finished.
* <p>
* See TrackEntry {@link TrackEntry#setListener(AnimationStateListener)} and AnimationState
* See {@link TrackEntry#setListener(AnimationStateListener)} and
* {@link AnimationState#addListener(AnimationStateListener)}. */
static public interface AnimationStateListener {
/** Invoked when this entry has been set as the current entry. {@link #end(TrackEntry)} will occur when this entry will no

View File

@ -33,7 +33,7 @@ import com.badlogic.gdx.utils.ObjectFloatMap;
import com.esotericsoftware.spine.AnimationState.TrackEntry;
/** Stores mix (crossfade) durations to be applied when {@link AnimationState} animations are changed. */
/** Stores mix (crossfade) durations to be applied when {@link AnimationState} animations are changed on the same track. */
public class AnimationStateData {
final SkeletonData skeletonData;
final ObjectFloatMap<Key> animationToMixTime = new ObjectFloatMap(51, 0.8f);
@ -73,8 +73,8 @@ public class AnimationStateData {
animationToMixTime.put(key, duration);
}
/** Returns the mix duration to use when changing from the specified animation to the other, or the {@link #getDefaultMix()} if
* no mix duration has been set. */
/** Returns the mix duration to use when changing from the specified animation to the other on the same track, or the
* {@link #getDefaultMix()} if no mix duration has been set. */
public float getMix (Animation from, Animation to) {
if (from == null) throw new IllegalArgumentException("from cannot be null.");
if (to == null) throw new IllegalArgumentException("to cannot be null.");

View File

@ -32,12 +32,15 @@ package com.esotericsoftware.spine;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Null;
// BOZO - Update javadocs.
/** The current pose for a bone, before constraints are applied.
* <p>
* A bone has a local transform which is used to compute its world transform. A bone also has an applied transform, which is a
* local transform that can be applied to compute the world transform. The local transform and applied transform may differ if a
* constraint or application code modifies the world transform after it was computed from the local transform. */
/** A bone has a number of poses:
* <ul>
* <li>{@link BoneData#getSetupPose()}: The setup pose.
* <li>{@link #getPose()}: The local pose. Set by animations and app code.
* <li>{@link #getAppliedPose()}: The applied local pose. This is the local pose modified by constraints and app code.
* <li>The world transform on the applied pose, computed by {@link Skeleton#updateWorldTransform(Physics)} and
* {@link BonePose#updateWorldTransform(Skeleton)}.
* </ul>
*/
public class Bone extends PosedActive<BoneData, BoneLocal, BonePose> {
@Null final Bone parent;
final Array<Bone> children = new Array(true, 4, Bone[]::new);

View File

@ -58,11 +58,19 @@ public class BoneData extends PosedData<BoneLocal> {
setup.set(data.setup);
}
/** The index of the bone in {@link Skeleton#getBones()}. */
/** The bone's name, unique across all bones in the skeleton.
* <p>
* See {@link SkeletonData#findBone(String)} and {@link Skeleton#findBone(String)}. */
public String getName () { // Do not port.
return super.getName();
}
/** The {@link Skeleton#getBones()} index. */
public int getIndex () {
return index;
}
/** The parent bone, or null if this bone is the root. */
public @Null BoneData getParent () {
return parent;
}
@ -82,7 +90,7 @@ public class BoneData extends PosedData<BoneLocal> {
return color;
}
/** The bone icon as it was in Spine, or null if nonessential data was not exported. */
/** The bone icon name as it was in Spine, or null if nonessential data was not exported. */
public @Null String getIcon () {
return icon;
}

View File

@ -9,8 +9,15 @@ import com.badlogic.gdx.math.Vector2;
import com.esotericsoftware.spine.BoneData.Inherit;
/** The applied pose for a bone. This is the {@link Bone} pose with constraints applied and the world transform computed by
* {@link Skeleton#updateWorldTransform(Physics)}. */
/** The applied local pose and world transform for a bone. This is the {@link Bone#getPose()} with constraints applied and the
* world transform computed by {@link Skeleton#updateWorldTransform(Physics)} and {@link #updateWorldTransform(Skeleton)}.
* <p>
* If the world transform is changed, call {@link #updateLocalTransform(Skeleton)} before using the local transform. The local
* transform may be needed by other code (eg to apply another constraint).
* <p>
* After changing the world transform, call {@link #updateWorldTransform(Skeleton)} on every descendant bone. It may be more
* convenient to modify the local transform instead, then call {@link Skeleton#updateWorldTransform(Physics)} to update the world
* transforms for all bones and apply constraints. */
public class BonePose extends BoneLocal implements Update {
Bone bone;
float a, b, worldX;
@ -22,7 +29,8 @@ public class BonePose extends BoneLocal implements Update {
if (world != skeleton.update) updateWorldTransform(skeleton);
}
/** Computes the world transform using the parent bone's applied pose and this pose. Child bones are not updated.
/** Computes the world transform using the parent bone's world transform and this applied local pose. Child bones are not
* updated.
* <p>
* See <a href="https://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
* Runtimes Guide. */
@ -130,10 +138,6 @@ public class BonePose extends BoneLocal implements Update {
}
/** Computes the local transform values from the world transform.
* <p>
* If the world transform is modified (by a constraint, {@link #rotateWorld(float)}, etc) then this method should be called so
* the local transform matches the world transform. The local transform may be needed by other code (eg to apply another
* constraint).
* <p>
* Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. The local transform after
* calling this method is equivalent to the local transform used to compute the world transform, but may not be identical. */
@ -218,8 +222,9 @@ public class BonePose extends BoneLocal implements Update {
}
}
/** If the world transform has been modified and the local transform no longer matches, {@link #updateLocalTransform(Skeleton)}
* is called. */
/** If the world transform has been modified by constraints and the local transform no longer matches,
* {@link #updateLocalTransform(Skeleton)} is called. Call this after {@link Skeleton#updateWorldTransform(Physics)} before
* using the applied local transform. */
public void validateLocalTransform (Skeleton skeleton) {
if (local == skeleton.update) updateLocalTransform(skeleton);
}
@ -248,7 +253,7 @@ public class BonePose extends BoneLocal implements Update {
}
}
/** Part of the world transform matrix for the X axis. If changed, {@link #updateLocalTransform(Skeleton)} should be called. */
/** Part of the world transform matrix for the X axis. */
public float getA () {
return a;
}
@ -257,7 +262,7 @@ public class BonePose extends BoneLocal implements Update {
this.a = a;
}
/** Part of the world transform matrix for the Y axis. If changed, {@link #updateLocalTransform(Skeleton)} should be called. */
/** Part of the world transform matrix for the Y axis. */
public float getB () {
return b;
}
@ -266,7 +271,7 @@ public class BonePose extends BoneLocal implements Update {
this.b = b;
}
/** Part of the world transform matrix for the X axis. If changed, {@link #updateLocalTransform(Skeleton)} should be called. */
/** Part of the world transform matrix for the X axis. */
public float getC () {
return c;
}
@ -275,7 +280,7 @@ public class BonePose extends BoneLocal implements Update {
this.c = c;
}
/** Part of the world transform matrix for the Y axis. If changed, {@link #updateLocalTransform(Skeleton)} should be called. */
/** Part of the world transform matrix for the Y axis. */
public float getD () {
return d;
}
@ -284,7 +289,7 @@ public class BonePose extends BoneLocal implements Update {
this.d = d;
}
/** The world X position. If changed, {@link #updateLocalTransform(Skeleton)} should be called. */
/** The world X position. */
public float getWorldX () {
return worldX;
}
@ -293,7 +298,7 @@ public class BonePose extends BoneLocal implements Update {
this.worldX = worldX;
}
/** The world Y position. If changed, {@link #updateLocalTransform(Skeleton)} should be called. */
/** The world Y position. */
public float getWorldY () {
return worldY;
}
@ -382,10 +387,7 @@ public class BonePose extends BoneLocal implements Update {
return atan2Deg(cos * c + sin * d, cos * a + sin * b);
}
/** Rotates the world transform the specified amount.
* <p>
* After changes are made to the world transform, {@link #updateLocalTransform(Skeleton)} should be called on this bone and any
* child bones, recursively. */
/** Rotates the world transform the specified amount. */
public void rotateWorld (float degrees) {
degrees *= degRad;
float sin = sin(degrees), cos = cos(degrees);

View File

@ -10,5 +10,12 @@ abstract public class ConstraintData< //
super(name, setup);
}
/** The constraint's name, unique across all constraints in the skeleton.
* <p>
* See {@link SkeletonData#findConstraint(String, Class)} and {@link Skeleton#findConstraint(String, Class)}. */
public String getName () { // Do not port.
return super.getName();
}
abstract public T create (Skeleton skeleton);
}

View File

@ -34,9 +34,8 @@ import com.esotericsoftware.spine.AnimationState.AnimationStateListener;
/** Stores the current pose values for an {@link Event}.
* <p>
* See Timeline
* {@link Timeline#apply(Skeleton, float, float, com.badlogic.gdx.utils.Array, float, boolean, boolean, boolean, boolean)},
* AnimationStateListener {@link AnimationStateListener#event(com.esotericsoftware.spine.AnimationState.TrackEntry, Event)}, and
* See {@link Timeline#apply(Skeleton, float, float, com.badlogic.gdx.utils.Array, float, boolean, boolean, boolean, boolean)},
* {@link AnimationStateListener#event(com.esotericsoftware.spine.AnimationState.TrackEntry, Event)}, and
* <a href="https://esotericsoftware.com/spine-events">Events</a> in the Spine User Guide. */
public class Event {
final EventData data;

View File

@ -94,7 +94,9 @@ public class EventData {
this.balance = balance;
}
/** The name of the event, which is unique across all events in the skeleton. */
/** The name of the event, unique across all events in the skeleton.
* <p>
* See {@link SkeletonData#findEvent(String)}. */
public String getName () {
return name;
}

View File

@ -16,11 +16,8 @@ abstract public class PosedActive< //
/** 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.
* @see Skin#getBones()
* @see Skin#getConstraints()
* @see PosedData#getSkinRequired()
* @see Skeleton#updateCache() */
* {@link Skeleton#getSkin() active skin} does not contain this item. See {@link Skin#getBones()},
* {@link Skin#getConstraints()}, {@link PosedData#getSkinRequired()}, and {@link Skeleton#updateCache()}. */
public boolean isActive () {
return active;
}

View File

@ -41,7 +41,6 @@ abstract public class PosedData<P extends Pose> {
this.setup = setup;
}
/** The constraint's name, which is unique across all constraints in the skeleton of the same type. */
public String getName () {
return name;
}

View File

@ -350,7 +350,7 @@ public class Skeleton {
return null;
}
/** The skeleton's slots in the order they should be drawn. The returned array may be modified to change the draw order. */
/** The skeleton's slots in the order they should be drawn. The returned list may be modified to change the draw order. */
public Array<Slot> getDrawOrder () {
return drawOrder;
}
@ -650,7 +650,7 @@ public class Skeleton {
constraints[i].rotate(x, y, degrees);
}
/** Returns the skeleton's time. This is used for time-based manipulations, such as {@link PhysicsConstraint}.
/** Returns the skeleton's time, used for time-based manipulations, such as {@link PhysicsConstraint}.
* <p>
* See {@link #update(float)}. */
public float getTime () {

View File

@ -39,7 +39,7 @@ import com.esotericsoftware.spine.attachments.MeshAttachment;
/** Stores attachments by slot index and placeholder name.
* <p>
* See SkeletonData {@link SkeletonData#defaultSkin}, Skeleton {@link Skeleton#skin}, and
* See {@link SkeletonData#defaultSkin}, {@link Skeleton#skin}, and
* <a href="https://esotericsoftware.com/spine-runtime-skins">Runtime skins</a> in the Spine Runtimes Guide. */
public class Skin {
final String name;
@ -138,7 +138,9 @@ public class Skin {
return constraints;
}
/** The skin's name, which is unique across all skins in the skeleton. */
/** The skin's name, unique across all skins in the skeleton.
* <p>
* See {@link SkeletonData#findSkin(String)}. */
public String getName () {
return name;
}

View File

@ -49,7 +49,14 @@ public class SlotData extends PosedData<SlotPose> {
this.boneData = boneData;
}
/** The index of the slot in {@link Skeleton#getSlots()}. */
/** The slot's name, unique across all slots in the skeleton.
* <p>
* See {@link SkeletonData#findSlot(String)} and {@link Skeleton#findSlot(String)}. */
public String getName () { // Do not port.
return super.getName();
}
/** The {@link Skeleton#getSlots()} index. */
public int getIndex () {
return index;
}

View File

@ -32,16 +32,20 @@ package com.esotericsoftware.spine.attachments;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Null;
import com.esotericsoftware.spine.Skin;
/** An {@link AttachmentLoader} that configures attachments using texture regions from an {@link Atlas}.
/** An {@link AttachmentLoader} that configures attachments using texture regions from an {@link TextureAtlas}.
* <p>
* See <a href='https://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data'>Loading skeleton data</a> in the
* Spine Runtimes Guide. */
@SuppressWarnings("javadoc")
public class AtlasAttachmentLoader implements AttachmentLoader {
private TextureAtlas atlas;
/** If true, {@link #findRegion(String, String)} may return null. If false, an error is raised if the texture region is not
* found. Default is false. */
public boolean allowMissingRegions;
public AtlasAttachmentLoader (TextureAtlas atlas) {
@ -54,13 +58,17 @@ public class AtlasAttachmentLoader implements AttachmentLoader {
this.allowMissingRegions = allowMissingRegions;
}
/** Sets each {@link Sequence#getRegions()} by calling {@link #findRegion(String, String)} for each texture region using
* {@link Sequence#getPath(String, int)}. */
protected void findRegions (String name, String basePath, Sequence sequence) {
TextureRegion[] regions = sequence.getRegions();
for (int i = 0, n = regions.length; i < n; i++)
regions[i] = findRegion(name, sequence.getPath(basePath, i));
}
protected AtlasRegion findRegion (String name, String path) {
/** Looks for the region with the specified path. If not found and {@link #allowMissingRegions} is false, an error is
* raised. */
protected @Null AtlasRegion findRegion (String name, String path) {
AtlasRegion region = atlas.findRegion(path);
if (region == null && !allowMissingRegions)
throw new RuntimeException("Region not found in atlas: " + path + " (attachment: " + name + ")");

View File

@ -52,7 +52,7 @@ public class ClippingAttachment extends VertexAttachment {
color.set(other.color);
}
/** Clipping is performed between the clipping attachment's slot and the end slot. If null clipping is done until the end of
/** Clipping is performed between the clipping attachment's slot and the end slot. If null, clipping is done until the end of
* the skeleton's rendering. */
public @Null SlotData getEndSlot () {
return endSlot;

View File

@ -31,15 +31,21 @@ package com.esotericsoftware.spine.attachments;
import com.badlogic.gdx.graphics.Color;
import com.esotericsoftware.spine.SlotPose;
/** Interface for an attachment that gets 1 or more texture regions from a {@link Sequence}. */
public interface HasSequence {
/** The base path for the attachment's texture region. */
public String getPath ();
public void setPath (String path);
/** The color the attachment is tinted, to be combined with {@link SlotPose#getColor()}. */
public Color getColor ();
/** Calls {@link Sequence#update(HasSequence)} on this attachment's sequence. */
public void updateSequence ();
/** The sequence that provides texture regions, UVs, and vertex offsets for rendering this attachment. */
public Sequence getSequence ();
}

View File

@ -37,7 +37,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Null;
/** An attachment that displays a textured mesh. A mesh has hull vertices and internal vertices within the hull. Holes are not
* supported. Each vertex has UVs (texture coordinates) and triangles are used to map an image on to the mesh.
* supported. Each vertex has UVs (texture coordinates) and triangles that are used to map an image on to the mesh.
* <p>
* See <a href="https://esotericsoftware.com/spine-meshes">Mesh attachments</a> in the Spine User Guide. */
public class MeshAttachment extends VertexAttachment implements HasSequence {
@ -138,8 +138,8 @@ public class MeshAttachment extends VertexAttachment implements HasSequence {
this.edges = edges;
}
/** Vertex index pairs describing edges for controlling triangulation, or be null if nonessential data was not exported. Mesh
* triangles never cross edges. Triangulation is not performed at runtime. */
/** Vertex index pairs describing edges for controlling triangulation, or null if nonessential data was not exported. Mesh
* triangles do not cross edges. Triangulation is not performed at runtime. */
public @Null short[] getEdges () {
return edges;
}
@ -164,7 +164,7 @@ public class MeshAttachment extends VertexAttachment implements HasSequence {
/** The parent mesh if this is a linked mesh, else null. A linked mesh shares the {@link #bones}, {@link #vertices},
* {@link #regionUVs}, {@link #triangles}, {@link #hullLength}, {@link #edges}, {@link #width}, and {@link #height} with the
* parent mesh, but may have a different {@link #name} or {@link #path} (and therefore a different texture). */
* parent mesh, but may have a different {@link #name} or {@link #path}, and therefore a different texture region. */
public @Null MeshAttachment getParentMesh () {
return parentMesh;
}

View File

@ -70,8 +70,8 @@ public class PathAttachment extends VertexAttachment {
this.closed = closed;
}
/** If true, additional calculations are performed to make computing positions along the path more accurate and movement along
* the path have a constant speed. */
/** If true, additional calculations are performed to make computing positions along the path more accurate so movement along
* the path has a constant speed. */
public boolean getConstantSpeed () {
return constantSpeed;
}

View File

@ -60,6 +60,7 @@ public class PointAttachment extends Attachment {
color.set(other.color);
}
/** The local X position. */
public float getX () {
return x;
}
@ -68,6 +69,7 @@ public class PointAttachment extends Attachment {
this.x = x;
}
/** The local Y position. */
public float getY () {
return y;
}
@ -76,6 +78,7 @@ public class PointAttachment extends Attachment {
this.y = y;
}
/** The local rotation in degrees, counter clockwise. */
public float getRotation () {
return rotation;
}
@ -90,12 +93,14 @@ public class PointAttachment extends Attachment {
return color;
}
/** Computes the world position from the local position. */
public Vector2 computeWorldPosition (BonePose bone, Vector2 point) {
point.x = x * bone.getA() + y * bone.getB() + bone.getWorldX();
point.y = x * bone.getC() + y * bone.getD() + bone.getWorldY();
return point;
}
/** Computes the world rotation from the local rotation. */
public float computeWorldRotation (BonePose bone) {
float r = rotation * degRad, cos = cos(r), sin = sin(r);
float x = cos * bone.getA() + sin * bone.getB();

View File

@ -153,7 +153,7 @@ public class RegionAttachment extends Attachment implements HasSequence {
this.scaleY = scaleY;
}
/** The local rotation. */
/** The local rotation in degrees, counter clockwise. */
public float getRotation () {
return rotation;
}

View File

@ -40,7 +40,7 @@ import com.esotericsoftware.spine.Skeleton;
import com.esotericsoftware.spine.Slot;
import com.esotericsoftware.spine.SlotPose;
/** Base class for an attachment with vertices that are transformed by one or more bones and can be deformed by a slot's
/** Base class for an attachment with vertices that are transformed by one or more bones and can be deformed by
* {@link SlotPose#getDeform()}. */
abstract public class VertexAttachment extends Attachment {
static private int nextID;
@ -73,8 +73,8 @@ abstract public class VertexAttachment extends Attachment {
worldVerticesLength = other.worldVerticesLength;
}
/** Transforms the attachment's local {@link #getVertices()} to world coordinates. If the slot's {@link SlotPose#getDeform()}
* is not empty, it is used to deform the vertices.
/** Transforms the attachment's local {@link #getVertices()} to world coordinates. If the {@link SlotPose#getDeform()} is not
* empty, it is used to deform the vertices.
* <p>
* See <a href="https://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
* Runtimes Guide.
@ -142,9 +142,9 @@ abstract public class VertexAttachment extends Attachment {
}
}
/** The bones which affect the {@link #getVertices()}. The array entries are, for each vertex, the number of bones affecting
* the vertex followed by that many bone indices, which is the index of the bone in {@link Skeleton#getBones()}. Will be null
* if this attachment has no weights. */
/** The bones that affect the {@link #getVertices()}. The entries are, for each vertex, the number of bones affecting the
* vertex followed by that many bone indices, which is the {@link Skeleton#getBones()} index. Null if this attachment has no
* weights. */
public @Null int[] getBones () {
return bones;
}
@ -154,9 +154,9 @@ abstract public class VertexAttachment extends Attachment {
this.bones = bones;
}
/** The vertex positions in the bone's coordinate system. For a non-weighted attachment, the values are <code>x,y</code>
* entries for each vertex. For a weighted attachment, the values are <code>x,y,weight</code> entries for each bone affecting
* each vertex. */
/** The vertex positions in the bone's coordinate system. For a non-weighted attachment, the values are <code>x,y</code> pairs
* for each vertex. For a weighted attachment, the values are <code>x,y,weight</code> triplets for each bone affecting each
* vertex. */
public float[] getVertices () {
return vertices;
}