mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 22:34:53 +08:00
Major API documentation update.
Used to generate this fancy stuff! http://esotericsoftware.com/spine-api-reference
This commit is contained in:
parent
e14a783c38
commit
8fe76a8dd9
@ -37,6 +37,7 @@ import com.badlogic.gdx.utils.FloatArray;
|
||||
import com.esotericsoftware.spine.attachments.Attachment;
|
||||
import com.esotericsoftware.spine.attachments.VertexAttachment;
|
||||
|
||||
/** A simple container for a list of timelines and a name. */
|
||||
public class Animation {
|
||||
final String name;
|
||||
final Array<Timeline> timelines;
|
||||
@ -54,7 +55,7 @@ public class Animation {
|
||||
return timelines;
|
||||
}
|
||||
|
||||
/** Returns the duration of the animation in seconds. */
|
||||
/** The duration of the animation in seconds, which is the highest time of all keys in the timeline. */
|
||||
public float getDuration () {
|
||||
return duration;
|
||||
}
|
||||
@ -64,7 +65,8 @@ public class Animation {
|
||||
}
|
||||
|
||||
/** Applies all the animation's timelines to the specified skeleton.
|
||||
* @see Timeline#apply(Skeleton, float, float, Array, float, boolean, boolean) */
|
||||
* <p>
|
||||
* See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, boolean, boolean)}. */
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, boolean loop, Array<Event> events, float alpha,
|
||||
boolean setupPose, boolean mixingOut) {
|
||||
if (skeleton == null) throw new IllegalArgumentException("skeleton cannot be null.");
|
||||
@ -79,6 +81,7 @@ public class Animation {
|
||||
timelines.get(i).apply(skeleton, lastTime, time, events, alpha, setupPose, false);
|
||||
}
|
||||
|
||||
/** The animation's name, which is unique within the skeleton. */
|
||||
public String getName () {
|
||||
return name;
|
||||
}
|
||||
@ -127,17 +130,32 @@ public class Animation {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** The interface for all timelines. */
|
||||
static public interface Timeline {
|
||||
/** Sets the value(s) for the specified time.
|
||||
* @param events May be null to not collect fired events.
|
||||
* @param setupPose True when the timeline is mixed with the setup pose, false when it is mixed with the current pose.
|
||||
* Passing true when alpha is 1 is slightly more efficient for most timelines.
|
||||
* @param mixingOut True when changing alpha over time toward 0 (the setup or current pose), false when changing alpha
|
||||
* toward 1 (the timeline's pose). Used for timelines with instant transitions, eg draw order, attachment
|
||||
* visibility, scale sign. */
|
||||
/** Applies this timeline to the skeleton.
|
||||
* @param skeleton The skeleton the timeline is being applied to. This provides access to the bones, slots, and other
|
||||
* skeleton components the timeline may change.
|
||||
* @param lastTime The time this timeline was last applied. Timelines such as {@link EventTimeline} trigger only at specific
|
||||
* times rather than every frame. In that case, the timeline triggers everything between <code>lastTime</code>
|
||||
* (exclusive) and <code>time</code> (inclusive).
|
||||
* @param time The time within the animation. Most timelines find the key before and the key after this time so they can
|
||||
* interpolate between the keys.
|
||||
* @param events If any events are fired, they are added to this list. Can be null to ignore firing events or if the
|
||||
* timeline does not fire events.
|
||||
* @param alpha 0 results in the value of the current or setup pose (depending on <code>setupPose</code>). 1 results in the
|
||||
* value from the timeline. Between 0 and 1 results in a value mixed between the current or setup pose and the
|
||||
* value from the timeline. By adjusting <code>alpha</code> over time, an animation can be mixed in or out.
|
||||
* <code>alpha</code> can also be useful to apply animations on top of each other.
|
||||
* @param setupPose Controls mixing when <code>alpha</code> < 1. When true the value from the timeline is mixed with the
|
||||
* value from the setup pose. When false the value from the timeline is mixed with the value from the current
|
||||
* pose. Passing true when <code>alpha</code> is 1 is slightly more efficient for most timelines.
|
||||
* @param mixingOut True when changing <code>alpha</code> over time toward 0 (the setup or current pose), false when
|
||||
* changing <code>alpha</code> toward 1 (the timeline's pose). Used for timelines which perform instant
|
||||
* transitions, such as {@link DrawOrderTimeline} or {@link AttachmentTimeline}. */
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose,
|
||||
boolean mixingOut);
|
||||
|
||||
/** Uniquely encodes both the type of this timeline and the skeleton property that it affects. */
|
||||
public int getPropertyId ();
|
||||
}
|
||||
|
||||
@ -149,7 +167,7 @@ public class Animation {
|
||||
pathConstraintPosition, pathConstraintSpacing, pathConstraintMix
|
||||
}
|
||||
|
||||
/** Base class for frames that use an interpolation bezier curve. */
|
||||
/** The base class for timelines that use interpolation between key frame values. */
|
||||
abstract static public class CurveTimeline implements Timeline {
|
||||
static public final float LINEAR = 0, STEPPED = 1, BEZIER = 2;
|
||||
static private final int BEZIER_SIZE = 10 * 2 - 1;
|
||||
@ -161,18 +179,23 @@ public class Animation {
|
||||
curves = new float[(frameCount - 1) * BEZIER_SIZE];
|
||||
}
|
||||
|
||||
/** The number of key frames for this timeline. */
|
||||
public int getFrameCount () {
|
||||
return curves.length / BEZIER_SIZE + 1;
|
||||
}
|
||||
|
||||
/** Sets the specified key frame to linear interpolation. */
|
||||
public void setLinear (int frameIndex) {
|
||||
curves[frameIndex * BEZIER_SIZE] = LINEAR;
|
||||
}
|
||||
|
||||
/** Sets the specified key frame to stepped interpolation. */
|
||||
public void setStepped (int frameIndex) {
|
||||
curves[frameIndex * BEZIER_SIZE] = STEPPED;
|
||||
}
|
||||
|
||||
/** Returns the interpolation type for the specified key frame.
|
||||
* @return Linear is 0, stepped is 1, Bezier is 2. */
|
||||
public float getCurveType (int frameIndex) {
|
||||
int index = frameIndex * BEZIER_SIZE;
|
||||
if (index == curves.length) return LINEAR;
|
||||
@ -182,9 +205,9 @@ public class Animation {
|
||||
return BEZIER;
|
||||
}
|
||||
|
||||
/** Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next.
|
||||
* cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of
|
||||
* the difference between the keyframe's values. */
|
||||
/** Sets the specified key frame to Bezier interpolation. <code>cx1</code> and <code>cx2</code> are from 0 to 1,
|
||||
* representing the percent of time between the two key frames. <code>cy1</code> and <code>cy2</code> are the percent of the
|
||||
* difference between the key frame's values. */
|
||||
public void setCurve (int frameIndex, float cx1, float cy1, float cx2, float cy2) {
|
||||
float tmpx = (-cx1 * 2 + cx2) * 0.03f, tmpy = (-cy1 * 2 + cy2) * 0.03f;
|
||||
float dddfx = ((cx1 - cx2) * 3 + 1) * 0.006f, dddfy = ((cy1 - cy2) * 3 + 1) * 0.006f;
|
||||
@ -208,6 +231,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the interpolated percentage for the specified key frame and linear percentage. */
|
||||
public float getCurvePercent (int frameIndex, float percent) {
|
||||
percent = MathUtils.clamp(percent, 0, 1);
|
||||
float[] curves = this.curves;
|
||||
@ -236,6 +260,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a bone's local {@link Bone#getRotation()}. */
|
||||
static public class RotateTimeline extends CurveTimeline {
|
||||
static public final int ENTRIES = 2;
|
||||
static final int PREV_TIME = -2, PREV_ROTATION = -1;
|
||||
@ -258,15 +283,17 @@ public class Animation {
|
||||
this.boneIndex = index;
|
||||
}
|
||||
|
||||
/** The index of the bone in {@link Skeleton#getBones()} that will be changed. */
|
||||
public int getBoneIndex () {
|
||||
return boneIndex;
|
||||
}
|
||||
|
||||
/** The time in seconds and rotation in degrees for each key frame. */
|
||||
public float[] getFrames () {
|
||||
return frames;
|
||||
}
|
||||
|
||||
/** Sets the time and angle of the specified keyframe. */
|
||||
/** Sets the time in seconds and the rotation in degrees for the specified key frame. */
|
||||
public void setFrame (int frameIndex, float time, float degrees) {
|
||||
frameIndex <<= 1;
|
||||
frames[frameIndex] = time;
|
||||
@ -311,6 +338,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a bone's local {@link Bone#getX()} and {@link Bone#getY()}. */
|
||||
static public class TranslateTimeline extends CurveTimeline {
|
||||
static public final int ENTRIES = 3;
|
||||
static final int PREV_TIME = -3, PREV_X = -2, PREV_Y = -1;
|
||||
@ -333,15 +361,17 @@ public class Animation {
|
||||
this.boneIndex = index;
|
||||
}
|
||||
|
||||
/** The index of the bone in {@link Skeleton#getBones()} that will be changed. */
|
||||
public int getBoneIndex () {
|
||||
return boneIndex;
|
||||
}
|
||||
|
||||
/** The time in seconds, x, and y values for each key frame. */
|
||||
public float[] getFrames () {
|
||||
return frames;
|
||||
}
|
||||
|
||||
/** Sets the time and value of the specified keyframe. */
|
||||
/** Sets the time in seconds, x, and y values for the specified key frame. */
|
||||
public void setFrame (int frameIndex, float time, float x, float y) {
|
||||
frameIndex *= ENTRIES;
|
||||
frames[frameIndex] = time;
|
||||
@ -382,6 +412,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a bone's local {@link Bone#getScaleX()} and {@link Bone#getScaleY()}. */
|
||||
static public class ScaleTimeline extends TranslateTimeline {
|
||||
public ScaleTimeline (int frameCount) {
|
||||
super(frameCount);
|
||||
@ -440,6 +471,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a bone's local {@link Bone#getShearX()} and {@link Bone#getShearY()}. */
|
||||
static public class ShearTimeline extends TranslateTimeline {
|
||||
public ShearTimeline (int frameCount) {
|
||||
super(frameCount);
|
||||
@ -482,6 +514,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a slot's {@link Slot#getColor()}. */
|
||||
static public class ColorTimeline extends CurveTimeline {
|
||||
static public final int ENTRIES = 5;
|
||||
static private final int PREV_TIME = -5, PREV_R = -4, PREV_G = -3, PREV_B = -2, PREV_A = -1;
|
||||
@ -504,15 +537,17 @@ public class Animation {
|
||||
this.slotIndex = index;
|
||||
}
|
||||
|
||||
/** The index of the slot in {@link Skeleton#getSlots()} that will be changed. */
|
||||
public int getSlotIndex () {
|
||||
return slotIndex;
|
||||
}
|
||||
|
||||
/** The time in seconds, red, green, blue, and alpha values for each key frame. */
|
||||
public float[] getFrames () {
|
||||
return frames;
|
||||
}
|
||||
|
||||
/** Sets the time and value of the specified keyframe. */
|
||||
/** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */
|
||||
public void setFrame (int frameIndex, float time, float r, float g, float b, float a) {
|
||||
frameIndex *= ENTRIES;
|
||||
frames[frameIndex] = time;
|
||||
@ -561,6 +596,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a slot's {@link Slot#getAttachment()}. */
|
||||
static public class AttachmentTimeline implements Timeline {
|
||||
int slotIndex;
|
||||
final float[] frames; // time, ...
|
||||
@ -575,6 +611,7 @@ public class Animation {
|
||||
return (TimelineType.attachment.ordinal() << 24) + slotIndex;
|
||||
}
|
||||
|
||||
/** The number of key frames for this timeline. */
|
||||
public int getFrameCount () {
|
||||
return frames.length;
|
||||
}
|
||||
@ -584,19 +621,22 @@ public class Animation {
|
||||
this.slotIndex = index;
|
||||
}
|
||||
|
||||
/** The index of the slot in {@link Skeleton#getSlots()} that will be changed. */
|
||||
public int getSlotIndex () {
|
||||
return slotIndex;
|
||||
}
|
||||
|
||||
/** The time in seconds for each key frame. */
|
||||
public float[] getFrames () {
|
||||
return frames;
|
||||
}
|
||||
|
||||
/** The attachment name for each key frame. May contain null values to clear the attachment. */
|
||||
public String[] getAttachmentNames () {
|
||||
return attachmentNames;
|
||||
}
|
||||
|
||||
/** Sets the time and value of the specified keyframe. */
|
||||
/** Sets the time in seconds and the attachment name for the specified key frame. */
|
||||
public void setFrame (int frameIndex, float time, String attachmentName) {
|
||||
frames[frameIndex] = time;
|
||||
attachmentNames[frameIndex] = attachmentName;
|
||||
@ -626,6 +666,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a slot's {@link Slot#getAttachmentVertices()} to deform a {@link VertexAttachment}. */
|
||||
static public class DeformTimeline extends CurveTimeline {
|
||||
int slotIndex;
|
||||
VertexAttachment attachment;
|
||||
@ -647,6 +688,7 @@ public class Animation {
|
||||
this.slotIndex = index;
|
||||
}
|
||||
|
||||
/** The index of the slot in {@link Skeleton#getSlots()} that will be changed. */
|
||||
public int getSlotIndex () {
|
||||
return slotIndex;
|
||||
}
|
||||
@ -655,19 +697,23 @@ public class Animation {
|
||||
this.attachment = attachment;
|
||||
}
|
||||
|
||||
/** The attachment that will be deformed. */
|
||||
public VertexAttachment getAttachment () {
|
||||
return attachment;
|
||||
}
|
||||
|
||||
/** The time in seconds for each key frame. */
|
||||
public float[] getFrames () {
|
||||
return frames;
|
||||
}
|
||||
|
||||
/** The vertices for each key frame. */
|
||||
public float[][] getVertices () {
|
||||
return frameVertices;
|
||||
}
|
||||
|
||||
/** Sets the time of the specified keyframe. */
|
||||
/** Sets the time in seconds and the vertices for the specified key frame.
|
||||
* @param vertices Vertex positions for an unweighted VertexAttachment, or deform offsets if it has weights. */
|
||||
public void setFrame (int frameIndex, float time, float[] vertices) {
|
||||
frames[frameIndex] = time;
|
||||
frameVertices[frameIndex] = vertices;
|
||||
@ -755,6 +801,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Fires an {@link Event} when specific animation times are reached. */
|
||||
static public class EventTimeline implements Timeline {
|
||||
private final float[] frames; // time, ...
|
||||
private final Event[] events;
|
||||
@ -768,25 +815,28 @@ public class Animation {
|
||||
return TimelineType.event.ordinal() << 24;
|
||||
}
|
||||
|
||||
/** The number of key frames for this timeline. */
|
||||
public int getFrameCount () {
|
||||
return frames.length;
|
||||
}
|
||||
|
||||
/** The time in seconds for each key frame. */
|
||||
public float[] getFrames () {
|
||||
return frames;
|
||||
}
|
||||
|
||||
/** The event for each key frame. */
|
||||
public Event[] getEvents () {
|
||||
return events;
|
||||
}
|
||||
|
||||
/** Sets the time of the specified keyframe. */
|
||||
/** Sets the time in seconds and the event for the specified key frame. */
|
||||
public void setFrame (int frameIndex, Event event) {
|
||||
frames[frameIndex] = event.time;
|
||||
events[frameIndex] = event;
|
||||
}
|
||||
|
||||
/** Fires events for frames > lastTime and <= time. */
|
||||
/** Fires events for frames > <code>lastTime</code> and <= <code>time</code>. */
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> firedEvents, float alpha, boolean setupPose,
|
||||
boolean mixingOut) {
|
||||
if (firedEvents == null) return;
|
||||
@ -816,6 +866,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a skeleton's {@link Skeleton#getDrawOrder()}. */
|
||||
static public class DrawOrderTimeline implements Timeline {
|
||||
private final float[] frames; // time, ...
|
||||
private final int[][] drawOrders;
|
||||
@ -829,20 +880,24 @@ public class Animation {
|
||||
return TimelineType.drawOrder.ordinal() << 24;
|
||||
}
|
||||
|
||||
/** The number of key frames for this timeline. */
|
||||
public int getFrameCount () {
|
||||
return frames.length;
|
||||
}
|
||||
|
||||
/** The time in seconds for each key frame. */
|
||||
public float[] getFrames () {
|
||||
return frames;
|
||||
}
|
||||
|
||||
/** The draw order for each key frame. See {@link #setFrame(int, float, int[])}. */
|
||||
public int[][] getDrawOrders () {
|
||||
return drawOrders;
|
||||
}
|
||||
|
||||
/** Sets the time of the specified keyframe.
|
||||
* @param drawOrder May be null to use bind pose draw order. */
|
||||
/** Sets the time in seconds and the draw order for the specified key frame.
|
||||
* @param drawOrder For each slot in {@link Skeleton#slots}, the index of the new draw order. May be null to use setup pose
|
||||
* draw order. */
|
||||
public void setFrame (int frameIndex, float time, int[] drawOrder) {
|
||||
frames[frameIndex] = time;
|
||||
drawOrders[frameIndex] = drawOrder;
|
||||
@ -876,6 +931,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes an IK constraint's {@link IkConstraint#getMix()} and {@link IkConstraint#getBendDirection()}. */
|
||||
static public class IkConstraintTimeline extends CurveTimeline {
|
||||
static public final int ENTRIES = 3;
|
||||
static private final int PREV_TIME = -3, PREV_MIX = -2, PREV_BEND_DIRECTION = -1;
|
||||
@ -898,15 +954,17 @@ public class Animation {
|
||||
this.ikConstraintIndex = index;
|
||||
}
|
||||
|
||||
/** The index of the IK constraint slot in {@link Skeleton#getIkConstraints()} that will be changed. */
|
||||
public int getIkConstraintIndex () {
|
||||
return ikConstraintIndex;
|
||||
}
|
||||
|
||||
/** The time in seconds, mix, and bend direction for each key frame. */
|
||||
public float[] getFrames () {
|
||||
return frames;
|
||||
}
|
||||
|
||||
/** Sets the time, mix and bend direction of the specified keyframe. */
|
||||
/** Sets the time in seconds, mix, and bend direction for the specified key frame. */
|
||||
public void setFrame (int frameIndex, float time, float mix, int bendDirection) {
|
||||
frameIndex *= ENTRIES;
|
||||
frames[frameIndex] = time;
|
||||
@ -949,6 +1007,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a transform constraint's mixes. */
|
||||
static public class TransformConstraintTimeline extends CurveTimeline {
|
||||
static public final int ENTRIES = 5;
|
||||
static private final int PREV_TIME = -5, PREV_ROTATE = -4, PREV_TRANSLATE = -3, PREV_SCALE = -2, PREV_SHEAR = -1;
|
||||
@ -971,15 +1030,17 @@ public class Animation {
|
||||
this.transformConstraintIndex = index;
|
||||
}
|
||||
|
||||
/** The index of the transform constraint slot in {@link Skeleton#getTransformConstraints()} that will be changed. */
|
||||
public int getTransformConstraintIndex () {
|
||||
return transformConstraintIndex;
|
||||
}
|
||||
|
||||
/** The time in seconds, rotate mix, translate mix, scale mix, and shear mix for each key frame. */
|
||||
public float[] getFrames () {
|
||||
return frames;
|
||||
}
|
||||
|
||||
/** Sets the time and mixes of the specified keyframe. */
|
||||
/** The time in seconds, rotate mix, translate mix, scale mix, and shear mix for the specified key frame. */
|
||||
public void setFrame (int frameIndex, float time, float rotateMix, float translateMix, float scaleMix, float shearMix) {
|
||||
frameIndex *= ENTRIES;
|
||||
frames[frameIndex] = time;
|
||||
@ -1034,6 +1095,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a path constraint's {@link PathConstraint#getPosition()}. */
|
||||
static public class PathConstraintPositionTimeline extends CurveTimeline {
|
||||
static public final int ENTRIES = 2;
|
||||
static final int PREV_TIME = -2, PREV_VALUE = -1;
|
||||
@ -1057,19 +1119,21 @@ public class Animation {
|
||||
this.pathConstraintIndex = index;
|
||||
}
|
||||
|
||||
/** The index of the path constraint slot in {@link Skeleton#getPathConstraints()} that will be changed. */
|
||||
public int getPathConstraintIndex () {
|
||||
return pathConstraintIndex;
|
||||
}
|
||||
|
||||
/** The time in seconds and path constraint position for each key frame. */
|
||||
public float[] getFrames () {
|
||||
return frames;
|
||||
}
|
||||
|
||||
/** Sets the time and value of the specified keyframe. */
|
||||
public void setFrame (int frameIndex, float time, float value) {
|
||||
/** Sets the time in seconds and path constraint position for the specified key frame. */
|
||||
public void setFrame (int frameIndex, float time, float position) {
|
||||
frameIndex *= ENTRIES;
|
||||
frames[frameIndex] = time;
|
||||
frames[frameIndex + VALUE] = value;
|
||||
frames[frameIndex + VALUE] = position;
|
||||
}
|
||||
|
||||
public void apply (Skeleton skeleton, float lastTime, float time, Array<Event> events, float alpha, boolean setupPose,
|
||||
@ -1099,6 +1163,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a path constraint's {@link PathConstraint#getSpacing()}. */
|
||||
static public class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
|
||||
public PathConstraintSpacingTimeline (int frameCount) {
|
||||
super(frameCount);
|
||||
@ -1136,6 +1201,7 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Changes a path constraint's mixes. */
|
||||
static public class PathConstraintMixTimeline extends CurveTimeline {
|
||||
static public final int ENTRIES = 3;
|
||||
static private final int PREV_TIME = -3, PREV_ROTATE = -2, PREV_TRANSLATE = -1;
|
||||
@ -1159,15 +1225,17 @@ public class Animation {
|
||||
this.pathConstraintIndex = index;
|
||||
}
|
||||
|
||||
/** The index of the path constraint slot in {@link Skeleton#getPathConstraints()} that will be changed. */
|
||||
public int getPathConstraintIndex () {
|
||||
return pathConstraintIndex;
|
||||
}
|
||||
|
||||
/** The time in seconds, rotate mix, and translate mix for each key frame. */
|
||||
public float[] getFrames () {
|
||||
return frames;
|
||||
}
|
||||
|
||||
/** Sets the time and mixes of the specified keyframe. */
|
||||
/** The time in seconds, rotate mix, and translate mix for the specified key frame. */
|
||||
public void setFrame (int frameIndex, float time, float rotateMix, float translateMix) {
|
||||
frameIndex *= ENTRIES;
|
||||
frames[frameIndex] = time;
|
||||
|
||||
@ -43,11 +43,10 @@ import com.esotericsoftware.spine.Animation.DrawOrderTimeline;
|
||||
import com.esotericsoftware.spine.Animation.RotateTimeline;
|
||||
import com.esotericsoftware.spine.Animation.Timeline;
|
||||
|
||||
/** Stores state for applying one or more animations over time and mixing (crossfading) between animations.
|
||||
/** Applies animations over time, queues animations for later playback, mixes (crossfading) between animations, and applies
|
||||
* multiple animations on top of each other (layering).
|
||||
* <p>
|
||||
* Animations on different tracks are applied sequentially each frame, from lowest to highest track index. This enables animations
|
||||
* to be layered, where higher tracks either key only a subset of the skeleton pose or use alpha < 1 to mix with the pose on the
|
||||
* lower track. */
|
||||
* See <a href='http://esotericsoftware.com/spine-applying-animations/'>Applying Animations</a> in the Spine Runtimes Guide. */
|
||||
public class AnimationState {
|
||||
static private final Animation emptyAnimation = new Animation("<empty>", new Array(0), 0);
|
||||
|
||||
@ -75,7 +74,7 @@ public class AnimationState {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/** Increments the track entry times, setting queued animations as current if needed. */
|
||||
/** Increments each track entry {@link TrackEntry#getTrackTime()}, setting queued animations as current if needed. */
|
||||
public void update (float delta) {
|
||||
delta *= timeScale;
|
||||
for (int i = 0, n = tracks.size; i < n; i++) {
|
||||
@ -337,10 +336,10 @@ public class AnimationState {
|
||||
events.clear();
|
||||
}
|
||||
|
||||
/** Removes all animations from all tracks, leaving skeletons in their last pose.
|
||||
/** Removes all animations from all tracks, leaving skeletons in their previous 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 last pose. */
|
||||
* rather than leaving them in their previous pose. */
|
||||
public void clearTracks () {
|
||||
queue.drainDisabled = true;
|
||||
for (int i = 0, n = tracks.size; i < n; i++)
|
||||
@ -350,10 +349,10 @@ public class AnimationState {
|
||||
queue.drain();
|
||||
}
|
||||
|
||||
/** Removes all animations from the track, leaving skeletons in their last pose.
|
||||
/** Removes all animations from the track, leaving skeletons in their previous 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 last pose. */
|
||||
* rather than leaving them in their previous pose. */
|
||||
public void clearTrack (int trackIndex) {
|
||||
if (trackIndex >= tracks.size) return;
|
||||
TrackEntry current = tracks.get(trackIndex);
|
||||
@ -395,7 +394,9 @@ public class AnimationState {
|
||||
queue.start(current);
|
||||
}
|
||||
|
||||
/** @see #setAnimation(int, Animation, boolean) */
|
||||
/** Sets an animation by name.
|
||||
* <p>
|
||||
* {@link #setAnimation(int, Animation, boolean)}. */
|
||||
public TrackEntry setAnimation (int trackIndex, String animationName, boolean loop) {
|
||||
Animation animation = data.skeletonData.findAnimation(animationName);
|
||||
if (animation == null) throw new IllegalArgumentException("Animation not found: " + animationName);
|
||||
@ -403,8 +404,10 @@ public class AnimationState {
|
||||
}
|
||||
|
||||
/** Sets the current animation for a track, discarding any queued animations.
|
||||
* @param loop If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its
|
||||
* duration. In either case {@link TrackEntry#getTrackEnd()} determines when the track is cleared.
|
||||
* @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
|
||||
* after {@link AnimationStateListener#dispose(TrackEntry)}. */
|
||||
* after the {@link AnimationStateListener#dispose(TrackEntry)} event occurs. */
|
||||
public TrackEntry setAnimation (int trackIndex, Animation animation, boolean loop) {
|
||||
if (animation == null) throw new IllegalArgumentException("animation cannot be null.");
|
||||
TrackEntry current = expandToIndex(trackIndex);
|
||||
@ -425,18 +428,21 @@ public class AnimationState {
|
||||
return entry;
|
||||
}
|
||||
|
||||
/** {@link #addAnimation(int, Animation, boolean, float)} */
|
||||
/** Queues an animation by name.
|
||||
* <p>
|
||||
* See {@link #addAnimation(int, Animation, boolean, float)}. */
|
||||
public TrackEntry addAnimation (int trackIndex, String animationName, boolean loop, float delay) {
|
||||
Animation animation = data.skeletonData.findAnimation(animationName);
|
||||
if (animation == null) throw new IllegalArgumentException("Animation not found: " + animationName);
|
||||
return addAnimation(trackIndex, animation, loop, delay);
|
||||
}
|
||||
|
||||
/** Adds an animation to be played after the current or last queued animation for a track.
|
||||
/** Adds an animation to be played after the current or last queued animation for a track. If the track is empty, it is
|
||||
* equivalent to calling {@link #setAnimation(int, Animation, boolean)}.
|
||||
* @param delay Seconds to begin this animation after the start of the previous animation. May be <= 0 to use the animation
|
||||
* duration of the previous track minus any mix duration plus the negative delay.
|
||||
* duration of the previous track minus any mix duration plus the <code>delay</code>.
|
||||
* @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
|
||||
* after {@link AnimationStateListener#dispose(TrackEntry)}. */
|
||||
* after the {@link AnimationStateListener#dispose(TrackEntry)} event occurs. */
|
||||
public TrackEntry addAnimation (int trackIndex, Animation animation, boolean loop, float delay) {
|
||||
if (animation == null) throw new IllegalArgumentException("animation cannot be null.");
|
||||
|
||||
@ -466,7 +472,13 @@ public class AnimationState {
|
||||
return entry;
|
||||
}
|
||||
|
||||
/** Sets an empty animation for a track, discarding any queued animations, and mixes to it over the specified mix duration. */
|
||||
/** Sets an empty animation for a track, discarding any queued animations, and sets the track entry's
|
||||
* {@link TrackEntry#getMixDuration()}.
|
||||
* <p>
|
||||
* Mixing out is done by setting an empty animation. A mix duration of 0 still mixes out over one frame.
|
||||
* <p>
|
||||
* To mix in, first set an empty animation and add an animation using {@link #addAnimation(int, Animation, boolean, float)},
|
||||
* then set the {@link TrackEntry#setMixDuration(float)} on the returned track entry. */
|
||||
public TrackEntry setEmptyAnimation (int trackIndex, float mixDuration) {
|
||||
TrackEntry entry = setAnimation(trackIndex, emptyAnimation, false);
|
||||
entry.mixDuration = mixDuration;
|
||||
@ -474,12 +486,13 @@ public class AnimationState {
|
||||
return entry;
|
||||
}
|
||||
|
||||
/** Adds an empty animation to be played after the current or last queued animation for a track, and mixes to it over the
|
||||
* specified mix duration.
|
||||
/** Adds an empty animation to be played after the current or last queued animation for a track, and sets the track entry's
|
||||
* {@link TrackEntry#getMixDuration()}. If the track is empty, it is equivalent to calling
|
||||
* {@link #setEmptyAnimation(int, float)}.
|
||||
* @param delay Seconds to begin this animation after the start of the previous animation. May be <= 0 to use the animation
|
||||
* duration of the previous track minus any mix duration plus the negative delay.
|
||||
* duration of the previous track minus any mix duration plus <code>delay</code>.
|
||||
* @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
|
||||
* after {@link AnimationStateListener#dispose(TrackEntry)}. */
|
||||
* after the {@link AnimationStateListener#dispose(TrackEntry)} event occurs. */
|
||||
public TrackEntry addEmptyAnimation (int trackIndex, float mixDuration, float delay) {
|
||||
if (delay <= 0) delay -= mixDuration;
|
||||
TrackEntry entry = addAnimation(trackIndex, emptyAnimation, false, delay);
|
||||
@ -598,7 +611,7 @@ public class AnimationState {
|
||||
usage[i] = propertyIDs.add(timelines.get(i).getPropertyId());
|
||||
}
|
||||
|
||||
/** Returns the track entry for the animation currently playing on the track, or null. */
|
||||
/** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */
|
||||
public TrackEntry getCurrent (int trackIndex) {
|
||||
if (trackIndex >= tracks.size) return null;
|
||||
return tracks.get(trackIndex);
|
||||
@ -615,19 +628,22 @@ public class AnimationState {
|
||||
listeners.removeValue(listener, true);
|
||||
}
|
||||
|
||||
/** Removes all listeners added with {@link #addListener(AnimationStateListener)}. */
|
||||
public void clearListeners () {
|
||||
listeners.clear();
|
||||
}
|
||||
|
||||
/** Discards all {@link #addListener(AnimationStateListener) listener} notifications that have not yet been delivered. This can
|
||||
* be useful to call from an {@link AnimationStateListener} when it is known that further notifications that may have been
|
||||
* already queued for delivery are not wanted because new animations are being set. */
|
||||
/** Discards all listener notifications that have not yet been delivered. This can be useful to call from an
|
||||
* {@link AnimationStateListener} when it is known that further notifications that may have been already queued for delivery
|
||||
* are not wanted because new animations are being set. */
|
||||
public void clearListenerNotifications () {
|
||||
queue.clear();
|
||||
}
|
||||
|
||||
/** Multiplier for the delta time when the animation state is updated, causing time for all animations to play slower or
|
||||
* faster. Defaults to 1. */
|
||||
* faster. Defaults to 1.
|
||||
* <p>
|
||||
* See TrackEntry {@link TrackEntry#getTimeScale()} for affecting a single animation. */
|
||||
public float getTimeScale () {
|
||||
return timeScale;
|
||||
}
|
||||
@ -636,6 +652,7 @@ public class AnimationState {
|
||||
this.timeScale = timeScale;
|
||||
}
|
||||
|
||||
/** The AnimationStateData to look up mix durations. */
|
||||
public AnimationStateData getData () {
|
||||
return data;
|
||||
}
|
||||
@ -645,7 +662,7 @@ public class AnimationState {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/** Returns the list of tracks that have animations, which may contain null entries. */
|
||||
/** The list of tracks that currently have animations, which may contain null entries. */
|
||||
public Array<TrackEntry> getTracks () {
|
||||
return tracks;
|
||||
}
|
||||
@ -662,7 +679,9 @@ public class AnimationState {
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/** State for the playback of an animation. */
|
||||
/** Stores settings and other state for the playback of an animation on an {@link AnimationState} track.
|
||||
* <p>
|
||||
* References to a track entry must not be kept after the {@link AnimationStateListener#dispose(TrackEntry)} event occurs. */
|
||||
static public class TrackEntry implements Poolable {
|
||||
Animation animation;
|
||||
TrackEntry next, mixingFrom;
|
||||
@ -685,10 +704,14 @@ public class AnimationState {
|
||||
timelinesRotation.clear();
|
||||
}
|
||||
|
||||
/** The index of the track where this track entry is either current or queued.
|
||||
* <p>
|
||||
* See {@link AnimationState#getCurrent(int)}. */
|
||||
public int getTrackIndex () {
|
||||
return trackIndex;
|
||||
}
|
||||
|
||||
/** The animation to apply for this track entry. */
|
||||
public Animation getAnimation () {
|
||||
return animation;
|
||||
}
|
||||
@ -697,6 +720,8 @@ public class AnimationState {
|
||||
this.animation = animation;
|
||||
}
|
||||
|
||||
/** If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its
|
||||
* duration. */
|
||||
public boolean getLoop () {
|
||||
return loop;
|
||||
}
|
||||
@ -705,9 +730,9 @@ public class AnimationState {
|
||||
this.loop = loop;
|
||||
}
|
||||
|
||||
/** Seconds to postpone playing the animation. When a track entry is the current track entry, delay postpones incrementing
|
||||
* the track time. When a track entry is queued, delay is the time from the start of the previous animation to when the
|
||||
* track entry will become the current track entry. */
|
||||
/** Seconds to postpone playing the animation. When a track entry is the current track entry, <code>delay</code> postpones
|
||||
* incrementing the {@link #getTrackTime()}. When a track entry is queued, <code>delay</code> is the time from the start of
|
||||
* the previous animation to when the track entry will become the current track entry. */
|
||||
public float getDelay () {
|
||||
return delay;
|
||||
}
|
||||
@ -727,13 +752,13 @@ public class AnimationState {
|
||||
this.trackTime = trackTime;
|
||||
}
|
||||
|
||||
/** The track time in seconds when this animation will be removed from the track. Defaults to the animation duration for
|
||||
* non-looping animations and to {@link Integer#MAX_VALUE} for looping animations. If the track end time is reached, no
|
||||
* other animations are queued for playback, and mixing from any previous animations is complete, then the track is cleared,
|
||||
* leaving skeletons in their last pose.
|
||||
/** The track time in seconds when this animation will be removed from the track. Defaults to the animation
|
||||
* {@link Animation#duration} for non-looping animations and the highest float possible for looping animations. If the track
|
||||
* end time is reached, no other animations are queued for playback, and mixing from any previous animations is complete,
|
||||
* then the track is cleared, leaving skeletons in their previous pose.
|
||||
* <p>
|
||||
* It may be desired to use {@link AnimationState#addEmptyAnimation(int, float, float)} to mix the skeletons back to the
|
||||
* setup pose, rather than leaving them in their last pose. */
|
||||
* setup pose, rather than leaving them in their previous pose. */
|
||||
public float getTrackEnd () {
|
||||
return trackEnd;
|
||||
}
|
||||
@ -744,8 +769,8 @@ public class AnimationState {
|
||||
|
||||
/** Seconds when this animation starts, both initially and after looping. Defaults to 0.
|
||||
* <p>
|
||||
* When changing the animation start time, it often makes sense to set {@link #getAnimationLast()} to the same value to
|
||||
* prevent timeline keys before the start time from triggering. */
|
||||
* When changing the <code>animationStart</code> time, it often makes sense to set {@link #getAnimationLast()} to the same
|
||||
* value to prevent timeline keys before the start time from triggering. */
|
||||
public float getAnimationStart () {
|
||||
return animationStart;
|
||||
}
|
||||
@ -755,7 +780,7 @@ public class AnimationState {
|
||||
}
|
||||
|
||||
/** Seconds for the last frame of this animation. Non-looping animations won't play past this time. Looping animations will
|
||||
* loop back to {@link #getAnimationStart()} at this time. Defaults to the animation duration. */
|
||||
* loop back to {@link #getAnimationStart()} at this time. Defaults to the animation {@link Animation#duration}. */
|
||||
public float getAnimationEnd () {
|
||||
return animationEnd;
|
||||
}
|
||||
@ -765,8 +790,9 @@ public class AnimationState {
|
||||
}
|
||||
|
||||
/** The time in seconds this animation was last applied. Some timelines use this for one-time triggers. Eg, when this
|
||||
* animation is applied, event timelines will fire all events between the animation last time (exclusive) and animation time
|
||||
* (inclusive). Defaults to -1 to ensure triggers on frame 0 happen the first time this animation is applied. */
|
||||
* animation is applied, event timelines will fire all events between the <code>animationLast</code> time (exclusive) and
|
||||
* <code>animationTime</code> (inclusive). Defaults to -1 to ensure triggers on frame 0 happen the first time this animation
|
||||
* is applied. */
|
||||
public float getAnimationLast () {
|
||||
return animationLast;
|
||||
}
|
||||
@ -776,8 +802,9 @@ public class AnimationState {
|
||||
nextAnimationLast = animationLast;
|
||||
}
|
||||
|
||||
/** Uses {@link #getTrackTime()} to compute the animation time between {@link #getAnimationStart()} and
|
||||
* {@link #getAnimationEnd()}. When the track time is 0, the animation time is equal to the animation start time. */
|
||||
/** Uses {@link #getTrackTime()} to compute the <code>animationTime</code>, which is between {@link #getAnimationStart()}
|
||||
* and {@link #getAnimationEnd()}. When the <code>trackTime</code> is 0, the <code>animationTime</code> is equal to the
|
||||
* <code>animationStart</code> time. */
|
||||
public float getAnimationTime () {
|
||||
if (loop) {
|
||||
float duration = animationEnd - animationStart;
|
||||
@ -788,7 +815,9 @@ public class AnimationState {
|
||||
}
|
||||
|
||||
/** Multiplier for the delta time when the animation state is updated, causing time for this animation to pass slower or
|
||||
* faster. Defaults to 1. */
|
||||
* faster. Defaults to 1.
|
||||
* <p>
|
||||
* See AnimationState {@link AnimationState#getTimeScale()} for affecting all animations. */
|
||||
public float getTimeScale () {
|
||||
return timeScale;
|
||||
}
|
||||
@ -807,8 +836,8 @@ public class AnimationState {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
/** Values < 1 mix this animation with the setup pose or the skeleton's last pose. Defaults to 1, which overwrites the
|
||||
* skeleton's last pose with this animation.
|
||||
/** Values < 1 mix this animation with the setup pose or the skeleton's previous pose. Defaults to 1, which overwrites the
|
||||
* skeleton's previous pose with this animation.
|
||||
* <p>
|
||||
* Typically track 0 is used to completely pose the skeleton, then alpha can be 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. */
|
||||
@ -820,8 +849,9 @@ public class AnimationState {
|
||||
this.alpha = alpha;
|
||||
}
|
||||
|
||||
/** When the mix percentage (mix time / mix duration) is less than the event threshold, event timelines for the animation
|
||||
* being mixed out will be applied. Defaults to 0, so event timelines are not applied for an animation being mixed out. */
|
||||
/** When the mix percentage ({@link #getMixTime()} / {@link #getMixDuration()}) is less than the
|
||||
* <code>eventThreshold</code>, event timelines for the animation being mixed out will be applied. Defaults to 0, so event
|
||||
* timelines are not applied for an animation being mixed out. */
|
||||
public float getEventThreshold () {
|
||||
return eventThreshold;
|
||||
}
|
||||
@ -830,9 +860,9 @@ public class AnimationState {
|
||||
this.eventThreshold = eventThreshold;
|
||||
}
|
||||
|
||||
/** When the mix percentage (mix time / mix duration) is less than the attachment threshold, attachment timelines for the
|
||||
* animation being mixed out will be applied. Defaults to 0, so attachment timelines are not applied for an animation being
|
||||
* mixed out. */
|
||||
/** When the mix percentage ({@link #getMixTime()} / {@link #getMixDuration()}) is less than the
|
||||
* <code>attachmentThreshold</code>, attachment timelines for the animation being mixed out will be applied. Defaults to 0,
|
||||
* so attachment timelines are not applied for an animation being mixed out. */
|
||||
public float getAttachmentThreshold () {
|
||||
return attachmentThreshold;
|
||||
}
|
||||
@ -841,9 +871,9 @@ public class AnimationState {
|
||||
this.attachmentThreshold = attachmentThreshold;
|
||||
}
|
||||
|
||||
/** When the mix percentage (mix time / mix duration) is less than the draw order threshold, draw order timelines for the
|
||||
* animation being mixed out will be applied. Defaults to 0, so draw order timelines are not applied for an animation being
|
||||
* mixed out. */
|
||||
/** When the mix percentage ({@link #getMixTime()} / {@link #getMixDuration()}) is less than the
|
||||
* <code>drawOrderThreshold</code>, draw order timelines for the animation being mixed out will be applied. Defaults to 0,
|
||||
* so draw order timelines are not applied for an animation being mixed out. */
|
||||
public float getDrawOrderThreshold () {
|
||||
return drawOrderThreshold;
|
||||
}
|
||||
@ -852,19 +882,21 @@ public class AnimationState {
|
||||
this.drawOrderThreshold = drawOrderThreshold;
|
||||
}
|
||||
|
||||
/** The animation queued to start after this animation, or null. */
|
||||
/** The animation queued to start after this animation, or null. <code>next</code> makes up a linked list. */
|
||||
public TrackEntry getNext () {
|
||||
return next;
|
||||
}
|
||||
|
||||
/** Returns true if at least one loop has been completed. */
|
||||
/** Returns true if at least one loop has been completed.
|
||||
* <p>
|
||||
* See {@link AnimationStateListener#complete(TrackEntry)}. */
|
||||
public boolean isComplete () {
|
||||
return trackTime >= animationEnd - animationStart;
|
||||
}
|
||||
|
||||
/** Seconds from 0 to the mix duration when mixing from the previous animation to this animation. May be slightly more than
|
||||
* {@link #getMixDuration()} when the mix is complete. The mix time can be set manually rather than use the value from
|
||||
* AnimationStateData. */
|
||||
/** 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. The mix time can be set manually rather than use
|
||||
* the value from AnimationStateData {@link AnimationStateData#getMix(Animation, Animation)}. */
|
||||
public float getMixTime () {
|
||||
return mixTime;
|
||||
}
|
||||
@ -873,10 +905,11 @@ public class AnimationState {
|
||||
this.mixTime = mixTime;
|
||||
}
|
||||
|
||||
/** Seconds for mixing from the previous animation to this animation. Defaults to the value provided by
|
||||
* {@link AnimationStateData} based on the animation before this animation (if any).
|
||||
/** Seconds for mixing from the previous animation to this animation. Defaults to the value provided by AnimationStateData
|
||||
* {@link AnimationStateData#getMix(Animation, Animation)} based on the animation before this animation (if any).
|
||||
* <p>
|
||||
* The mix duration must be set before {@link AnimationState#update(float)} is next called. */
|
||||
* The <code>mixDuration</code> must be set for a new track entry before {@link AnimationState#update(float)} is next
|
||||
* called. */
|
||||
public float getMixDuration () {
|
||||
return mixDuration;
|
||||
}
|
||||
@ -886,7 +919,7 @@ public class AnimationState {
|
||||
}
|
||||
|
||||
/** The track entry for the previous animation when mixing from the previous animation to this animation, or null if no
|
||||
* mixing is currently occuring. If mixing from multiple animations, mixing from makes up a linked list. */
|
||||
* mixing is currently occuring. If mixing from multiple animations, <code>mixingFrom</code> makes up a linked list. */
|
||||
public TrackEntry getMixingFrom () {
|
||||
return mixingFrom;
|
||||
}
|
||||
@ -1003,7 +1036,7 @@ public class AnimationState {
|
||||
public void end (TrackEntry entry);
|
||||
|
||||
/** Invoked when this entry will be disposed. This may occur without the entry ever being set as the current entry.
|
||||
* References to the entry should not be kept after dispose is called, as it may be destroyed or reused. */
|
||||
* References to the entry should not be kept after <code>dispose</code> is called, as it may be destroyed or reused. */
|
||||
public void dispose (TrackEntry entry);
|
||||
|
||||
/** Invoked every time this entry's animation completes a loop. */
|
||||
|
||||
@ -31,10 +31,11 @@
|
||||
package com.esotericsoftware.spine;
|
||||
|
||||
import com.badlogic.gdx.utils.ObjectFloatMap;
|
||||
import com.esotericsoftware.spine.AnimationState.TrackEntry;
|
||||
|
||||
/** Stores mixing times between animations. */
|
||||
/** Stores mix (crossfade) durations to be applied when {@link AnimationState} animations are changed. */
|
||||
public class AnimationStateData {
|
||||
private final SkeletonData skeletonData;
|
||||
final SkeletonData skeletonData;
|
||||
final ObjectFloatMap<Key> animationToMixTime = new ObjectFloatMap();
|
||||
final Key tempKey = new Key();
|
||||
float defaultMix;
|
||||
@ -44,10 +45,14 @@ public class AnimationStateData {
|
||||
this.skeletonData = skeletonData;
|
||||
}
|
||||
|
||||
/** The SkeletonData to look up animations when they are specified by name. */
|
||||
public SkeletonData getSkeletonData () {
|
||||
return skeletonData;
|
||||
}
|
||||
|
||||
/** Sets a mix duration by animation name.
|
||||
* <p>
|
||||
* See {@link #setMix(Animation, Animation, float)}. */
|
||||
public void setMix (String fromName, String toName, float duration) {
|
||||
Animation from = skeletonData.findAnimation(fromName);
|
||||
if (from == null) throw new IllegalArgumentException("Animation not found: " + fromName);
|
||||
@ -56,6 +61,9 @@ public class AnimationStateData {
|
||||
setMix(from, to, duration);
|
||||
}
|
||||
|
||||
/** Sets the mix duration when changing from the specified animation to the other.
|
||||
* <p>
|
||||
* See {@link TrackEntry#mixDuration}. */
|
||||
public void setMix (Animation from, Animation to, float duration) {
|
||||
if (from == null) throw new IllegalArgumentException("from cannot be null.");
|
||||
if (to == null) throw new IllegalArgumentException("to cannot be null.");
|
||||
@ -65,6 +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. */
|
||||
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.");
|
||||
@ -73,6 +83,7 @@ public class AnimationStateData {
|
||||
return animationToMixTime.get(tempKey, defaultMix);
|
||||
}
|
||||
|
||||
/** The mix duration to use when no mix duration has been defined between two animations. */
|
||||
public float getDefaultMix () {
|
||||
return defaultMix;
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@ package com.esotericsoftware.spine;
|
||||
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
|
||||
/** Determines how images are blended with existing pixels when drawn. */
|
||||
public enum BlendMode {
|
||||
normal(GL20.GL_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA), //
|
||||
additive(GL20.GL_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE), //
|
||||
|
||||
@ -38,6 +38,7 @@ import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.esotericsoftware.spine.BoneData.TransformMode;
|
||||
|
||||
/** Stores a bone's current pose. */
|
||||
public class Bone implements Updatable {
|
||||
final BoneData data;
|
||||
final Skeleton skeleton;
|
||||
@ -84,12 +85,17 @@ public class Bone implements Updatable {
|
||||
updateWorldTransform(x, y, rotation, scaleX, scaleY, shearX, shearY);
|
||||
}
|
||||
|
||||
/** Computes the world transform using the parent bone and this bone's local transform. */
|
||||
/** Computes the world transform using the parent bone and this bone's local transform.
|
||||
* <p>
|
||||
* See {@link #updateWorldTransform(float, float, float, float, float, float, float)}. */
|
||||
public void updateWorldTransform () {
|
||||
updateWorldTransform(x, y, rotation, scaleX, scaleY, shearX, shearY);
|
||||
}
|
||||
|
||||
/** Computes the world transform using the parent bone and the specified local transform. */
|
||||
/** Computes the world transform using the parent bone and the specified local transform. Child bones are not updated.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-skeleton-manipulation#World-transforms">World transforms</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
public void updateWorldTransform (float x, float y, float rotation, float scaleX, float scaleY, float shearX, float shearY) {
|
||||
ax = x;
|
||||
ay = y;
|
||||
@ -214,6 +220,7 @@ public class Bone implements Updatable {
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets this bone's local transform to the setup pose. */
|
||||
public void setToSetupPose () {
|
||||
BoneData data = this.data;
|
||||
x = data.x;
|
||||
@ -225,22 +232,27 @@ public class Bone implements Updatable {
|
||||
shearY = data.shearY;
|
||||
}
|
||||
|
||||
/** The bone's setup pose data. */
|
||||
public BoneData getData () {
|
||||
return data;
|
||||
}
|
||||
|
||||
/** The skeleton this bone belongs to. */
|
||||
public Skeleton getSkeleton () {
|
||||
return skeleton;
|
||||
}
|
||||
|
||||
/** The parent bone, or null if this is the root bone. */
|
||||
public Bone getParent () {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/** The immediate children of this bone. */
|
||||
public Array<Bone> getChildren () {
|
||||
return children;
|
||||
}
|
||||
|
||||
/** The local x translation. */
|
||||
public float getX () {
|
||||
return x;
|
||||
}
|
||||
@ -249,6 +261,7 @@ public class Bone implements Updatable {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
/** The local y translation. */
|
||||
public float getY () {
|
||||
return y;
|
||||
}
|
||||
@ -262,6 +275,7 @@ public class Bone implements Updatable {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/** The local rotation. */
|
||||
public float getRotation () {
|
||||
return rotation;
|
||||
}
|
||||
@ -270,6 +284,7 @@ public class Bone implements Updatable {
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
/** The local scaleX. */
|
||||
public float getScaleX () {
|
||||
return scaleX;
|
||||
}
|
||||
@ -278,6 +293,7 @@ public class Bone implements Updatable {
|
||||
this.scaleX = scaleX;
|
||||
}
|
||||
|
||||
/** The local scaleY. */
|
||||
public float getScaleY () {
|
||||
return scaleY;
|
||||
}
|
||||
@ -296,6 +312,7 @@ public class Bone implements Updatable {
|
||||
scaleY = scale;
|
||||
}
|
||||
|
||||
/** The local shearX. */
|
||||
public float getShearX () {
|
||||
return shearX;
|
||||
}
|
||||
@ -304,6 +321,7 @@ public class Bone implements Updatable {
|
||||
this.shearX = shearX;
|
||||
}
|
||||
|
||||
/** The local shearY. */
|
||||
public float getShearY () {
|
||||
return shearY;
|
||||
}
|
||||
@ -312,44 +330,52 @@ public class Bone implements Updatable {
|
||||
this.shearY = shearY;
|
||||
}
|
||||
|
||||
/** Part of the world transform matrix for the X axis. */
|
||||
public float getA () {
|
||||
return a;
|
||||
}
|
||||
|
||||
/** Part of the world transform matrix for the Y axis. */
|
||||
public float getB () {
|
||||
return b;
|
||||
}
|
||||
|
||||
/** Part of the world transform matrix for the X axis. */
|
||||
public float getC () {
|
||||
return c;
|
||||
}
|
||||
|
||||
/** Part of the world transform matrix for the Y axis. */
|
||||
public float getD () {
|
||||
return d;
|
||||
}
|
||||
|
||||
/** The world X position. */
|
||||
public float getWorldX () {
|
||||
return worldX;
|
||||
}
|
||||
|
||||
/** The world Y position. */
|
||||
public float getWorldY () {
|
||||
return worldY;
|
||||
}
|
||||
|
||||
/** The world rotation for the X axis, calculated using {@link #a} and {@link #c}. */
|
||||
public float getWorldRotationX () {
|
||||
return atan2(c, a) * radDeg;
|
||||
}
|
||||
|
||||
/** The world rotation for the Y axis, calculated using {@link #b} and {@link #d}. */
|
||||
public float getWorldRotationY () {
|
||||
return atan2(d, b) * radDeg;
|
||||
}
|
||||
|
||||
/** Returns the magnitude (always positive) of the world scale X. */
|
||||
/** The magnitude (always positive) of the world scale X, calculated using {@link #a} and {@link #c}. */
|
||||
public float getWorldScaleX () {
|
||||
return (float)Math.sqrt(a * a + c * c);
|
||||
}
|
||||
|
||||
/** Returns the magnitude (always positive) of the world scale Y. */
|
||||
/** The magnitude (always positive) of the world scale Y, calculated using {@link #b} and {@link #d}. */
|
||||
public float getWorldScaleY () {
|
||||
return (float)Math.sqrt(b * b + d * d);
|
||||
}
|
||||
@ -366,6 +392,8 @@ public class Bone implements Updatable {
|
||||
return atan2(parent.a * d - parent.c * b, parent.d * b - parent.b * d) * radDeg;
|
||||
}
|
||||
|
||||
/** Rotates the world transform the specified amount. {@link #updateWorldTransform()} will need to be called on any child
|
||||
* bones, recursively. */
|
||||
public void rotateWorld (float degrees) {
|
||||
float cos = cosDeg(degrees), sin = sinDeg(degrees);
|
||||
a = cos * a - sin * c;
|
||||
@ -435,6 +463,7 @@ public class Bone implements Updatable {
|
||||
return worldTransform;
|
||||
}
|
||||
|
||||
/** Transforms a point from world coordinates to the bone's local coordinates. */
|
||||
public Vector2 worldToLocal (Vector2 world) {
|
||||
float invDet = 1 / (a * d - b * c);
|
||||
float x = world.x - worldX, y = world.y - worldY;
|
||||
@ -443,6 +472,7 @@ public class Bone implements Updatable {
|
||||
return world;
|
||||
}
|
||||
|
||||
/** Transforms a point from the bone's local coordinates to world coordinates. */
|
||||
public Vector2 localToWorld (Vector2 local) {
|
||||
float x = local.x, y = local.y;
|
||||
local.x = x * a + y * b + worldX;
|
||||
|
||||
@ -32,6 +32,7 @@ package com.esotericsoftware.spine;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
|
||||
/** Stores the setup pose for a {@link Bone}. */
|
||||
public class BoneData {
|
||||
final int index;
|
||||
final String name;
|
||||
@ -69,10 +70,12 @@ public class BoneData {
|
||||
shearY = bone.shearY;
|
||||
}
|
||||
|
||||
/** The index of the bone in {@link Skeleton#getBones()}. */
|
||||
public int getIndex () {
|
||||
return index;
|
||||
}
|
||||
|
||||
/** The name of the bone, which is unique within the skeleton. */
|
||||
public String getName () {
|
||||
return name;
|
||||
}
|
||||
@ -82,6 +85,7 @@ public class BoneData {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/** The bone's length. */
|
||||
public float getLength () {
|
||||
return length;
|
||||
}
|
||||
@ -90,6 +94,7 @@ public class BoneData {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
/** The local x translation. */
|
||||
public float getX () {
|
||||
return x;
|
||||
}
|
||||
@ -98,6 +103,7 @@ public class BoneData {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
/** The local y translation. */
|
||||
public float getY () {
|
||||
return y;
|
||||
}
|
||||
@ -111,6 +117,7 @@ public class BoneData {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/** The local rotation. */
|
||||
public float getRotation () {
|
||||
return rotation;
|
||||
}
|
||||
@ -119,6 +126,7 @@ public class BoneData {
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
/** The local scaleX. */
|
||||
public float getScaleX () {
|
||||
return scaleX;
|
||||
}
|
||||
@ -127,6 +135,7 @@ public class BoneData {
|
||||
this.scaleX = scaleX;
|
||||
}
|
||||
|
||||
/** The local scaleY. */
|
||||
public float getScaleY () {
|
||||
return scaleY;
|
||||
}
|
||||
@ -140,6 +149,7 @@ public class BoneData {
|
||||
this.scaleY = scaleY;
|
||||
}
|
||||
|
||||
/** The local shearX. */
|
||||
public float getShearX () {
|
||||
return shearX;
|
||||
}
|
||||
@ -148,6 +158,7 @@ public class BoneData {
|
||||
this.shearX = shearX;
|
||||
}
|
||||
|
||||
/** The local shearX. */
|
||||
public float getShearY () {
|
||||
return shearY;
|
||||
}
|
||||
@ -156,6 +167,7 @@ public class BoneData {
|
||||
this.shearY = shearY;
|
||||
}
|
||||
|
||||
/** The transform mode for how parent world transforms affect this bone. */
|
||||
public TransformMode getTransformMode () {
|
||||
return transformMode;
|
||||
}
|
||||
@ -164,6 +176,8 @@ public class BoneData {
|
||||
this.transformMode = transformMode;
|
||||
}
|
||||
|
||||
/** The color of the bone as it was in Spine. Available only when nonessential data was exported. Bones are not usually
|
||||
* rendered at runtime. */
|
||||
public Color getColor () {
|
||||
return color;
|
||||
}
|
||||
@ -172,6 +186,7 @@ public class BoneData {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** Determines how a bone inherits world transforms from parent bones. */
|
||||
static public enum TransformMode {
|
||||
normal, onlyTranslation, noRotationOrReflection, noScale, noScaleOrReflection;
|
||||
|
||||
|
||||
@ -30,6 +30,8 @@
|
||||
|
||||
package com.esotericsoftware.spine;
|
||||
|
||||
/** The interface for all constraints. */
|
||||
public interface Constraint extends Updatable {
|
||||
/** The ordinal for the order a skeleton's constraints will be applied. */
|
||||
public int getOrder ();
|
||||
}
|
||||
|
||||
@ -30,6 +30,14 @@
|
||||
|
||||
package com.esotericsoftware.spine;
|
||||
|
||||
import com.esotericsoftware.spine.Animation.Timeline;
|
||||
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)},
|
||||
* AnimationStateListener {@link AnimationStateListener#event(com.esotericsoftware.spine.AnimationState.TrackEntry, Event)}, and
|
||||
* <a href="http://esotericsoftware.com/spine-events">Events</a> in the Spine User Guide. */
|
||||
public class Event {
|
||||
final private EventData data;
|
||||
int intValue;
|
||||
@ -67,10 +75,12 @@ public class Event {
|
||||
this.stringValue = stringValue;
|
||||
}
|
||||
|
||||
/** The animation time this event was keyed. */
|
||||
public float getTime () {
|
||||
return time;
|
||||
}
|
||||
|
||||
/** The events's setup pose data. */
|
||||
public EventData getData () {
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -30,6 +30,9 @@
|
||||
|
||||
package com.esotericsoftware.spine;
|
||||
|
||||
/** Stores the setup pose values for an {@link Event}.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-events">Events</a> in the Spine User Guide. */
|
||||
public class EventData {
|
||||
final String name;
|
||||
int intValue;
|
||||
@ -65,6 +68,7 @@ public class EventData {
|
||||
this.stringValue = stringValue;
|
||||
}
|
||||
|
||||
/** The name of the event, which is unique within the skeleton. */
|
||||
public String getName () {
|
||||
return name;
|
||||
}
|
||||
|
||||
@ -34,6 +34,10 @@ import static com.badlogic.gdx.math.MathUtils.*;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
|
||||
/** Stores the current pose for an IK constraint. An IK constraint adjusts the rotation of 1 or 2 constrained bones so the tip of
|
||||
* the last bone is as close to the target bone as possible.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-ik-constraints">IK constraints</a> in the Spine User Guide. */
|
||||
public class IkConstraint implements Constraint {
|
||||
final IkConstraintData data;
|
||||
final Array<Bone> bones;
|
||||
@ -67,6 +71,7 @@ public class IkConstraint implements Constraint {
|
||||
bendDirection = constraint.bendDirection;
|
||||
}
|
||||
|
||||
/** Applies the constraint to the constrained bones. */
|
||||
public void apply () {
|
||||
update();
|
||||
}
|
||||
@ -88,10 +93,12 @@ public class IkConstraint implements Constraint {
|
||||
return data.order;
|
||||
}
|
||||
|
||||
/** The bones that will be modified by this IK constraint. */
|
||||
public Array<Bone> getBones () {
|
||||
return bones;
|
||||
}
|
||||
|
||||
/** The bone that is the IK target. */
|
||||
public Bone getTarget () {
|
||||
return target;
|
||||
}
|
||||
@ -100,6 +107,7 @@ public class IkConstraint implements Constraint {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */
|
||||
public float getMix () {
|
||||
return mix;
|
||||
}
|
||||
@ -108,6 +116,7 @@ public class IkConstraint implements Constraint {
|
||||
this.mix = mix;
|
||||
}
|
||||
|
||||
/** Controls the bend direction of the IK bones, either 1 or -1. */
|
||||
public int getBendDirection () {
|
||||
return bendDirection;
|
||||
}
|
||||
@ -116,6 +125,7 @@ public class IkConstraint implements Constraint {
|
||||
this.bendDirection = bendDirection;
|
||||
}
|
||||
|
||||
/** The IK constraint's setup pose data. */
|
||||
public IkConstraintData getData () {
|
||||
return data;
|
||||
}
|
||||
@ -124,8 +134,7 @@ public class IkConstraint implements Constraint {
|
||||
return data.name;
|
||||
}
|
||||
|
||||
/** Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified in the world
|
||||
* coordinate system. */
|
||||
/** Applies 1 bone IK. The target is specified in the world coordinate system. */
|
||||
static public void apply (Bone bone, float targetX, float targetY, float alpha) {
|
||||
if (!bone.appliedValid) bone.updateAppliedTransform();
|
||||
Bone p = bone.parent;
|
||||
@ -141,8 +150,7 @@ public class IkConstraint implements Constraint {
|
||||
bone.ashearY);
|
||||
}
|
||||
|
||||
/** Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as possible. The
|
||||
* target is specified in the world coordinate system.
|
||||
/** Applies 2 bone IK. The target is specified in the world coordinate system.
|
||||
* @param child A direct descendant of the parent bone. */
|
||||
static public void apply (Bone parent, Bone child, float targetX, float targetY, int bendDir, float alpha) {
|
||||
if (alpha == 0) {
|
||||
|
||||
@ -32,6 +32,9 @@ package com.esotericsoftware.spine;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
|
||||
/** Stores the setup pose for an {@link IkConstraint}.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-ik-constraints">IK constraints</a> in the Spine User Guide. */
|
||||
public class IkConstraintData {
|
||||
final String name;
|
||||
int order;
|
||||
@ -45,10 +48,12 @@ public class IkConstraintData {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/** The IK constraint's name, which is unique within the skeleton. */
|
||||
public String getName () {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** See {@link Constraint#getOrder()}. */
|
||||
public int getOrder () {
|
||||
return order;
|
||||
}
|
||||
@ -57,10 +62,12 @@ public class IkConstraintData {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
/** The bones that are constrained by this IK constraint. */
|
||||
public Array<BoneData> getBones () {
|
||||
return bones;
|
||||
}
|
||||
|
||||
/** The bone that is the IK target. */
|
||||
public BoneData getTarget () {
|
||||
return target;
|
||||
}
|
||||
@ -70,6 +77,7 @@ public class IkConstraintData {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/** Controls the bend direction of the IK bones, either 1 or -1. */
|
||||
public int getBendDirection () {
|
||||
return bendDirection;
|
||||
}
|
||||
@ -78,6 +86,7 @@ public class IkConstraintData {
|
||||
this.bendDirection = bendDirection;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */
|
||||
public float getMix () {
|
||||
return mix;
|
||||
}
|
||||
|
||||
@ -40,6 +40,10 @@ import com.esotericsoftware.spine.PathConstraintData.SpacingMode;
|
||||
import com.esotericsoftware.spine.attachments.Attachment;
|
||||
import com.esotericsoftware.spine.attachments.PathAttachment;
|
||||
|
||||
/** Stores the current pose for a path constraint. A path constraint adjusts the rotation, translation, and scale of the
|
||||
* constrained bones so they follow a {@link PathAttachment}.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-path-constraints">Path constraints</a> in the Spine User Guide. */
|
||||
public class PathConstraint implements Constraint {
|
||||
static private final int NONE = -1, BEFORE = -2, AFTER = -3;
|
||||
|
||||
@ -81,6 +85,7 @@ public class PathConstraint implements Constraint {
|
||||
translateMix = constraint.translateMix;
|
||||
}
|
||||
|
||||
/** Applies the constraint to the constrained bones. */
|
||||
public void apply () {
|
||||
update();
|
||||
}
|
||||
@ -414,6 +419,7 @@ public class PathConstraint implements Constraint {
|
||||
return data.order;
|
||||
}
|
||||
|
||||
/** The position along the path. */
|
||||
public float getPosition () {
|
||||
return position;
|
||||
}
|
||||
@ -422,6 +428,7 @@ public class PathConstraint implements Constraint {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/** The spacing between bones. */
|
||||
public float getSpacing () {
|
||||
return spacing;
|
||||
}
|
||||
@ -430,6 +437,7 @@ public class PathConstraint implements Constraint {
|
||||
this.spacing = spacing;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */
|
||||
public float getRotateMix () {
|
||||
return rotateMix;
|
||||
}
|
||||
@ -438,6 +446,7 @@ public class PathConstraint implements Constraint {
|
||||
this.rotateMix = rotateMix;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translations. */
|
||||
public float getTranslateMix () {
|
||||
return translateMix;
|
||||
}
|
||||
@ -446,10 +455,12 @@ public class PathConstraint implements Constraint {
|
||||
this.translateMix = translateMix;
|
||||
}
|
||||
|
||||
/** The bones that will be modified by this path constraint. */
|
||||
public Array<Bone> getBones () {
|
||||
return bones;
|
||||
}
|
||||
|
||||
/** The slot whose path attachment will be used to constrained the bones. */
|
||||
public Slot getTarget () {
|
||||
return target;
|
||||
}
|
||||
@ -458,6 +469,7 @@ public class PathConstraint implements Constraint {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/** The path constraint's setup pose data. */
|
||||
public PathConstraintData getData () {
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -32,6 +32,9 @@ package com.esotericsoftware.spine;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
|
||||
/** Stores the setup pose for a {@link PathConstraint}.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-path-constraints">Path constraints</a> in the Spine User Guide. */
|
||||
public class PathConstraintData {
|
||||
final String name;
|
||||
int order;
|
||||
@ -48,10 +51,12 @@ public class PathConstraintData {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/** The path constraint's name, which is unique within the skeleton. */
|
||||
public String getName () {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** See {@link Constraint#getOrder()}. */
|
||||
public int getOrder () {
|
||||
return order;
|
||||
}
|
||||
@ -60,10 +65,12 @@ public class PathConstraintData {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
/** The bones that will be modified by this path constraint. */
|
||||
public Array<BoneData> getBones () {
|
||||
return bones;
|
||||
}
|
||||
|
||||
/** The slot whose path attachment will be used to constrained the bones. */
|
||||
public SlotData getTarget () {
|
||||
return target;
|
||||
}
|
||||
@ -72,6 +79,7 @@ public class PathConstraintData {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/** The mode for positioning the first bone on the path. */
|
||||
public PositionMode getPositionMode () {
|
||||
return positionMode;
|
||||
}
|
||||
@ -80,6 +88,7 @@ public class PathConstraintData {
|
||||
this.positionMode = positionMode;
|
||||
}
|
||||
|
||||
/** The mode for positioning the bones after the first bone on the path. */
|
||||
public SpacingMode getSpacingMode () {
|
||||
return spacingMode;
|
||||
}
|
||||
@ -88,6 +97,7 @@ public class PathConstraintData {
|
||||
this.spacingMode = spacingMode;
|
||||
}
|
||||
|
||||
/** The mode for adjusting the rotation of the bones. */
|
||||
public RotateMode getRotateMode () {
|
||||
return rotateMode;
|
||||
}
|
||||
@ -96,6 +106,7 @@ public class PathConstraintData {
|
||||
this.rotateMode = rotateMode;
|
||||
}
|
||||
|
||||
/** An offset added to the constrained bone rotation. */
|
||||
public float getOffsetRotation () {
|
||||
return offsetRotation;
|
||||
}
|
||||
@ -104,6 +115,7 @@ public class PathConstraintData {
|
||||
this.offsetRotation = offsetRotation;
|
||||
}
|
||||
|
||||
/** The position along the path. */
|
||||
public float getPosition () {
|
||||
return position;
|
||||
}
|
||||
@ -112,6 +124,7 @@ public class PathConstraintData {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/** The spacing between bones. */
|
||||
public float getSpacing () {
|
||||
return spacing;
|
||||
}
|
||||
@ -120,6 +133,7 @@ public class PathConstraintData {
|
||||
this.spacing = spacing;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */
|
||||
public float getRotateMix () {
|
||||
return rotateMix;
|
||||
}
|
||||
@ -128,6 +142,7 @@ public class PathConstraintData {
|
||||
this.rotateMix = rotateMix;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translations. */
|
||||
public float getTranslateMix () {
|
||||
return translateMix;
|
||||
}
|
||||
@ -140,18 +155,27 @@ public class PathConstraintData {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** Controls how the first bone is positioned along the path.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-path-constraints#Position-mode">Position mode</a> in the Spine User Guide. */
|
||||
static public enum PositionMode {
|
||||
fixed, percent;
|
||||
|
||||
static public final PositionMode[] values = PositionMode.values();
|
||||
}
|
||||
|
||||
/** Controls how bones after the first bone are positioned along the path.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-path-constraints#Spacing-mode">Spacing mode</a> in the Spine User Guide. */
|
||||
static public enum SpacingMode {
|
||||
length, fixed, percent;
|
||||
|
||||
static public final SpacingMode[] values = SpacingMode.values();
|
||||
}
|
||||
|
||||
/** Controls how bones are rotated, translated, and scaled to match the path.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-path-constraints#Rotate-mode">Rotate mode</a> in the Spine User Guide. */
|
||||
static public enum RotateMode {
|
||||
tangent, chain, chainScale;
|
||||
|
||||
|
||||
@ -40,6 +40,10 @@ import com.esotericsoftware.spine.attachments.MeshAttachment;
|
||||
import com.esotericsoftware.spine.attachments.PathAttachment;
|
||||
import com.esotericsoftware.spine.attachments.RegionAttachment;
|
||||
|
||||
/** Stores the current pose for a skeleton.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-runtime-architecture#Instance-objects">Instance objects</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
public class Skeleton {
|
||||
final SkeletonData data;
|
||||
final Array<Bone> bones;
|
||||
@ -290,7 +294,10 @@ public class Skeleton {
|
||||
}
|
||||
}
|
||||
|
||||
/** Updates the world transform for each bone and applies constraints. */
|
||||
/** Updates the world transform for each bone and applies all constraints.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-skeleton-manipulation#World-transforms">World transforms</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
public void updateWorldTransform () {
|
||||
// This partial update avoids computing the world transform for constrained bones when 1) the bone is not updated
|
||||
// before the constraint, 2) the constraint only needs to access the applied local transform, and 3) the constraint calls
|
||||
@ -312,7 +319,7 @@ public class Skeleton {
|
||||
updateCache.get(i).update();
|
||||
}
|
||||
|
||||
/** Sets the bones, constraints, and slots to their setup pose values. */
|
||||
/** Sets the bones, constraints, slots, and draw order to their setup pose values. */
|
||||
public void setToSetupPose () {
|
||||
setBonesToSetupPose();
|
||||
setSlotsToSetupPose();
|
||||
@ -352,6 +359,7 @@ public class Skeleton {
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets the slots and draw order to their setup pose values. */
|
||||
public void setSlotsToSetupPose () {
|
||||
Array<Slot> slots = this.slots;
|
||||
System.arraycopy(slots.items, 0, drawOrder.items, 0, slots.size);
|
||||
@ -359,10 +367,12 @@ public class Skeleton {
|
||||
slots.get(i).setToSetupPose();
|
||||
}
|
||||
|
||||
/** The skeleton's setup pose data. */
|
||||
public SkeletonData getData () {
|
||||
return data;
|
||||
}
|
||||
|
||||
/** The skeleton's bones, sorted parent first. The root bone is always the first bone. */
|
||||
public Array<Bone> getBones () {
|
||||
return bones;
|
||||
}
|
||||
@ -371,13 +381,15 @@ public class Skeleton {
|
||||
return updateCache;
|
||||
}
|
||||
|
||||
/** @return May return null. */
|
||||
/** Returns the root bone, or null. */
|
||||
public Bone getRootBone () {
|
||||
if (bones.size == 0) return null;
|
||||
return bones.first();
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** Finds a bone by comparing each bone's name. It is more efficient to cache the results of this method than to call it
|
||||
* multiple times.
|
||||
* @return May be null. */
|
||||
public Bone findBone (String boneName) {
|
||||
if (boneName == null) throw new IllegalArgumentException("boneName cannot be null.");
|
||||
Array<Bone> bones = this.bones;
|
||||
@ -388,11 +400,14 @@ public class Skeleton {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** The skeleton's slots. */
|
||||
public Array<Slot> getSlots () {
|
||||
return slots;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it
|
||||
* multiple times.
|
||||
* @return May be null. */
|
||||
public Slot findSlot (String slotName) {
|
||||
if (slotName == null) throw new IllegalArgumentException("slotName cannot be null.");
|
||||
Array<Slot> slots = this.slots;
|
||||
@ -403,24 +418,25 @@ public class Skeleton {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Returns the slots in the order they will 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 array may be modified to change the draw order. */
|
||||
public Array<Slot> getDrawOrder () {
|
||||
return drawOrder;
|
||||
}
|
||||
|
||||
/** Sets the slots and the order they will be drawn. */
|
||||
public void setDrawOrder (Array<Slot> drawOrder) {
|
||||
if (drawOrder == null) throw new IllegalArgumentException("drawOrder cannot be null.");
|
||||
this.drawOrder = drawOrder;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** The skeleton's current skin.
|
||||
* @return May be null. */
|
||||
public Skin getSkin () {
|
||||
return skin;
|
||||
}
|
||||
|
||||
/** Sets a skin by name.
|
||||
* @see #setSkin(Skin) */
|
||||
* <p>
|
||||
* See {@link #setSkin(Skin)}. */
|
||||
public void setSkin (String skinName) {
|
||||
Skin skin = data.findSkin(skinName);
|
||||
if (skin == null) throw new IllegalArgumentException("Skin not found: " + skinName);
|
||||
@ -428,6 +444,7 @@ public class Skeleton {
|
||||
}
|
||||
|
||||
/** Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default skin}.
|
||||
* <p>
|
||||
* Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was no
|
||||
* old skin, each slot's setup mode attachment is attached from the new skin.
|
||||
* @param newSkin May be null. */
|
||||
@ -450,14 +467,22 @@ public class Skeleton {
|
||||
skin = newSkin;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** Finds an attachment by looking in the {@link #skin} and {@link SkeletonData#defaultSkin} using the slot name and attachment
|
||||
* name.
|
||||
* <p>
|
||||
* See {@link #getAttachment(int, String)}.
|
||||
* @return May be null. */
|
||||
public Attachment getAttachment (String slotName, String attachmentName) {
|
||||
SlotData slot = data.findSlot(slotName);
|
||||
if (slot == null) throw new IllegalArgumentException("Slot not found: " + slotName);
|
||||
return getAttachment(slot.getIndex(), attachmentName);
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** Finds an attachment by looking in the {@link #skin} and {@link SkeletonData#defaultSkin} using the slot index and
|
||||
* attachment name. First the skin is checked and if the attachment was not found, the default skin is checked.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-runtime-skins">Runtime skins</a> in the Spine Runtimes Guide.
|
||||
* @return May be null. */
|
||||
public Attachment getAttachment (int slotIndex, String attachmentName) {
|
||||
if (attachmentName == null) throw new IllegalArgumentException("attachmentName cannot be null.");
|
||||
if (skin != null) {
|
||||
@ -468,8 +493,8 @@ public class Skeleton {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Sets an attachment by finding the slot with {@link #findSlot(String)}, finding the attachment with
|
||||
* {@link #getAttachment(int, String)}, then sets the slot's {@link Slot#attachment}.
|
||||
/** A convenience method to set an attachment by finding the slot with {@link #findSlot(String)}, finding the attachment with
|
||||
* {@link #getAttachment(int, String)}, then setting the slot's {@link Slot#attachment}.
|
||||
* @param attachmentName May be null to clear the slot. */
|
||||
public void setAttachment (String slotName, String attachmentName) {
|
||||
if (slotName == null) throw new IllegalArgumentException("slotName cannot be null.");
|
||||
@ -484,11 +509,14 @@ public class Skeleton {
|
||||
slot.setAttachment(attachment);
|
||||
}
|
||||
|
||||
/** The skeleton's IK constraints. */
|
||||
public Array<IkConstraint> getIkConstraints () {
|
||||
return ikConstraints;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results of this method
|
||||
* than to call it multiple times.
|
||||
* @return May be null. */
|
||||
public IkConstraint findIkConstraint (String constraintName) {
|
||||
if (constraintName == null) throw new IllegalArgumentException("constraintName cannot be null.");
|
||||
Array<IkConstraint> ikConstraints = this.ikConstraints;
|
||||
@ -499,11 +527,14 @@ public class Skeleton {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** The skeleton's transform constraints. */
|
||||
public Array<TransformConstraint> getTransformConstraints () {
|
||||
return transformConstraints;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** Finds a transform constraint by comparing each transform constraint's name. It is more efficient to cache the results of
|
||||
* this method than to call it multiple times.
|
||||
* @return May be null. */
|
||||
public TransformConstraint findTransformConstraint (String constraintName) {
|
||||
if (constraintName == null) throw new IllegalArgumentException("constraintName cannot be null.");
|
||||
Array<TransformConstraint> transformConstraints = this.transformConstraints;
|
||||
@ -514,11 +545,14 @@ public class Skeleton {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** The skeleton's path constraints. */
|
||||
public Array<PathConstraint> getPathConstraints () {
|
||||
return pathConstraints;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method
|
||||
* than to call it multiple times.
|
||||
* @return May be null. */
|
||||
public PathConstraint findPathConstraint (String constraintName) {
|
||||
if (constraintName == null) throw new IllegalArgumentException("constraintName cannot be null.");
|
||||
Array<PathConstraint> pathConstraints = this.pathConstraints;
|
||||
@ -530,8 +564,8 @@ public class Skeleton {
|
||||
}
|
||||
|
||||
/** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose.
|
||||
* @param offset The distance from the skeleton origin to the bottom left corner of the AABB.
|
||||
* @param size The width and height of the AABB. */
|
||||
* @param offset An output value, the distance from the skeleton origin to the bottom left corner of the AABB.
|
||||
* @param size An output value, the width and height of the AABB. */
|
||||
public void getBounds (Vector2 offset, Vector2 size) {
|
||||
if (offset == null) throw new IllegalArgumentException("offset cannot be null.");
|
||||
if (size == null) throw new IllegalArgumentException("size cannot be null.");
|
||||
@ -559,6 +593,7 @@ public class Skeleton {
|
||||
size.set(maxX - minX, maxY - minY);
|
||||
}
|
||||
|
||||
/** The color to tint all the skeleton's attachments. */
|
||||
public Color getColor () {
|
||||
return color;
|
||||
}
|
||||
@ -569,6 +604,8 @@ public class Skeleton {
|
||||
this.color.set(color);
|
||||
}
|
||||
|
||||
/** If true, the entire skeleton is flipped over the Y axis. This affects all bones, even if the bone's transform mode
|
||||
* disallows scale inheritance. */
|
||||
public boolean getFlipX () {
|
||||
return flipX;
|
||||
}
|
||||
@ -577,6 +614,8 @@ public class Skeleton {
|
||||
this.flipX = flipX;
|
||||
}
|
||||
|
||||
/** If true, the entire skeleton is flipped over the X axis. This affects all bones, even if the bone's transform mode
|
||||
* disallows scale inheritance. */
|
||||
public boolean getFlipY () {
|
||||
return flipY;
|
||||
}
|
||||
@ -590,6 +629,7 @@ public class Skeleton {
|
||||
this.flipY = flipY;
|
||||
}
|
||||
|
||||
/** Sets the skeleton X position, which is added to the root bone worldX position. */
|
||||
public float getX () {
|
||||
return x;
|
||||
}
|
||||
@ -598,6 +638,7 @@ public class Skeleton {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
/** Sets the skeleton Y position, which is added to the root bone worldY position. */
|
||||
public float getY () {
|
||||
return y;
|
||||
}
|
||||
@ -611,6 +652,9 @@ public class Skeleton {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/** Returns the skeleton's time. This can be used for tracking, such as with Slot {@link Slot#getAttachmentTime()}.
|
||||
* <p>
|
||||
* See {@link #update(float)}. */
|
||||
public float getTime () {
|
||||
return time;
|
||||
}
|
||||
@ -619,6 +663,7 @@ public class Skeleton {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
/** Increments the skeleton's {@link #time}. */
|
||||
public void update (float delta) {
|
||||
time += delta;
|
||||
}
|
||||
|
||||
@ -72,6 +72,11 @@ import com.esotericsoftware.spine.attachments.PathAttachment;
|
||||
import com.esotericsoftware.spine.attachments.RegionAttachment;
|
||||
import com.esotericsoftware.spine.attachments.VertexAttachment;
|
||||
|
||||
/** Loads skeleton data in the Spine binary format.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-binary-format">Spine binary format</a> and
|
||||
* <a href="http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data">JSON and binary data</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
public class SkeletonBinary {
|
||||
static public final int BONE_ROTATE = 0;
|
||||
static public final int BONE_TRANSLATE = 1;
|
||||
@ -104,11 +109,14 @@ public class SkeletonBinary {
|
||||
this.attachmentLoader = attachmentLoader;
|
||||
}
|
||||
|
||||
/** Scales bone positions, image sizes, and translations as they are loaded. This allows different size images to be used at
|
||||
* runtime than were used in Spine.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-loading-skeleton-data#Scaling">Scaling</a> in the Spine Runtimes Guide. */
|
||||
public float getScale () {
|
||||
return scale;
|
||||
}
|
||||
|
||||
/** Scales the bones, images, and animations as they are loaded. */
|
||||
public void setScale (float scale) {
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
@ -30,13 +30,14 @@
|
||||
|
||||
package com.esotericsoftware.spine;
|
||||
|
||||
import com.esotericsoftware.spine.attachments.Attachment;
|
||||
import com.esotericsoftware.spine.attachments.BoundingBoxAttachment;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.FloatArray;
|
||||
import com.badlogic.gdx.utils.Pool;
|
||||
import com.esotericsoftware.spine.attachments.Attachment;
|
||||
import com.esotericsoftware.spine.attachments.BoundingBoxAttachment;
|
||||
|
||||
/** Collects each {@link BoundingBoxAttachment} that is visible and computes the world vertices for its polygon. The polygon
|
||||
* vertices are provided along with convenience methods for doing hit detection. */
|
||||
public class SkeletonBounds {
|
||||
private float minX, minY, maxX, maxY;
|
||||
private Array<BoundingBoxAttachment> boundingBoxes = new Array();
|
||||
@ -47,6 +48,10 @@ public class SkeletonBounds {
|
||||
}
|
||||
};
|
||||
|
||||
/** Clears any previous polygons, finds all visible bounding box attachments, and computes the world vertices for each bounding
|
||||
* box's polygon.
|
||||
* @param updateAabb If true, the axis aligned bounding box containing all the polygons is computed. If false, the
|
||||
* SkeletonBounds AABB methods will always return true. */
|
||||
public void update (Skeleton skeleton, boolean updateAabb) {
|
||||
if (skeleton == null) throw new IllegalArgumentException("skeleton cannot be null.");
|
||||
Array<BoundingBoxAttachment> boundingBoxes = this.boundingBoxes;
|
||||
@ -194,34 +199,42 @@ public class SkeletonBounds {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** The left edge of the axis aligned bounding box. */
|
||||
public float getMinX () {
|
||||
return minX;
|
||||
}
|
||||
|
||||
/** The bottom edge of the axis aligned bounding box. */
|
||||
public float getMinY () {
|
||||
return minY;
|
||||
}
|
||||
|
||||
/** The right edge of the axis aligned bounding box. */
|
||||
public float getMaxX () {
|
||||
return maxX;
|
||||
}
|
||||
|
||||
/** The top edge of the axis aligned bounding box. */
|
||||
public float getMaxY () {
|
||||
return maxY;
|
||||
}
|
||||
|
||||
/** The width of the axis aligned bounding box. */
|
||||
public float getWidth () {
|
||||
return maxX - minX;
|
||||
}
|
||||
|
||||
/** The height of the axis aligned bounding box. */
|
||||
public float getHeight () {
|
||||
return maxY - minY;
|
||||
}
|
||||
|
||||
/** The visible bounding boxes. */
|
||||
public Array<BoundingBoxAttachment> getBoundingBoxes () {
|
||||
return boundingBoxes;
|
||||
}
|
||||
|
||||
/** The world vertices for the bounding box polygons. */
|
||||
public Array<FloatArray> getPolygons () {
|
||||
return polygons;
|
||||
}
|
||||
|
||||
@ -32,6 +32,10 @@ package com.esotericsoftware.spine;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
|
||||
/** Stores the setup pose and all of the stateless data for a skeleton.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-runtime-architecture#Data-objects">Data objects</a> in the Spine Runtimes
|
||||
* Guide. */
|
||||
public class SkeletonData {
|
||||
String name;
|
||||
final Array<BoneData> bones = new Array(); // Ordered parents first.
|
||||
@ -52,11 +56,14 @@ public class SkeletonData {
|
||||
|
||||
// --- Bones.
|
||||
|
||||
/** The skeleton's bones, sorted parent first. The root bone is always the first bone. */
|
||||
public Array<BoneData> getBones () {
|
||||
return bones;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** Finds a bone by comparing each bone's name. It is more efficient to cache the results of this method than to call it
|
||||
* multiple times.
|
||||
* @return May be null. */
|
||||
public BoneData findBone (String boneName) {
|
||||
if (boneName == null) throw new IllegalArgumentException("boneName cannot be null.");
|
||||
Array<BoneData> bones = this.bones;
|
||||
@ -69,11 +76,14 @@ public class SkeletonData {
|
||||
|
||||
// --- Slots.
|
||||
|
||||
/** The skeleton's slots. */
|
||||
public Array<SlotData> getSlots () {
|
||||
return slots;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it
|
||||
* multiple times.
|
||||
* @return May be null. */
|
||||
public SlotData findSlot (String slotName) {
|
||||
if (slotName == null) throw new IllegalArgumentException("slotName cannot be null.");
|
||||
Array<SlotData> slots = this.slots;
|
||||
@ -86,7 +96,10 @@ public class SkeletonData {
|
||||
|
||||
// --- Skins.
|
||||
|
||||
/** @return May be null. */
|
||||
/** The skeleton's default skin. By default this skin contains all attachments that were not in a skin in Spine.
|
||||
* <p>
|
||||
* See {@link Skeleton#getAttachment(int, String)}.
|
||||
* @return May be null. */
|
||||
public Skin getDefaultSkin () {
|
||||
return defaultSkin;
|
||||
}
|
||||
@ -96,7 +109,9 @@ public class SkeletonData {
|
||||
this.defaultSkin = defaultSkin;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** Finds a skin by comparing each skin's name. It is more efficient to cache the results of this method than to call it
|
||||
* multiple times.
|
||||
* @return May be null. */
|
||||
public Skin findSkin (String skinName) {
|
||||
if (skinName == null) throw new IllegalArgumentException("skinName cannot be null.");
|
||||
for (Skin skin : skins)
|
||||
@ -104,14 +119,16 @@ public class SkeletonData {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Returns all skins, including the default skin. */
|
||||
/** All skins, including the default skin. */
|
||||
public Array<Skin> getSkins () {
|
||||
return skins;
|
||||
}
|
||||
|
||||
// --- Events.
|
||||
|
||||
/** @return May be null. */
|
||||
/** Finds an event by comparing each events's name. It is more efficient to cache the results of this method than to call it
|
||||
* multiple times.
|
||||
* @return May be null. */
|
||||
public EventData findEvent (String eventDataName) {
|
||||
if (eventDataName == null) throw new IllegalArgumentException("eventDataName cannot be null.");
|
||||
for (EventData eventData : events)
|
||||
@ -119,17 +136,21 @@ public class SkeletonData {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** The skeleton's events. */
|
||||
public Array<EventData> getEvents () {
|
||||
return events;
|
||||
}
|
||||
|
||||
// --- Animations.
|
||||
|
||||
/** The skeleton's animations. */
|
||||
public Array<Animation> getAnimations () {
|
||||
return animations;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** Finds an animation by comparing each animation's name. It is more efficient to cache the results of this method than to
|
||||
* call it multiple times.
|
||||
* @return May be null. */
|
||||
public Animation findAnimation (String animationName) {
|
||||
if (animationName == null) throw new IllegalArgumentException("animationName cannot be null.");
|
||||
Array<Animation> animations = this.animations;
|
||||
@ -142,11 +163,14 @@ public class SkeletonData {
|
||||
|
||||
// --- IK constraints
|
||||
|
||||
/** The skeleton's IK constraints. */
|
||||
public Array<IkConstraintData> getIkConstraints () {
|
||||
return ikConstraints;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results of this method
|
||||
* than to call it multiple times.
|
||||
* @return May be null. */
|
||||
public IkConstraintData findIkConstraint (String constraintName) {
|
||||
if (constraintName == null) throw new IllegalArgumentException("constraintName cannot be null.");
|
||||
Array<IkConstraintData> ikConstraints = this.ikConstraints;
|
||||
@ -159,11 +183,14 @@ public class SkeletonData {
|
||||
|
||||
// --- Transform constraints
|
||||
|
||||
/** The skeleton's transform constraints. */
|
||||
public Array<TransformConstraintData> getTransformConstraints () {
|
||||
return transformConstraints;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** Finds a transform constraint by comparing each transform constraint's name. It is more efficient to cache the results of
|
||||
* this method than to call it multiple times.
|
||||
* @return May be null. */
|
||||
public TransformConstraintData findTransformConstraint (String constraintName) {
|
||||
if (constraintName == null) throw new IllegalArgumentException("constraintName cannot be null.");
|
||||
Array<TransformConstraintData> transformConstraints = this.transformConstraints;
|
||||
@ -176,11 +203,14 @@ public class SkeletonData {
|
||||
|
||||
// --- Path constraints
|
||||
|
||||
/** The skeleton's path constraints. */
|
||||
public Array<PathConstraintData> getPathConstraints () {
|
||||
return pathConstraints;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method
|
||||
* than to call it multiple times.
|
||||
* @return May be null. */
|
||||
public PathConstraintData findPathConstraint (String constraintName) {
|
||||
if (constraintName == null) throw new IllegalArgumentException("constraintName cannot be null.");
|
||||
Array<PathConstraintData> pathConstraints = this.pathConstraints;
|
||||
@ -193,7 +223,8 @@ public class SkeletonData {
|
||||
|
||||
// ---
|
||||
|
||||
/** @return May be null. */
|
||||
/** The skeleton's name, which by default is the name of the skeleton data file, if possible.
|
||||
* @return May be null. */
|
||||
public String getName () {
|
||||
return name;
|
||||
}
|
||||
@ -203,6 +234,7 @@ public class SkeletonData {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/** The width of the skeleton's axis aligned bounding box in the setup pose. */
|
||||
public float getWidth () {
|
||||
return width;
|
||||
}
|
||||
@ -211,6 +243,7 @@ public class SkeletonData {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
/** The height of the skeleton's axis aligned bounding box in the setup pose. */
|
||||
public float getHeight () {
|
||||
return height;
|
||||
}
|
||||
@ -219,7 +252,7 @@ public class SkeletonData {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/** Returns the Spine version used to export this data, or null. */
|
||||
/** The Spine version used to export the skeleton data, or null. */
|
||||
public String getVersion () {
|
||||
return version;
|
||||
}
|
||||
@ -229,7 +262,8 @@ public class SkeletonData {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** The skeleton data hash. This value will change if any of the skeleton data has changed.
|
||||
* @return May be null. */
|
||||
public String getHash () {
|
||||
return hash;
|
||||
}
|
||||
@ -239,7 +273,8 @@ public class SkeletonData {
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** The path to the image directory as defined in Spine. Available only when nonessential data was exported.
|
||||
* @return May be null. */
|
||||
public String getImagesPath () {
|
||||
return imagesPath;
|
||||
}
|
||||
@ -249,6 +284,7 @@ public class SkeletonData {
|
||||
this.imagesPath = imagesPath;
|
||||
}
|
||||
|
||||
/** The dopesheet FPS in Spine. Available only when nonessential data was exported. */
|
||||
public float getFps () {
|
||||
return fps;
|
||||
}
|
||||
|
||||
@ -69,6 +69,11 @@ import com.esotericsoftware.spine.attachments.PathAttachment;
|
||||
import com.esotericsoftware.spine.attachments.RegionAttachment;
|
||||
import com.esotericsoftware.spine.attachments.VertexAttachment;
|
||||
|
||||
/** Loads skeleton data in the Spine JSON format.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-json-format">Spine JSON format</a> and
|
||||
* <a href="http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data">JSON and binary data</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
public class SkeletonJson {
|
||||
private final AttachmentLoader attachmentLoader;
|
||||
private float scale = 1;
|
||||
@ -83,11 +88,14 @@ public class SkeletonJson {
|
||||
this.attachmentLoader = attachmentLoader;
|
||||
}
|
||||
|
||||
/** Scales bone positions, image sizes, and translations as they are loaded. This allows different size images to be used at
|
||||
* runtime than were used in Spine.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-loading-skeleton-data#Scaling">Scaling</a> in the Spine Runtimes Guide. */
|
||||
public float getScale () {
|
||||
return scale;
|
||||
}
|
||||
|
||||
/** Scales the bones, images, and animations as they are loaded. */
|
||||
public void setScale (float scale) {
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
@ -36,7 +36,10 @@ import com.badlogic.gdx.utils.ObjectMap.Entry;
|
||||
import com.badlogic.gdx.utils.Pool;
|
||||
import com.esotericsoftware.spine.attachments.Attachment;
|
||||
|
||||
/** Stores attachments by slot index and attachment name. */
|
||||
/** Stores attachments by slot index and attachment name.
|
||||
* <p>
|
||||
* See SkeletonData {@link SkeletonData#defaultSkin}, Skeleton {@link Skeleton#skin}, and
|
||||
* <a href="http://esotericsoftware.com/spine-runtime-skins">Runtime skins</a> in the Spine Runtimes Guide. */
|
||||
public class Skin {
|
||||
static private final Key lookup = new Key();
|
||||
|
||||
@ -53,6 +56,7 @@ public class Skin {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/** Adds an attachment to the skin for the specified slot index and name. */
|
||||
public void addAttachment (int slotIndex, String name, Attachment attachment) {
|
||||
if (attachment == null) throw new IllegalArgumentException("attachment cannot be null.");
|
||||
if (slotIndex < 0) throw new IllegalArgumentException("slotIndex must be >= 0.");
|
||||
@ -61,7 +65,7 @@ public class Skin {
|
||||
attachments.put(key, attachment);
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** Returns the attachment for the specified slot index and name, or null. */
|
||||
public Attachment getAttachment (int slotIndex, String name) {
|
||||
if (slotIndex < 0) throw new IllegalArgumentException("slotIndex must be >= 0.");
|
||||
lookup.set(slotIndex, name);
|
||||
@ -88,6 +92,7 @@ public class Skin {
|
||||
attachments.clear();
|
||||
}
|
||||
|
||||
/** The skin's name, which is unique within the skeleton. */
|
||||
public String getName () {
|
||||
return name;
|
||||
}
|
||||
|
||||
@ -32,8 +32,13 @@ package com.esotericsoftware.spine;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.utils.FloatArray;
|
||||
import com.esotericsoftware.spine.Animation.DeformTimeline;
|
||||
import com.esotericsoftware.spine.attachments.Attachment;
|
||||
import com.esotericsoftware.spine.attachments.VertexAttachment;
|
||||
|
||||
/** Stores a slot's current pose. Slots organize attachments for {@link Skeleton#drawOrder} purposes and provide a place to store
|
||||
* state for an attachment. State cannot be stored in an attachment itself because attachments are stateless and may be shared
|
||||
* across multiple skeletons. */
|
||||
public class Slot {
|
||||
final SlotData data;
|
||||
final Bone bone;
|
||||
@ -62,28 +67,33 @@ public class Slot {
|
||||
attachmentTime = slot.attachmentTime;
|
||||
}
|
||||
|
||||
/** The slot's setup pose data. */
|
||||
public SlotData getData () {
|
||||
return data;
|
||||
}
|
||||
|
||||
/** The bone this slot belongs to. */
|
||||
public Bone getBone () {
|
||||
return bone;
|
||||
}
|
||||
|
||||
/** The skeleton this slot belongs to. */
|
||||
public Skeleton getSkeleton () {
|
||||
return bone.skeleton;
|
||||
}
|
||||
|
||||
/** The color used to tint the slot's attachment. */
|
||||
public Color getColor () {
|
||||
return color;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** The current attachment for the slot, or null if the slot has no attachment. */
|
||||
public Attachment getAttachment () {
|
||||
return attachment;
|
||||
}
|
||||
|
||||
/** Sets the attachment and if it changed, resets {@link #getAttachmentTime()} and clears {@link #getAttachmentVertices()}.
|
||||
/** Sets the slot's attachment and, if the attachment changed, resets {@link #attachmentTime} and clears
|
||||
* {@link #attachmentVertices}.
|
||||
* @param attachment May be null. */
|
||||
public void setAttachment (Attachment attachment) {
|
||||
if (this.attachment == attachment) return;
|
||||
@ -92,13 +102,21 @@ public class Slot {
|
||||
attachmentVertices.clear();
|
||||
}
|
||||
|
||||
/** The time that has elapsed since the last time the attachment was set or cleared. Relies on Skeleton
|
||||
* {@link Skeleton#time}. */
|
||||
public float getAttachmentTime () {
|
||||
return bone.skeleton.time - attachmentTime;
|
||||
}
|
||||
|
||||
public void setAttachmentTime (float time) {
|
||||
attachmentTime = bone.skeleton.time - time;
|
||||
}
|
||||
|
||||
/** Returns the time since the attachment was set. */
|
||||
public float getAttachmentTime () {
|
||||
return bone.skeleton.time - attachmentTime;
|
||||
/** Vertices to deform the slot's attachment.
|
||||
* <p>
|
||||
* See {@link VertexAttachment#computeWorldVertices(Slot, int, int, float[], int)} and {@link DeformTimeline}. */
|
||||
public FloatArray getAttachmentVertices () {
|
||||
return attachmentVertices;
|
||||
}
|
||||
|
||||
public void setAttachmentVertices (FloatArray attachmentVertices) {
|
||||
@ -106,10 +124,7 @@ public class Slot {
|
||||
this.attachmentVertices = attachmentVertices;
|
||||
}
|
||||
|
||||
public FloatArray getAttachmentVertices () {
|
||||
return attachmentVertices;
|
||||
}
|
||||
|
||||
/** Sets this slot to the setup pose. */
|
||||
public void setToSetupPose () {
|
||||
color.set(data.color);
|
||||
if (data.attachmentName == null)
|
||||
|
||||
@ -32,6 +32,7 @@ package com.esotericsoftware.spine;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
|
||||
/** Stores the setup pose for a {@link Slot}. */
|
||||
public class SlotData {
|
||||
final int index;
|
||||
final String name;
|
||||
@ -49,18 +50,22 @@ public class SlotData {
|
||||
this.boneData = boneData;
|
||||
}
|
||||
|
||||
/** The index of the slot in {@link Skeleton#getSlots()}. */
|
||||
public int getIndex () {
|
||||
return index;
|
||||
}
|
||||
|
||||
/** The name of the slot, which is unique within the skeleton. */
|
||||
public String getName () {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** The bone this slot belongs to. */
|
||||
public BoneData getBoneData () {
|
||||
return boneData;
|
||||
}
|
||||
|
||||
/** The color used to tint the slot's attachment. */
|
||||
public Color getColor () {
|
||||
return color;
|
||||
}
|
||||
@ -70,11 +75,12 @@ public class SlotData {
|
||||
this.attachmentName = attachmentName;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** The name of the attachment that is visible for this slot in the setup pose, or null if no attachment is visible. */
|
||||
public String getAttachmentName () {
|
||||
return attachmentName;
|
||||
}
|
||||
|
||||
/** The blend mode for drawing the slot's attachment. */
|
||||
public BlendMode getBlendMode () {
|
||||
return blendMode;
|
||||
}
|
||||
|
||||
@ -35,6 +35,10 @@ import static com.badlogic.gdx.math.MathUtils.*;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
|
||||
/** 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.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-transform-constraints">Transform constraints</a> in the Spine User Guide. */
|
||||
public class TransformConstraint implements Constraint {
|
||||
final TransformConstraintData data;
|
||||
final Array<Bone> bones;
|
||||
@ -71,6 +75,7 @@ public class TransformConstraint implements Constraint {
|
||||
shearMix = constraint.shearMix;
|
||||
}
|
||||
|
||||
/** Applies the constraint to the constrained bones. */
|
||||
public void apply () {
|
||||
update();
|
||||
}
|
||||
@ -143,10 +148,12 @@ public class TransformConstraint implements Constraint {
|
||||
return data.order;
|
||||
}
|
||||
|
||||
/** The bones that will be modified by this transform constraint. */
|
||||
public Array<Bone> getBones () {
|
||||
return bones;
|
||||
}
|
||||
|
||||
/** The target bone whose world transform will be copied to the constrained bones. */
|
||||
public Bone getTarget () {
|
||||
return target;
|
||||
}
|
||||
@ -155,6 +162,7 @@ public class TransformConstraint implements Constraint {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */
|
||||
public float getRotateMix () {
|
||||
return rotateMix;
|
||||
}
|
||||
@ -163,6 +171,7 @@ public class TransformConstraint implements Constraint {
|
||||
this.rotateMix = rotateMix;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translations. */
|
||||
public float getTranslateMix () {
|
||||
return translateMix;
|
||||
}
|
||||
@ -171,6 +180,7 @@ public class TransformConstraint implements Constraint {
|
||||
this.translateMix = translateMix;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained scales. */
|
||||
public float getScaleMix () {
|
||||
return scaleMix;
|
||||
}
|
||||
@ -179,6 +189,7 @@ public class TransformConstraint implements Constraint {
|
||||
this.scaleMix = scaleMix;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained scales. */
|
||||
public float getShearMix () {
|
||||
return shearMix;
|
||||
}
|
||||
@ -187,6 +198,7 @@ public class TransformConstraint implements Constraint {
|
||||
this.shearMix = shearMix;
|
||||
}
|
||||
|
||||
/** The transform constraint's setup pose data. */
|
||||
public TransformConstraintData getData () {
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -32,6 +32,9 @@ package com.esotericsoftware.spine;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
|
||||
/** Stores the setup pose for a {@link TransformConstraint}.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-transform-constraints">Transform constraints</a> in the Spine User Guide. */
|
||||
public class TransformConstraintData {
|
||||
final String name;
|
||||
int order;
|
||||
@ -45,10 +48,12 @@ public class TransformConstraintData {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/** The transform constraint's name, which is unique within the skeleton. */
|
||||
public String getName () {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** See {@link Constraint#getOrder()}. */
|
||||
public int getOrder () {
|
||||
return order;
|
||||
}
|
||||
@ -57,10 +62,12 @@ public class TransformConstraintData {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
/** The bones that will be modified by this transform constraint. */
|
||||
public Array<BoneData> getBones () {
|
||||
return bones;
|
||||
}
|
||||
|
||||
/** The target bone whose world transform will be copied to the constrained bones. */
|
||||
public BoneData getTarget () {
|
||||
return target;
|
||||
}
|
||||
@ -70,6 +77,7 @@ public class TransformConstraintData {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotations. */
|
||||
public float getRotateMix () {
|
||||
return rotateMix;
|
||||
}
|
||||
@ -78,6 +86,7 @@ public class TransformConstraintData {
|
||||
this.rotateMix = rotateMix;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translations. */
|
||||
public float getTranslateMix () {
|
||||
return translateMix;
|
||||
}
|
||||
@ -86,6 +95,7 @@ public class TransformConstraintData {
|
||||
this.translateMix = translateMix;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained scales. */
|
||||
public float getScaleMix () {
|
||||
return scaleMix;
|
||||
}
|
||||
@ -94,6 +104,7 @@ public class TransformConstraintData {
|
||||
this.scaleMix = scaleMix;
|
||||
}
|
||||
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained shears. */
|
||||
public float getShearMix () {
|
||||
return shearMix;
|
||||
}
|
||||
@ -102,6 +113,7 @@ public class TransformConstraintData {
|
||||
this.shearMix = shearMix;
|
||||
}
|
||||
|
||||
/** An offset added to the constrained bone rotation. */
|
||||
public float getOffsetRotation () {
|
||||
return offsetRotation;
|
||||
}
|
||||
@ -110,6 +122,7 @@ public class TransformConstraintData {
|
||||
this.offsetRotation = offsetRotation;
|
||||
}
|
||||
|
||||
/** An offset added to the constrained bone X translation. */
|
||||
public float getOffsetX () {
|
||||
return offsetX;
|
||||
}
|
||||
@ -118,6 +131,7 @@ public class TransformConstraintData {
|
||||
this.offsetX = offsetX;
|
||||
}
|
||||
|
||||
/** An offset added to the constrained bone Y translation. */
|
||||
public float getOffsetY () {
|
||||
return offsetY;
|
||||
}
|
||||
@ -126,6 +140,7 @@ public class TransformConstraintData {
|
||||
this.offsetY = offsetY;
|
||||
}
|
||||
|
||||
/** An offset added to the constrained bone scaleX. */
|
||||
public float getOffsetScaleX () {
|
||||
return offsetScaleX;
|
||||
}
|
||||
@ -134,6 +149,7 @@ public class TransformConstraintData {
|
||||
this.offsetScaleX = offsetScaleX;
|
||||
}
|
||||
|
||||
/** An offset added to the constrained bone scaleY. */
|
||||
public float getOffsetScaleY () {
|
||||
return offsetScaleY;
|
||||
}
|
||||
@ -142,6 +158,7 @@ public class TransformConstraintData {
|
||||
this.offsetScaleY = offsetScaleY;
|
||||
}
|
||||
|
||||
/** An offset added to the constrained bone shearY. */
|
||||
public float getOffsetShearY () {
|
||||
return offsetShearY;
|
||||
}
|
||||
|
||||
@ -35,6 +35,11 @@ import com.esotericsoftware.spine.Skin;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
|
||||
|
||||
/** An {@link AttachmentLoader} that configures attachments using texture regions from an {@link Atlas}.
|
||||
* <p>
|
||||
* See <a href='http://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;
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
|
||||
package com.esotericsoftware.spine.attachments;
|
||||
|
||||
/** The base class for all attachments. */
|
||||
abstract public class Attachment {
|
||||
String name;
|
||||
|
||||
@ -38,6 +39,7 @@ abstract public class Attachment {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/** The attachment's name. */
|
||||
public String getName () {
|
||||
return name;
|
||||
}
|
||||
|
||||
@ -32,16 +32,20 @@ package com.esotericsoftware.spine.attachments;
|
||||
|
||||
import com.esotericsoftware.spine.Skin;
|
||||
|
||||
/** The interface which can be implemented to customize creating and populating attachments.
|
||||
* <p>
|
||||
* See <a href='http://esotericsoftware.com/spine-loading-skeleton-data#AttachmentLoader'>Loading skeleton data</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
public interface AttachmentLoader {
|
||||
/** @return May be null to not load any attachment. */
|
||||
/** @return May be null to not load the attachment. */
|
||||
public RegionAttachment newRegionAttachment (Skin skin, String name, String path);
|
||||
|
||||
/** @return May be null to not load any attachment. */
|
||||
/** @return May be null to not load the attachment. */
|
||||
public MeshAttachment newMeshAttachment (Skin skin, String name, String path);
|
||||
|
||||
/** @return May be null to not load any attachment. */
|
||||
/** @return May be null to not load the attachment. */
|
||||
public BoundingBoxAttachment newBoundingBoxAttachment (Skin skin, String name);
|
||||
|
||||
/** @return May be null to not load any attachment. */
|
||||
/** @return May be null to not load the attachment. */
|
||||
public PathAttachment newPathAttachment (Skin skin, String name);
|
||||
}
|
||||
|
||||
@ -31,8 +31,13 @@
|
||||
package com.esotericsoftware.spine.attachments;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.esotericsoftware.spine.Slot;
|
||||
import com.esotericsoftware.spine.SkeletonBounds;
|
||||
|
||||
/** An attachment with vertices that make up a polygon. Can be used for hit detection, creating physics bodies, spawning particle
|
||||
* effects, and more.
|
||||
* <p>
|
||||
* See {@link SkeletonBounds} and <a href="http://esotericsoftware.com/spine-bounding-boxes">Bounding Boxes</a> in the Spine User
|
||||
* Guide. */
|
||||
public class BoundingBoxAttachment extends VertexAttachment {
|
||||
// Nonessential.
|
||||
final Color color = new Color(0.38f, 0.94f, 0, 1);
|
||||
|
||||
@ -35,11 +35,15 @@ import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.utils.FloatArray;
|
||||
import com.badlogic.gdx.utils.NumberUtils;
|
||||
import com.esotericsoftware.spine.Animation.DeformTimeline;
|
||||
import com.esotericsoftware.spine.Bone;
|
||||
import com.esotericsoftware.spine.Skeleton;
|
||||
import com.esotericsoftware.spine.Slot;
|
||||
|
||||
/** Attachment that displays a texture region. */
|
||||
/** 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.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-meshes">Mesh attachments</a> in the Spine User Guide. */
|
||||
public class MeshAttachment extends VertexAttachment {
|
||||
private TextureRegion region;
|
||||
private String path;
|
||||
@ -68,6 +72,8 @@ public class MeshAttachment extends VertexAttachment {
|
||||
return region;
|
||||
}
|
||||
|
||||
/** Calculates {@link #worldVertices} UVs using {@link #regionUVs} and the {@link #region}. Must be called after changing the
|
||||
* region UVs or region. */
|
||||
public void updateUVs () {
|
||||
float[] regionUVs = this.regionUVs;
|
||||
int verticesLength = regionUVs.length;
|
||||
@ -160,6 +166,8 @@ public class MeshAttachment extends VertexAttachment {
|
||||
return worldVertices;
|
||||
}
|
||||
|
||||
/** Returns true if the <code>sourceAttachment</code> is this mesh, else returns true if {@link #inheritDeform} is true and the
|
||||
* the <code>sourceAttachment</code> is the {@link #parentMesh}. */
|
||||
public boolean applyDeform (VertexAttachment sourceAttachment) {
|
||||
return this == sourceAttachment || (inheritDeform && parentMesh == sourceAttachment);
|
||||
}
|
||||
@ -168,11 +176,11 @@ public class MeshAttachment extends VertexAttachment {
|
||||
return worldVertices;
|
||||
}
|
||||
|
||||
/** Triplets of vertex indices which describe the mesh's triangulation. */
|
||||
public short[] getTriangles () {
|
||||
return triangles;
|
||||
}
|
||||
|
||||
/** Vertex number triplets which describe the mesh's triangulation. */
|
||||
public void setTriangles (short[] triangles) {
|
||||
this.triangles = triangles;
|
||||
}
|
||||
@ -186,10 +194,12 @@ public class MeshAttachment extends VertexAttachment {
|
||||
this.regionUVs = regionUVs;
|
||||
}
|
||||
|
||||
/** The color to tint the mesh. */
|
||||
public Color getColor () {
|
||||
return color;
|
||||
}
|
||||
|
||||
/** The name of the texture region for this attachment. */
|
||||
public String getPath () {
|
||||
return path;
|
||||
}
|
||||
@ -198,6 +208,7 @@ public class MeshAttachment extends VertexAttachment {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
/** The number of entries at the beginning of {@link #vertices} that make up the mesh hull. */
|
||||
public int getHullLength () {
|
||||
return hullLength;
|
||||
}
|
||||
@ -210,10 +221,13 @@ public class MeshAttachment extends VertexAttachment {
|
||||
this.edges = edges;
|
||||
}
|
||||
|
||||
/** Vertex index pairs describing edges for controling triangulation. Mesh triangles will never cross edges. Only available if
|
||||
* nonessential data was exported. Triangulation is not performed at runtime. */
|
||||
public short[] getEdges () {
|
||||
return edges;
|
||||
}
|
||||
|
||||
/** The width of the mesh's image. Available only when nonessential data was exported. */
|
||||
public float getWidth () {
|
||||
return width;
|
||||
}
|
||||
@ -222,6 +236,7 @@ public class MeshAttachment extends VertexAttachment {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
/** The height of the mesh's image. Available only when nonessential data was exported. */
|
||||
public float getHeight () {
|
||||
return height;
|
||||
}
|
||||
@ -230,7 +245,9 @@ public class MeshAttachment extends VertexAttachment {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/** Returns the source mesh if this is a linked mesh, else returns null. */
|
||||
/** 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). */
|
||||
public MeshAttachment getParentMesh () {
|
||||
return parentMesh;
|
||||
}
|
||||
@ -250,6 +267,10 @@ public class MeshAttachment extends VertexAttachment {
|
||||
}
|
||||
}
|
||||
|
||||
/** When this is a linked mesh (see {@link #parentMesh}), if true, any {@link DeformTimeline} for the {@link #parentMesh} is
|
||||
* also applied to this mesh. If false, this linked mesh may have its own deform timelines.
|
||||
* <p>
|
||||
* See {@link #applyDeform(VertexAttachment)}. */
|
||||
public boolean getInheritDeform () {
|
||||
return inheritDeform;
|
||||
}
|
||||
|
||||
@ -31,8 +31,11 @@
|
||||
package com.esotericsoftware.spine.attachments;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.esotericsoftware.spine.Slot;
|
||||
import com.esotericsoftware.spine.PathConstraint;
|
||||
|
||||
/** An attachment whose vertices make up a composite Bezier curve.
|
||||
* <p>
|
||||
* See {@link PathConstraint} and <a href="http://esotericsoftware.com/spine-paths">Paths</a> in the Spine User Guide. */
|
||||
public class PathAttachment extends VertexAttachment {
|
||||
float[] lengths;
|
||||
boolean closed, constantSpeed;
|
||||
@ -53,6 +56,8 @@ public class PathAttachment extends VertexAttachment {
|
||||
this.closed = closed;
|
||||
}
|
||||
|
||||
/** If true, additional calculations are performed to make calculating positions along the path more accurate. If false, fewer
|
||||
* calculations are performed but calculating positions along the path is less accurate. */
|
||||
public boolean getConstantSpeed () {
|
||||
return constantSpeed;
|
||||
}
|
||||
@ -61,7 +66,7 @@ public class PathAttachment extends VertexAttachment {
|
||||
this.constantSpeed = constantSpeed;
|
||||
}
|
||||
|
||||
/** Returns the length in the setup pose from the start of the path to the end of each curve. */
|
||||
/** The lengths along the path in the setup pose from the start of the path to the end of each Bezier curve. */
|
||||
public float[] getLengths () {
|
||||
return lengths;
|
||||
}
|
||||
@ -70,6 +75,8 @@ public class PathAttachment extends VertexAttachment {
|
||||
this.lengths = lengths;
|
||||
}
|
||||
|
||||
/** The color of the path as it was in Spine. Available only when nonessential data was exported. Paths are not usually
|
||||
* rendered at runtime. */
|
||||
public Color getColor () {
|
||||
return color;
|
||||
}
|
||||
|
||||
@ -30,10 +30,6 @@
|
||||
|
||||
package com.esotericsoftware.spine.attachments;
|
||||
|
||||
import com.esotericsoftware.spine.Bone;
|
||||
import com.esotericsoftware.spine.Skeleton;
|
||||
import com.esotericsoftware.spine.Slot;
|
||||
|
||||
import static com.badlogic.gdx.graphics.g2d.Batch.*;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
@ -41,8 +37,13 @@ import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
|
||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||
import com.badlogic.gdx.math.MathUtils;
|
||||
import com.badlogic.gdx.utils.NumberUtils;
|
||||
import com.esotericsoftware.spine.Bone;
|
||||
import com.esotericsoftware.spine.Skeleton;
|
||||
import com.esotericsoftware.spine.Slot;
|
||||
|
||||
/** Attachment that displays a texture region. */
|
||||
/** An attachment that displays a textured quadrilateral.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-regions">Region attachments</a> in the Spine User Guide. */
|
||||
public class RegionAttachment extends Attachment {
|
||||
static public final int BLX = 0;
|
||||
static public final int BLY = 1;
|
||||
@ -64,6 +65,7 @@ public class RegionAttachment extends Attachment {
|
||||
super(name);
|
||||
}
|
||||
|
||||
/** Calculates the {@link #offset} using the region settings. Must be called after changing region settings. */
|
||||
public void updateOffset () {
|
||||
float width = getWidth();
|
||||
float height = getHeight();
|
||||
@ -196,10 +198,14 @@ public class RegionAttachment extends Attachment {
|
||||
return vertices;
|
||||
}
|
||||
|
||||
/** For each of the 4 vertices, a pair of <code>x,y</code> values that is the local position of the vertex.
|
||||
* <p>
|
||||
* See {@link #updateOffset()}. */
|
||||
public float[] getOffset () {
|
||||
return offset;
|
||||
}
|
||||
|
||||
/** The local x translation. */
|
||||
public float getX () {
|
||||
return x;
|
||||
}
|
||||
@ -208,6 +214,7 @@ public class RegionAttachment extends Attachment {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
/** The local y translation. */
|
||||
public float getY () {
|
||||
return y;
|
||||
}
|
||||
@ -216,6 +223,7 @@ public class RegionAttachment extends Attachment {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/** The local scaleX. */
|
||||
public float getScaleX () {
|
||||
return scaleX;
|
||||
}
|
||||
@ -224,6 +232,7 @@ public class RegionAttachment extends Attachment {
|
||||
this.scaleX = scaleX;
|
||||
}
|
||||
|
||||
/** The local scaleY. */
|
||||
public float getScaleY () {
|
||||
return scaleY;
|
||||
}
|
||||
@ -232,6 +241,7 @@ public class RegionAttachment extends Attachment {
|
||||
this.scaleY = scaleY;
|
||||
}
|
||||
|
||||
/** The local rotation. */
|
||||
public float getRotation () {
|
||||
return rotation;
|
||||
}
|
||||
@ -240,6 +250,7 @@ public class RegionAttachment extends Attachment {
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
/** The width of the region attachment in Spine. */
|
||||
public float getWidth () {
|
||||
return width;
|
||||
}
|
||||
@ -248,6 +259,7 @@ public class RegionAttachment extends Attachment {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
/** The height of the region attachment in Spine. */
|
||||
public float getHeight () {
|
||||
return height;
|
||||
}
|
||||
@ -256,10 +268,12 @@ public class RegionAttachment extends Attachment {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/** The color to tint the region attachment. */
|
||||
public Color getColor () {
|
||||
return color;
|
||||
}
|
||||
|
||||
/** The name of the texture region for this attachment. */
|
||||
public String getPath () {
|
||||
return path;
|
||||
}
|
||||
|
||||
@ -35,7 +35,8 @@ import com.esotericsoftware.spine.Bone;
|
||||
import com.esotericsoftware.spine.Skeleton;
|
||||
import com.esotericsoftware.spine.Slot;
|
||||
|
||||
/** An attachment with vertices that are transformed by one or more bones and can be deformed by a slot's vertices. */
|
||||
/** Base class for an attachment with vertices that are transformed by one or more bones and can be deformed by a slot's
|
||||
* {@link Slot#getAttachmentVertices()}. */
|
||||
public class VertexAttachment extends Attachment {
|
||||
int[] bones;
|
||||
float[] vertices;
|
||||
@ -45,11 +46,18 @@ public class VertexAttachment extends Attachment {
|
||||
super(name);
|
||||
}
|
||||
|
||||
protected void computeWorldVertices (Slot slot, float[] worldVertices) {
|
||||
/** Transforms local {@link #getVertices()} to world coordinates, using 0 for <code>start</code> and <code>offset</code>.
|
||||
* <p>
|
||||
* See {@link #computeWorldVertices(Slot, int, int, float[], int)}. */
|
||||
public void computeWorldVertices (Slot slot, float[] worldVertices) {
|
||||
computeWorldVertices(slot, 0, worldVerticesLength, worldVertices, 0);
|
||||
}
|
||||
|
||||
/** Transforms local vertices to world coordinates.
|
||||
/** Transforms local {@link #getVertices()} to world coordinates. If the slot has {@link Slot#getAttachmentVertices()}, they
|
||||
* are used to deform the vertices.
|
||||
* <p>
|
||||
* See <a href="http://esotericsoftware.com/spine-skeleton-manipulation#World-transforms">World transforms</a> in the Spine
|
||||
* Runtimes Guide.
|
||||
* @param start The index of the first {@link #getVertices()} value to transform. Each vertex has 2 values, x and y.
|
||||
* @param count The number of world vertex values to output. Must be <= {@link #getWorldVerticesLength()} - <code>start</code>.
|
||||
* @param worldVertices The output world vertices. Must have a length >= <code>offset</code> + <code>count</code>.
|
||||
@ -111,32 +119,37 @@ public class VertexAttachment extends Attachment {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns true if a deform originally applied to the specified attachment should be applied to this attachment. */
|
||||
/** Returns true if a deform originally applied to the specified attachment should be applied to this attachment. The default
|
||||
* implementation returns true only when <code>sourceAttachment</code> is this attachment. */
|
||||
public boolean applyDeform (VertexAttachment sourceAttachment) {
|
||||
return this == sourceAttachment;
|
||||
}
|
||||
|
||||
/** @return May be null if this attachment has no weights. */
|
||||
/** 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()}. May be null if
|
||||
* this attachment has no weights. */
|
||||
public int[] getBones () {
|
||||
return bones;
|
||||
}
|
||||
|
||||
/** For each vertex, the number of bones affecting the vertex followed by that many bone indices. Ie: count, boneIndex, ...
|
||||
* @param bones May be null if this attachment has no weights. */
|
||||
/** @param bones May be null if this attachment has no weights. */
|
||||
public void setBones (int[] bones) {
|
||||
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. */
|
||||
public float[] getVertices () {
|
||||
return vertices;
|
||||
}
|
||||
|
||||
/** Sets the vertex position in the bone's coordinate system. For a non-weighted attachment, the values are x,y entries for
|
||||
* each vertex. For a weighted attachment, the values are x,y,weight entries for each bone affecting each vertex. */
|
||||
public void setVertices (float[] vertices) {
|
||||
this.vertices = vertices;
|
||||
}
|
||||
|
||||
/** The maximum length required of the <code>worldVertices</code> passed to
|
||||
* {@link #computeWorldVertices(Slot, int, int, float[], int)}. */
|
||||
public int getWorldVerticesLength () {
|
||||
return worldVerticesLength;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user