mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 14:24:53 +08:00
[Haxe] Synchronize documentation with reference implementation
This commit is contained in:
parent
f5da0c6f8f
commit
b413153b59
@ -32,6 +32,9 @@ package spine;
|
||||
import haxe.io.FPHelper;
|
||||
import haxe.io.Bytes;
|
||||
|
||||
/**
|
||||
* Input for reading skeleton data.
|
||||
*/
|
||||
class BinaryInput {
|
||||
private var bytes:Bytes;
|
||||
private var index:Int = 0;
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** Determines how images are blended with existing pixels when drawn. */
|
||||
class BlendMode {
|
||||
public static var normal(default, never):BlendMode = new BlendMode(0, "normal");
|
||||
public static var additive(default, never):BlendMode = new BlendMode(1, "additive");
|
||||
|
||||
@ -29,6 +29,11 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** Stores a bone's current pose.
|
||||
* <p>
|
||||
* A bone has a local transform which is used to compute its world transform. A bone also has an applied transform, which is a
|
||||
* local transform that can be applied to compute the world transform. The local transform and applied transform may differ if a
|
||||
* constraint or application code modifies the world transform after it was computed from the local transform. */
|
||||
class Bone implements Updatable {
|
||||
static public var yDown:Bool = false;
|
||||
|
||||
@ -37,48 +42,73 @@ class Bone implements Updatable {
|
||||
private var _parent:Bone;
|
||||
private var _children:Array<Bone> = new Array<Bone>();
|
||||
|
||||
/** The local x translation. */
|
||||
public var x:Float = 0;
|
||||
/** The local y translation. */
|
||||
public var y:Float = 0;
|
||||
/** The local rotation in degrees, counter clockwise. */
|
||||
public var rotation:Float = 0;
|
||||
/** The local scaleX. */
|
||||
public var scaleX:Float = 0;
|
||||
/** The local scaleY. */
|
||||
public var scaleY:Float = 0;
|
||||
/** The local shearX. */
|
||||
public var shearX:Float = 0;
|
||||
/** The local shearY. */
|
||||
public var shearY:Float = 0;
|
||||
/** The applied local x translation. */
|
||||
public var ax:Float = 0;
|
||||
/** The applied local y translation. */
|
||||
public var ay:Float = 0;
|
||||
/** The applied local rotation in degrees, counter clockwise. */
|
||||
public var arotation:Float = 0;
|
||||
/** The applied local scaleX. */
|
||||
public var ascaleX:Float = 0;
|
||||
/** The applied local scaleY. */
|
||||
public var ascaleY:Float = 0;
|
||||
/** The applied local shearX. */
|
||||
public var ashearX:Float = 0;
|
||||
/** The applied local shearY. */
|
||||
public var ashearY:Float = 0;
|
||||
/** Part of the world transform matrix for the X axis. If changed, {@link #updateAppliedTransform()} should be called. */
|
||||
public var a:Float = 0;
|
||||
/** Part of the world transform matrix for the Y axis. If changed, {@link #updateAppliedTransform()} should be called. */
|
||||
public var b:Float = 0;
|
||||
/** Part of the world transform matrix for the X axis. If changed, {@link #updateAppliedTransform()} should be called. */
|
||||
public var c:Float = 0;
|
||||
/** Part of the world transform matrix for the Y axis. If changed, {@link #updateAppliedTransform()} should be called. */
|
||||
public var d:Float = 0;
|
||||
/** The world X position. If changed, {@link #updateAppliedTransform()} should be called. */
|
||||
public var worldX:Float = 0;
|
||||
/** The world Y position. If changed, {@link #updateAppliedTransform()} should be called. */
|
||||
public var worldY:Float = 0;
|
||||
/** Determines how parent world transforms affect this bone. */
|
||||
public var inherit:Inherit = Inherit.normal;
|
||||
public var sorted:Bool = false;
|
||||
public var active:Bool = false;
|
||||
|
||||
/** The bone's setup pose data. */
|
||||
public var data(get, never):BoneData;
|
||||
|
||||
private function get_data():BoneData {
|
||||
return _data;
|
||||
}
|
||||
|
||||
/** The skeleton this bone belongs to. */
|
||||
public var skeleton(get, never):Skeleton;
|
||||
|
||||
private function get_skeleton():Skeleton {
|
||||
return _skeleton;
|
||||
}
|
||||
|
||||
/** The parent bone, or null if this is the root bone. */
|
||||
public var parent(get, never):Bone;
|
||||
|
||||
private function get_parent():Bone {
|
||||
return _parent;
|
||||
}
|
||||
|
||||
/** The immediate children of this bone. */
|
||||
public var children(get, never):Array<Bone>;
|
||||
|
||||
private function get_children():Array<Bone> {
|
||||
@ -101,17 +131,23 @@ class Bone implements Updatable {
|
||||
return active;
|
||||
}
|
||||
|
||||
/** Same as updateWorldTransform(). This method exists for Bone to implement Updatable. */
|
||||
/** Computes the world transform using the parent bone and this bone's local applied transform. */
|
||||
public function update(physics:Physics):Void {
|
||||
updateWorldTransformWith(ax, ay, arotation, ascaleX, ascaleY, ashearX, ashearY);
|
||||
}
|
||||
|
||||
/** Computes the world SRT using the parent bone and this bone's local SRT. */
|
||||
/** Computes the world transform using the parent bone and this bone's local transform.
|
||||
* <p>
|
||||
* See {@link #updateWorldTransformWith(float, float, float, float, float, float, float)}. */
|
||||
public function updateWorldTransform():Void {
|
||||
updateWorldTransformWith(x, y, rotation, scaleX, scaleY, shearX, shearY);
|
||||
}
|
||||
|
||||
/** Computes the world SRT using the parent bone and the specified local SRT. */
|
||||
/** Computes the world transform using the parent bone and the specified local transform. The applied transform is set to the
|
||||
* specified local transform. Child bones are not updated.
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
public function updateWorldTransformWith(x:Float, y:Float, rotation:Float, scaleX:Float, scaleY:Float, shearX:Float, shearY:Float):Void {
|
||||
ax = x;
|
||||
ay = y;
|
||||
@ -234,6 +270,7 @@ class Bone implements Updatable {
|
||||
d *= sy;
|
||||
}
|
||||
|
||||
/** Sets this bone's local transform to the setup pose. */
|
||||
public function setToSetupPose():Void {
|
||||
x = data.x;
|
||||
y = data.y;
|
||||
@ -245,10 +282,14 @@ class Bone implements Updatable {
|
||||
inherit = data.inherit;
|
||||
}
|
||||
|
||||
/** Computes the individual applied transform values from the world transform. This can be useful to perform processing using
|
||||
* the applied transform after the world transform has been modified directly (eg, by a constraint).
|
||||
/** Computes the applied transform values from the world transform.
|
||||
* <p>
|
||||
* Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. */
|
||||
* If the world transform is modified (by a constraint, {@link #rotateWorld(float)}, etc) then this method should be called so
|
||||
* the applied transform matches the world transform. The applied transform may be needed by other code (eg to apply another
|
||||
* constraint).
|
||||
* <p>
|
||||
* Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. The applied transform after
|
||||
* calling this method is equivalent to the local transform used to compute the world transform, but may not be identical. */
|
||||
public function updateAppliedTransform():Void {
|
||||
var parent:Bone = parent;
|
||||
if (parent == null) {
|
||||
@ -329,42 +370,58 @@ class Bone implements Updatable {
|
||||
}
|
||||
}
|
||||
|
||||
/** The world rotation for the X axis, calculated using {@link #a} and {@link #c}. */
|
||||
public var worldRotationX(get, never):Float;
|
||||
|
||||
private function get_worldRotationX():Float {
|
||||
return Math.atan2(c, a) * MathUtils.radDeg;
|
||||
}
|
||||
|
||||
/** The world rotation for the Y axis, calculated using {@link #b} and {@link #d}. */
|
||||
public var worldRotationY(get, never):Float;
|
||||
|
||||
private function get_worldRotationY():Float {
|
||||
return Math.atan2(d, b) * MathUtils.radDeg;
|
||||
}
|
||||
|
||||
/** The magnitude (always positive) of the world scale X, calculated using {@link #a} and {@link #c}. */
|
||||
public var worldScaleX(get, never):Float;
|
||||
|
||||
private function get_worldScaleX():Float {
|
||||
return Math.sqrt(a * a + c * c);
|
||||
}
|
||||
|
||||
/** The magnitude (always positive) of the world scale Y, calculated using {@link #b} and {@link #d}. */
|
||||
public var worldScaleY(get, never):Float;
|
||||
|
||||
private function get_worldScaleY():Float {
|
||||
return Math.sqrt(b * b + d * d);
|
||||
}
|
||||
|
||||
/** Transforms a point from world coordinates to the parent bone's local coordinates.
|
||||
* @param world The world coordinates to transform.
|
||||
* @return The transformed coordinates in the parent's local space.
|
||||
*/
|
||||
private function worldToParent(world: Array<Float>):Array<Float> {
|
||||
if (world == null)
|
||||
throw new SpineException("world cannot be null.");
|
||||
return parent == null ? world : parent.worldToLocal(world);
|
||||
}
|
||||
|
||||
/** Transforms a point from the parent bone's coordinates to world coordinates.
|
||||
* @param world The parent coordinates to transform.
|
||||
* @return The transformed coordinates in world space.
|
||||
*/
|
||||
private function parentToWorld(world: Array<Float>):Array<Float> {
|
||||
if (world == null)
|
||||
throw new SpineException("world cannot be null.");
|
||||
return parent == null ? world : parent.localToWorld(world);
|
||||
}
|
||||
|
||||
/** Transforms a point from world coordinates to the bone's local coordinates.
|
||||
* @param world The world coordinates to transform.
|
||||
* @return The transformed coordinates in local space.
|
||||
*/
|
||||
public function worldToLocal(world:Array<Float>):Array<Float> {
|
||||
var a:Float = a, b:Float = b, c:Float = c, d:Float = d;
|
||||
var invDet:Float = 1 / (a * d - b * c);
|
||||
@ -374,6 +431,10 @@ class Bone implements Updatable {
|
||||
return world;
|
||||
}
|
||||
|
||||
/** Transforms a point from the bone's local coordinates to world coordinates.
|
||||
* @param local The local coordinates to transform.
|
||||
* @return The transformed coordinates in world space.
|
||||
*/
|
||||
public function localToWorld(local:Array<Float>):Array<Float> {
|
||||
var localX:Float = local[0], localY:Float = local[1];
|
||||
local[0] = localX * a + localY * b + worldX;
|
||||
@ -381,12 +442,20 @@ class Bone implements Updatable {
|
||||
return local;
|
||||
}
|
||||
|
||||
/** Transforms a world rotation to a local rotation.
|
||||
* @param worldRotation The world rotation in degrees.
|
||||
* @return The rotation in local space in degrees.
|
||||
*/
|
||||
public function worldToLocalRotation(worldRotation:Float):Float {
|
||||
var sin:Float = MathUtils.sinDeg(worldRotation),
|
||||
cos:Float = MathUtils.cosDeg(worldRotation);
|
||||
return Math.atan2(a * sin - c * cos, d * cos - b * sin) * MathUtils.radDeg + rotation - shearX;
|
||||
}
|
||||
|
||||
/** Transforms a local rotation to a world rotation.
|
||||
* @param localRotation The local rotation in degrees.
|
||||
* @return The rotation in world space in degrees.
|
||||
*/
|
||||
public function localToWorldRotation(localRotation:Float):Float {
|
||||
localRotation -= rotation - shearX;
|
||||
var sin:Float = MathUtils.sinDeg(localRotation),
|
||||
@ -394,6 +463,12 @@ class Bone implements Updatable {
|
||||
return Math.atan2(cos * c + sin * d, cos * a + sin * b) * MathUtils.radDeg;
|
||||
}
|
||||
|
||||
/** Rotates the world transform the specified amount.
|
||||
* <p>
|
||||
* After changes are made to the world transform, {@link #updateAppliedTransform()} should be called and
|
||||
* {@link #update(Physics)} will need to be called on any child bones, recursively.
|
||||
* @param degrees The rotation in degrees.
|
||||
*/
|
||||
public function rotateWorld(degrees:Float):Void {
|
||||
degrees *= MathUtils.degRad;
|
||||
var sin:Float = Math.sin(degrees), cos:Float = Math.cos(degrees);
|
||||
|
||||
@ -29,23 +29,41 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** Stores the setup pose for a {@link Bone}. */
|
||||
class BoneData {
|
||||
private var _index:Int;
|
||||
private var _name:String;
|
||||
private var _parent:BoneData;
|
||||
|
||||
/** The bone's length. */
|
||||
public var length:Float = 0;
|
||||
/** The local x translation. */
|
||||
public var x:Float = 0;
|
||||
/** The local y translation. */
|
||||
public var y:Float = 0;
|
||||
/** The local rotation in degrees, counter clockwise. */
|
||||
public var rotation:Float = 0;
|
||||
/** The local scaleX. */
|
||||
public var scaleX:Float = 1;
|
||||
/** The local scaleY. */
|
||||
public var scaleY:Float = 1;
|
||||
/** The local shearX. */
|
||||
public var shearX:Float = 0;
|
||||
/** The local shearY. */
|
||||
public var shearY:Float = 0;
|
||||
/** Determines how parent world transforms affect this bone. */
|
||||
public var inherit:Inherit = Inherit.normal;
|
||||
/** When true, {@link Skeleton#updateWorldTransform()} only updates this bone if the {@link Skeleton#getSkin()} contains
|
||||
* this bone.
|
||||
*
|
||||
* See {@link Skin#getBones()}. */
|
||||
public var skinRequired:Bool = false;
|
||||
/** The color of the bone as it was in Spine, or a default color if nonessential data was not exported. Bones are not usually
|
||||
* rendered at runtime. */
|
||||
public var color:Color = new Color(0, 0, 0, 0);
|
||||
/** The bone icon as it was in Spine, or null if nonessential data was not exported. */
|
||||
public var icon:String;
|
||||
/** False if the bone was hidden in Spine and nonessential data was exported. Does not affect runtime rendering. */
|
||||
public var visible:Bool = false;
|
||||
|
||||
/** @param parent May be null. */
|
||||
@ -59,12 +77,14 @@ class BoneData {
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
/** The index of the bone in {@link Skeleton#getBones()}. */
|
||||
public var index(get, never):Int;
|
||||
|
||||
private function get_index():Int {
|
||||
return _index;
|
||||
}
|
||||
|
||||
/** The name of the bone, which is unique across all bones in the skeleton. */
|
||||
public var name(get, never):String;
|
||||
|
||||
function get_name():String {
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** A color class, storing the r, g, b and alpha components as floats in the range [0,1]. */
|
||||
class Color {
|
||||
public static var WHITE:Color = new Color(1, 1, 1, 1);
|
||||
public static var RED:Color = new Color(1, 0, 0, 1);
|
||||
|
||||
@ -29,9 +29,17 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** The base class for all constraint datas. */
|
||||
class ConstraintData {
|
||||
/** The constraint's name, which is unique across all constraints in the skeleton of the same type. */
|
||||
public var name:String;
|
||||
/** The ordinal of this constraint for the order a skeleton's constraints will be applied by
|
||||
* Skeleton#updateWorldTransform(). */
|
||||
public var order:Int = 0;
|
||||
/** When true, Skeleton#updateWorldTransform() only updates this constraint if the Skeleton#getSkin()
|
||||
* contains this constraint.
|
||||
*
|
||||
* See Skin#getConstraints(). */
|
||||
public var skinRequired:Bool = false;
|
||||
|
||||
function new(name:String, order:Int, skinRequired:Bool) {
|
||||
|
||||
@ -29,9 +29,16 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** Stores the current pose values for an {@link Event}.
|
||||
* <p>
|
||||
* See Timeline
|
||||
* {@link Timeline#apply(Skeleton, float, float, com.badlogic.gdx.utils.Array, float, com.esotericsoftware.spine.Animation.MixBlend, com.esotericsoftware.spine.Animation.MixDirection)},
|
||||
* AnimationStateListener {@link AnimationStateListener#event(com.esotericsoftware.spine.AnimationState.TrackEntry, Event)}, and
|
||||
* <a href="https://esotericsoftware.com/spine-events">Events</a> in the Spine User Guide. */
|
||||
class Event {
|
||||
private var _data:EventData;
|
||||
|
||||
/** The animation time this event was keyed. */
|
||||
public var time:Float = 0;
|
||||
public var intValue:Int = 0;
|
||||
public var floatValue:Float = 0;
|
||||
@ -46,6 +53,7 @@ class Event {
|
||||
_data = data;
|
||||
}
|
||||
|
||||
/** The event's setup pose data. */
|
||||
public var data(get, never):EventData;
|
||||
|
||||
private function get_data():EventData {
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** Stores the setup pose values for an {@link Event}.
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-events">Events</a> in the Spine User Guide. */
|
||||
class EventData {
|
||||
private var _name:String;
|
||||
|
||||
@ -45,6 +48,7 @@ class EventData {
|
||||
_name = name;
|
||||
}
|
||||
|
||||
/** The name of the event, which is unique across all events in the skeleton. */
|
||||
public var name(get, never):String;
|
||||
|
||||
private function get_name():String {
|
||||
|
||||
@ -30,9 +30,15 @@
|
||||
package spine;
|
||||
|
||||
interface HasTextureRegion {
|
||||
/** The name used to find the {@link #region}. */
|
||||
public var path:String;
|
||||
/** Sets the region used to draw the attachment. After setting the region or if the region's properties are changed,
|
||||
* {@link #updateRegion()} must be called. */
|
||||
public var region:TextureRegion;
|
||||
/** The color to tint the attachment. */
|
||||
public var color:Color;
|
||||
public var sequence:Sequence;
|
||||
/** Updates any values the attachment calculates using the {@link #region}. Must be called after setting the
|
||||
* {@link #region} or if the region's properties are changed. */
|
||||
public function updateRegion():Void;
|
||||
}
|
||||
|
||||
@ -29,15 +29,32 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** 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="https://esotericsoftware.com/spine-ik-constraints">IK constraints</a> in the Spine User Guide. */
|
||||
class IkConstraint implements Updatable {
|
||||
private var _data:IkConstraintData;
|
||||
|
||||
/** The bones that will be modified by this IK constraint. */
|
||||
public var bones:Array<Bone>;
|
||||
/** The bone that is the IK target. */
|
||||
public var target:Bone;
|
||||
/** For two bone IK, controls the bend direction of the IK bones, either 1 or -1. */
|
||||
public var bendDirection:Int = 0;
|
||||
/** For one bone IK, when true and the target is too close, the bone is scaled to reach it. */
|
||||
public var compress:Bool = false;
|
||||
/** When true and the target is out of range, the parent bone is scaled to reach it.
|
||||
* <p>
|
||||
* For two bone IK: 1) the child bone's local Y translation is set to 0, 2) stretch is not applied if {@link #getSoftness()} is
|
||||
* > 0, and 3) if the parent bone has local nonuniform scale, stretch is not applied. */
|
||||
public var stretch:Bool = false;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation.
|
||||
* <p>
|
||||
* For two bone IK: if the parent bone has local nonuniform scale, the child bone's local Y translation is set to 0. */
|
||||
public var mix:Float = 0;
|
||||
/** For two bone IK, the target bone's distance from the maximum reach of the bones where rotation begins to slow. The bones
|
||||
* will not straighten completely until the target is this far out of range. */
|
||||
public var softness:Float = 0;
|
||||
public var active:Bool = false;
|
||||
|
||||
@ -74,6 +91,7 @@ class IkConstraint implements Updatable {
|
||||
stretch = data.stretch;
|
||||
}
|
||||
|
||||
/** Applies the constraint to the constrained bones. */
|
||||
public function update(physics:Physics):Void {
|
||||
if (mix == 0)
|
||||
return;
|
||||
@ -85,6 +103,7 @@ class IkConstraint implements Updatable {
|
||||
}
|
||||
}
|
||||
|
||||
/** The IK constraint's setup pose data. */
|
||||
public var data(get, never):IkConstraintData;
|
||||
|
||||
private function get_data():IkConstraintData {
|
||||
@ -95,8 +114,7 @@ class IkConstraint implements Updatable {
|
||||
return _data.name != null ? _data.name : "IkContstraint?";
|
||||
}
|
||||
|
||||
/** 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 function apply1(bone:Bone, targetX:Float, targetY:Float, compress:Bool, stretch:Bool, uniform:Bool, alpha:Float):Void {
|
||||
var p:Bone = bone.parent;
|
||||
var pa:Float = p.a, pb:Float = p.b, pc:Float = p.c, pd:Float = p.d;
|
||||
@ -164,9 +182,8 @@ class IkConstraint implements Updatable {
|
||||
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, 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.
|
||||
* @param child Any descendant bone of the parent. */
|
||||
/** Applies 2 bone IK. The target is specified in the world coordinate system.
|
||||
* @param child A direct descendant of the parent bone. */
|
||||
static public function apply2(parent:Bone, child:Bone, targetX:Float, targetY:Float, bendDir:Int, stretch:Bool, uniform:Bool, softness:Float,
|
||||
alpha:Float):Void {
|
||||
if (parent.inherit != Inherit.normal || child.inherit != Inherit.normal) return;
|
||||
|
||||
@ -29,14 +29,31 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** Stores the setup pose for an {@link IkConstraint}.
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-ik-constraints">IK constraints</a> in the Spine User Guide. */
|
||||
class IkConstraintData extends ConstraintData {
|
||||
/** The bones that are constrained by this IK constraint. */
|
||||
public var bones:Array<BoneData> = new Array<BoneData>();
|
||||
/** The bone that is the IK target. */
|
||||
public var target:BoneData;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation.
|
||||
*
|
||||
* For two bone IK: if the parent bone has local nonuniform scale, the child bone's local Y translation is set to 0. */
|
||||
public var mix:Float = 0;
|
||||
/** For two bone IK, controls the bend direction of the IK bones, either 1 or -1. */
|
||||
public var bendDirection:Int = 0;
|
||||
/** For one bone IK, when true and the target is too close, the bone is scaled to reach it. */
|
||||
public var compress:Bool = false;
|
||||
/** When true and the target is out of range, the parent bone is scaled to reach it.
|
||||
*
|
||||
* For two bone IK: 1) the child bone's local Y translation is set to 0, 2) stretch is not applied if {@link #getSoftness()} is
|
||||
* > 0, and 3) if the parent bone has local nonuniform scale, stretch is not applied. */
|
||||
public var stretch:Bool = false;
|
||||
/** When true and {@link #getCompress()} or {@link #getStretch()} is used, the bone is scaled on both the X and Y axes. */
|
||||
public var uniform:Bool = false;
|
||||
/** For two bone IK, the target bone's distance from the maximum reach of the bones where rotation begins to slow. The bones
|
||||
* will not straighten completely until the target is this far out of range. */
|
||||
public var softness:Float = 0;
|
||||
|
||||
public function new(name:String) {
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** Determines how a bone inherits world transforms from parent bones. */
|
||||
class Inherit {
|
||||
public static var normal(default, never):Inherit = new Inherit(0, "normal");
|
||||
public static var onlyTranslation(default, never):Inherit = new Inherit(1, "onlyTranslation");
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/**
|
||||
* Various math utility functions.
|
||||
*/
|
||||
class MathUtils {
|
||||
static public var PI:Float = Math.PI;
|
||||
static public var PI2:Float = Math.PI * 2;
|
||||
@ -36,18 +39,41 @@ class MathUtils {
|
||||
static public var radDeg:Float = 180 / Math.PI;
|
||||
static public var degRad:Float = Math.PI / 180;
|
||||
|
||||
/**
|
||||
* Returns the cosine in degrees.
|
||||
* @param degrees The angle in degrees.
|
||||
* @return The cosine.
|
||||
*/
|
||||
static public function cosDeg(degrees:Float):Float {
|
||||
return Math.cos(degrees * degRad);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sine in degrees.
|
||||
* @param degrees The angle in degrees.
|
||||
* @return The sine.
|
||||
*/
|
||||
static public function sinDeg(degrees:Float):Float {
|
||||
return Math.sin(degrees * degRad);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the arc tangent in degrees.
|
||||
* @param y The y-coordinate.
|
||||
* @param x The x-coordinate.
|
||||
* @return The arc tangent in degrees.
|
||||
*/
|
||||
static public function atan2Deg (y:Float, x:Float):Float {
|
||||
return Math.atan2(y, x) * MathUtils.degRad;
|
||||
return Math.atan2(y, x) * MathUtils.radDeg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clamps a value between a minimum and maximum value.
|
||||
* @param value The value to clamp.
|
||||
* @param min The minimum value.
|
||||
* @param max The maximum value.
|
||||
* @return The clamped value.
|
||||
*/
|
||||
static public function clamp(value:Float, min:Float, max:Float):Float {
|
||||
if (value < min)
|
||||
return min;
|
||||
@ -56,14 +82,32 @@ class MathUtils {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the signum function of the value.
|
||||
* @param value The value.
|
||||
* @return -1 if the value is negative, 1 if the value is positive, 0 if the value is zero.
|
||||
*/
|
||||
static public function signum(value:Float):Float {
|
||||
return value > 0 ? 1 : value < 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random number between the specified minimum and maximum values using a triangular distribution.
|
||||
* @param min The minimum value.
|
||||
* @param max The maximum value.
|
||||
* @return A random number using a triangular distribution.
|
||||
*/
|
||||
static public function randomTriangular(min:Float, max:Float):Float {
|
||||
return randomTriangularWith(min, max, (min + max) * 0.5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random number between the specified minimum and maximum values using a triangular distribution.
|
||||
* @param min The minimum value.
|
||||
* @param max The maximum value.
|
||||
* @param mode The mode of the triangular distribution.
|
||||
* @return A random number using a triangular distribution.
|
||||
*/
|
||||
static public function randomTriangularWith(min:Float, max:Float, mode:Float):Float {
|
||||
var u:Float = Math.random();
|
||||
var d:Float = max - min;
|
||||
|
||||
@ -31,6 +31,10 @@ package spine;
|
||||
|
||||
import 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}.
|
||||
*
|
||||
* See <a href="https://esotericsoftware.com/spine-path-constraints">Path constraints</a> in the Spine User Guide. */
|
||||
class PathConstraint implements Updatable {
|
||||
private static inline var NONE:Int = -1;
|
||||
private static inline var BEFORE:Int = -2;
|
||||
@ -40,11 +44,17 @@ class PathConstraint implements Updatable {
|
||||
private var _data:PathConstraintData;
|
||||
private var _bones:Array<Bone>;
|
||||
|
||||
/** The slot whose path attachment will be used to constrained the bones. */
|
||||
public var target:Slot;
|
||||
/** The position along the path. */
|
||||
public var position:Float = 0;
|
||||
/** The spacing between bones. */
|
||||
public var spacing:Float = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. */
|
||||
public var mixRotate:Float = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. */
|
||||
public var mixX:Float = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. */
|
||||
public var mixY:Float = 0;
|
||||
|
||||
private var _spaces(default, never):Array<Float> = new Array<Float>();
|
||||
@ -89,6 +99,7 @@ class PathConstraint implements Updatable {
|
||||
mixY = data.mixY;
|
||||
}
|
||||
|
||||
/** Applies the constraint to the constrained bones. */
|
||||
public function update(physics:Physics):Void {
|
||||
var attachment:PathAttachment = cast(target.attachment, PathAttachment);
|
||||
if (attachment == null)
|
||||
@ -585,12 +596,14 @@ class PathConstraint implements Updatable {
|
||||
}
|
||||
}
|
||||
|
||||
/** The bones that will be modified by this path constraint. */
|
||||
public var bones(get, never):Array<Bone>;
|
||||
|
||||
private function get_bones():Array<Bone> {
|
||||
return _bones;
|
||||
}
|
||||
|
||||
/** The path constraint's setup pose data. */
|
||||
public var data(get, never):PathConstraintData;
|
||||
|
||||
private function get_data():PathConstraintData {
|
||||
|
||||
@ -29,24 +29,39 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** Stores the setup pose for a {@link PathConstraint}.
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-path-constraints">Path constraints</a> in the Spine User Guide. */
|
||||
class PathConstraintData extends ConstraintData {
|
||||
/** The bones that will be modified by this path constraint. */
|
||||
private var _bones:Array<BoneData> = new Array<BoneData>();
|
||||
|
||||
/** The slot whose path attachment will be used to constrained the bones. */
|
||||
public var target:SlotData;
|
||||
/** The mode for positioning the first bone on the path. */
|
||||
public var positionMode:PositionMode = PositionMode.fixed;
|
||||
/** The mode for positioning the bones after the first bone on the path. */
|
||||
public var spacingMode:SpacingMode = SpacingMode.fixed;
|
||||
/** The mode for adjusting the rotation of the bones. */
|
||||
public var rotateMode:RotateMode = RotateMode.chain;
|
||||
/** An offset added to the constrained bone rotation. */
|
||||
public var offsetRotation:Float = 0;
|
||||
/** The position along the path. */
|
||||
public var position:Float = 0;
|
||||
/** The spacing between bones. */
|
||||
public var spacing:Float = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. */
|
||||
public var mixRotate:Float = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. */
|
||||
public var mixX:Float = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. */
|
||||
public var mixY:Float = 0;
|
||||
|
||||
public function new(name:String) {
|
||||
super(name, 0, false);
|
||||
}
|
||||
|
||||
/** The bones that will be modified by this path constraint. */
|
||||
public var bones(get, never):Array<BoneData>;
|
||||
|
||||
private function get_bones():Array<BoneData> {
|
||||
|
||||
@ -29,10 +29,15 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** Determines how physics and other non-deterministic updates are applied. */
|
||||
class Physics {
|
||||
/** Physics are not updated or applied. */
|
||||
public static var none(default, never):Physics = new Physics("none");
|
||||
/** Physics are reset to the current pose. */
|
||||
public static var reset(default, never):Physics = new Physics("reset");
|
||||
/** Physics are updated and the pose from physics is applied. */
|
||||
public static var update(default, never):Physics = new Physics("update");
|
||||
/** Physics are not updated but the pose from physics is applied. */
|
||||
public static var pose(default, never):Physics = new Physics("pose");
|
||||
|
||||
public static var values:Array<Physics> = [none, reset, update, pose];
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** Stores the current pose for a physics constraint. A physics constraint applies physics to bones.
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-physics-constraints">Physics constraints</a> in the Spine User Guide. */
|
||||
class PhysicsConstraint implements Updatable {
|
||||
private var _data:PhysicsConstraintData;
|
||||
private var _bone:Bone = null;
|
||||
@ -108,6 +111,7 @@ class PhysicsConstraint implements Updatable {
|
||||
return active;
|
||||
}
|
||||
|
||||
/** Applies the constraint to the constrained bones. */
|
||||
public function update(physics:Physics):Void {
|
||||
var mix:Float = this.mix;
|
||||
if (mix == 0) return;
|
||||
@ -291,6 +295,8 @@ class PhysicsConstraint implements Updatable {
|
||||
bone.updateAppliedTransform();
|
||||
}
|
||||
|
||||
/** Translates the physics constraint so next update(Physics) forces are applied as if the bone moved an additional
|
||||
* amount in world space. */
|
||||
public function translate (x:Float, y:Float):Void {
|
||||
ux -= x;
|
||||
uy -= y;
|
||||
@ -298,12 +304,15 @@ class PhysicsConstraint implements Updatable {
|
||||
cy -= y;
|
||||
}
|
||||
|
||||
/** Rotates the physics constraint so next update(Physics) forces are applied as if the bone rotated around the
|
||||
* specified point in world space. */
|
||||
public function rotate (x:Float, y:Float, degrees:Float):Void {
|
||||
var r:Float = degrees * MathUtils.degRad, cos:Float = Math.cos(r), sin:Float = Math.sin(r);
|
||||
var dx:Float = cx - x, dy:Float = cy - y;
|
||||
translate(dx * cos - dy * sin - dx, dx * sin + dy * cos - dy);
|
||||
}
|
||||
|
||||
/** The bone constrained by this physics constraint. */
|
||||
public var bone(get, never):Bone;
|
||||
|
||||
private function get_bone():Bone {
|
||||
@ -312,6 +321,7 @@ class PhysicsConstraint implements Updatable {
|
||||
else return _bone;
|
||||
}
|
||||
|
||||
/** The physics constraint's setup pose data. */
|
||||
public var data(get, never):PhysicsConstraintData;
|
||||
|
||||
private function get_data():PhysicsConstraintData {
|
||||
|
||||
@ -29,7 +29,11 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** Stores the setup pose for a {@link PhysicsConstraint}.
|
||||
*
|
||||
* See <a href="https://esotericsoftware.com/spine-physics-constraints">Physics constraints</a> in the Spine User Guide. */
|
||||
class PhysicsConstraintData extends ConstraintData {
|
||||
/** The bone constrained by this physics constraint. */
|
||||
public var bone:BoneData;
|
||||
public var x:Float = 0;
|
||||
public var y:Float = 0;
|
||||
@ -44,6 +48,7 @@ class PhysicsConstraintData extends ConstraintData {
|
||||
public var massInverse:Float = 0;
|
||||
public var wind:Float = 0;
|
||||
public var gravity:Float = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained poses. */
|
||||
public var mix:Float = 0;
|
||||
public var inertiaGlobal:Bool = false;
|
||||
public var strengthGlobal:Bool = false;
|
||||
|
||||
@ -29,6 +29,12 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/**
|
||||
* Objects implementing this interface can be reset to prepare them for reuse by an object pool.
|
||||
*/
|
||||
interface Poolable {
|
||||
/**
|
||||
* Resets this object to prepare it for reuse by an object pool.
|
||||
*/
|
||||
function reset():Void;
|
||||
}
|
||||
|
||||
@ -29,6 +29,10 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** Controls how the first bone is positioned along the path.
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-path-constraints#Position-mode">Position mode</a> in the Spine User
|
||||
* Guide. */
|
||||
class PositionMode {
|
||||
public static var fixed(default, never):PositionMode = new PositionMode("fixed");
|
||||
public static var percent(default, never):PositionMode = new PositionMode("percent");
|
||||
|
||||
@ -29,9 +29,14 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** Controls how bones are rotated, translated, and scaled to match the path.
|
||||
*
|
||||
* See <a href="https://esotericsoftware.com/spine-path-constraints#Rotate-mode">Rotate mode</a> in the Spine User Guide. */
|
||||
class RotateMode {
|
||||
public static var tangent(default, never):RotateMode = new RotateMode("tangent");
|
||||
public static var chain(default, never):RotateMode = new RotateMode("chain");
|
||||
/** When chain scale, constrained bones should all have the same parent. That way when the path constraint scales a bone, it
|
||||
* doesn't affect other constrained bones. */
|
||||
public static var chainScale(default, never):RotateMode = new RotateMode("chainScale");
|
||||
|
||||
public static var values(default, never):Array<RotateMode> = [tangent, chain, chainScale];
|
||||
|
||||
@ -29,9 +29,11 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** A sequence for an attachment with multiple texture regions, which can be used for animation. */
|
||||
class Sequence {
|
||||
private static var _nextID = 0;
|
||||
|
||||
/** Returns a unique ID for this attachment. */
|
||||
public var id = _nextID++;
|
||||
public var regions:Array<TextureRegion>;
|
||||
public var start = 0;
|
||||
@ -45,6 +47,7 @@ class Sequence {
|
||||
this.regions.resize(count);
|
||||
}
|
||||
|
||||
/** Copy constructor. */
|
||||
public function copy():Sequence {
|
||||
var copy = new Sequence(this.regions.length);
|
||||
for (i in 0...this.regions.length) {
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/**
|
||||
* Defines how a {@link Sequence} is played.
|
||||
*/
|
||||
class SequenceMode {
|
||||
public static var hold(default, never):SequenceMode = new SequenceMode("hold", 0);
|
||||
public static var once(default, never):SequenceMode = new SequenceMode("once", 1);
|
||||
|
||||
@ -37,33 +37,61 @@ import spine.attachments.MeshAttachment;
|
||||
import spine.attachments.PathAttachment;
|
||||
import spine.attachments.RegionAttachment;
|
||||
|
||||
/** Stores the current pose for a skeleton.
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-runtime-architecture#Instance-objects">Instance objects</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
class Skeleton {
|
||||
private static var quadTriangles:Array<Int> = [0, 1, 2, 2, 3, 0];
|
||||
private var _data:SkeletonData;
|
||||
|
||||
/** The skeleton's bones, sorted parent first. The root bone is always the first bone. */
|
||||
public var bones:Array<Bone>;
|
||||
/** The skeleton's slots. */
|
||||
public var slots:Array<Slot>; // Setup pose 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 var drawOrder:Array<Slot>;
|
||||
/** The skeleton's IK constraints. */
|
||||
public var ikConstraints:Array<IkConstraint>;
|
||||
/** The skeleton's transform constraints. */
|
||||
public var transformConstraints:Array<TransformConstraint>;
|
||||
/** The skeleton's path constraints. */
|
||||
public var pathConstraints:Array<PathConstraint>;
|
||||
/** The skeleton's physics constraints. */
|
||||
public var physicsConstraints:Array<PhysicsConstraint>;
|
||||
|
||||
private var _updateCache:Array<Updatable> = new Array<Updatable>();
|
||||
private var _skin:Skin;
|
||||
|
||||
/** The color to tint all the skeleton's attachments. */
|
||||
public var color:Color = new Color(1, 1, 1, 1);
|
||||
/** Scales the entire skeleton on the X axis.
|
||||
* <p>
|
||||
* Bones that do not inherit scale are still affected by this property. */
|
||||
public var scaleX:Float = 1;
|
||||
|
||||
/** Scales the entire skeleton on the Y axis.
|
||||
* <p>
|
||||
* Bones that do not inherit scale are still affected by this property. */
|
||||
public var scaleY(get, default):Float = 1;
|
||||
function get_scaleY() {
|
||||
return Bone.yDown ? -scaleY : scaleY;
|
||||
}
|
||||
|
||||
/** Sets the skeleton X position, which is added to the root bone worldX position.
|
||||
* <p>
|
||||
* Bones that do not inherit translation are still affected by this property. */
|
||||
public var x:Float = 0;
|
||||
/** Sets the skeleton Y position, which is added to the root bone worldY position.
|
||||
* <p>
|
||||
* Bones that do not inherit translation are still affected by this property. */
|
||||
public var y:Float = 0;
|
||||
/** Returns the skeleton's time. This is used for time-based manipulations, such as {@link PhysicsConstraint}.
|
||||
* <p>
|
||||
* See {@link #update(float)}. */
|
||||
public var time:Float = 0;
|
||||
|
||||
/** Creates a new skeleton with the specified skeleton data. */
|
||||
public function new(data:SkeletonData) {
|
||||
if (data == null) {
|
||||
throw new SpineException("data cannot be null.");
|
||||
@ -115,8 +143,8 @@ class Skeleton {
|
||||
updateCache();
|
||||
}
|
||||
|
||||
/** Caches information about bones and constraints. Must be called if bones, constraints, or weighted path attachments are
|
||||
* added or removed. */
|
||||
/** Caches information about bones and constraints. Must be called if the {@link #getSkin()} is modified or if bones,
|
||||
* constraints, or weighted path attachments are added or removed. */
|
||||
public function updateCache():Void {
|
||||
_updateCache.resize(0);
|
||||
|
||||
@ -350,7 +378,10 @@ 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="https://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
public function updateWorldTransform(physics:Physics):Void {
|
||||
if (physics == null) throw new SpineException("physics is undefined");
|
||||
for (bone in bones) {
|
||||
@ -368,6 +399,11 @@ class Skeleton {
|
||||
}
|
||||
}
|
||||
|
||||
/** Temporarily sets the root bone as a child of the specified bone, then updates the world transform for each bone and applies
|
||||
* all constraints.
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
public function updateWorldTransformWith(physics:Physics, parent:Bone):Void {
|
||||
// Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection.
|
||||
var rootBone:Bone = rootBone;
|
||||
@ -396,7 +432,7 @@ class Skeleton {
|
||||
}
|
||||
}
|
||||
|
||||
/** 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 function setToSetupPose():Void {
|
||||
setBonesToSetupPose();
|
||||
setSlotsToSetupPose();
|
||||
@ -411,6 +447,7 @@ class Skeleton {
|
||||
for (constraint in this.physicsConstraints) constraint.setToSetupPose();
|
||||
}
|
||||
|
||||
/** Sets the slots and draw order to their setup pose values. */
|
||||
public function setSlotsToSetupPose():Void {
|
||||
var i:Int = 0;
|
||||
for (slot in slots) {
|
||||
@ -419,18 +456,21 @@ class Skeleton {
|
||||
}
|
||||
}
|
||||
|
||||
/** The skeleton's setup pose data. */
|
||||
public var data(get, never):SkeletonData;
|
||||
|
||||
private function get_data():SkeletonData {
|
||||
return _data;
|
||||
}
|
||||
|
||||
public var getUpdateCache(get, never):Array<Updatable>;
|
||||
/** The list of bones and constraints, sorted in the order they should be updated, as computed by {@link #updateCache()}. */
|
||||
public var updateCache(get, never):Array<Updatable>;
|
||||
|
||||
private function get_getUpdateCache():Array<Updatable> {
|
||||
private function get_updateCache():Array<Updatable> {
|
||||
return _updateCache;
|
||||
}
|
||||
|
||||
/** Returns the root bone, or null if the skeleton has no bones. */
|
||||
public var rootBone(get, never):Bone;
|
||||
|
||||
private function get_rootBone():Bone {
|
||||
@ -439,7 +479,8 @@ class Skeleton {
|
||||
return bones[0];
|
||||
}
|
||||
|
||||
/** @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
|
||||
* repeatedly. */
|
||||
public function findBone(boneName:String):Bone {
|
||||
if (boneName == null) {
|
||||
throw new SpineException("boneName cannot be null.");
|
||||
@ -465,7 +506,8 @@ class Skeleton {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** @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
|
||||
* repeatedly. */
|
||||
public function findSlot(slotName:String):Slot {
|
||||
if (slotName == null) {
|
||||
throw new SpineException("slotName cannot be null.");
|
||||
@ -477,8 +519,12 @@ class Skeleton {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** The skeleton's current skin. */
|
||||
public var skinName(get, set):String;
|
||||
|
||||
/** Sets a skin by name.
|
||||
* <p>
|
||||
* See {@link #setSkin(Skin)}. */
|
||||
private function set_skinName(skinName:String):String {
|
||||
var skin:Skin = data.findSkin(skinName);
|
||||
if (skin == null)
|
||||
@ -492,16 +538,23 @@ class Skeleton {
|
||||
return _skin == null ? null : _skin.name;
|
||||
}
|
||||
|
||||
/** The skeleton's current skin. */
|
||||
public var skin(get, set):Skin;
|
||||
|
||||
private function get_skin():Skin {
|
||||
return _skin;
|
||||
}
|
||||
|
||||
/** Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default skin}.
|
||||
* 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. */
|
||||
/** Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default skin}. If the
|
||||
* skin is changed, {@link #updateCache()} is called.
|
||||
* <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.
|
||||
* <p>
|
||||
* After changing the skin, the visible attachments can be reset to those attached in the setup pose by calling
|
||||
* {@link #setSlotsToSetupPose()}. Also, often {@link AnimationState#apply(Skeleton)} is called before the next time the
|
||||
* skeleton is rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new
|
||||
* skin. */
|
||||
private function set_skin(newSkin:Skin):Skin {
|
||||
if (newSkin == _skin)
|
||||
return null;
|
||||
@ -526,12 +579,18 @@ class Skeleton {
|
||||
return _skin;
|
||||
}
|
||||
|
||||
/** @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)}. */
|
||||
public function getAttachmentForSlotName(slotName:String, attachmentName:String):Attachment {
|
||||
return getAttachmentForSlotIndex(data.findSlot(slotName).index, 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="https://esotericsoftware.com/spine-runtime-skins">Runtime skins</a> in the Spine Runtimes Guide. */
|
||||
public function getAttachmentForSlotIndex(slotIndex:Int, attachmentName:String):Attachment {
|
||||
if (attachmentName == null)
|
||||
throw new SpineException("attachmentName cannot be null.");
|
||||
@ -545,7 +604,9 @@ class Skeleton {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @param attachmentName May be null. */
|
||||
/** 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's attachment. */
|
||||
public function setAttachment(slotName:String, attachmentName:String):Void {
|
||||
if (slotName == null)
|
||||
throw new SpineException("slotName cannot be null.");
|
||||
@ -567,7 +628,8 @@ class Skeleton {
|
||||
throw new SpineException("Slot not found: " + slotName);
|
||||
}
|
||||
|
||||
/** @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 repeatedly. */
|
||||
public function findIkConstraint(constraintName:String):IkConstraint {
|
||||
if (constraintName == null)
|
||||
throw new SpineException("constraintName cannot be null.");
|
||||
@ -578,7 +640,8 @@ class Skeleton {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @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 repeatedly. */
|
||||
public function findTransformConstraint(constraintName:String):TransformConstraint {
|
||||
if (constraintName == null)
|
||||
throw new SpineException("constraintName cannot be null.");
|
||||
@ -589,7 +652,8 @@ class Skeleton {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @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 repeatedly. */
|
||||
public function findPathConstraint(constraintName:String):PathConstraint {
|
||||
if (constraintName == null)
|
||||
throw new SpineException("constraintName cannot be null.");
|
||||
@ -600,7 +664,8 @@ class Skeleton {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** Finds a physics constraint by comparing each physics constraint's name. It is more efficient to cache the results of this
|
||||
* method than to call it repeatedly. */
|
||||
public function findPhysicsConstraint(constraintName:String):PhysicsConstraint {
|
||||
if (constraintName == null)
|
||||
throw new SpineException("constraintName cannot be null.");
|
||||
@ -618,6 +683,8 @@ class Skeleton {
|
||||
private var _tempVertices = new Array<Float>();
|
||||
private var _bounds = new Rectangle();
|
||||
|
||||
/** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose.
|
||||
* Optionally applies clipping. */
|
||||
public function getBounds(clipper: SkeletonClipping = null):Rectangle {
|
||||
var minX:Float = Math.POSITIVE_INFINITY;
|
||||
var minY:Float = Math.POSITIVE_INFINITY;
|
||||
@ -674,15 +741,18 @@ class Skeleton {
|
||||
return _bounds;
|
||||
}
|
||||
|
||||
/** Increments the skeleton's {@link #time}. */
|
||||
public function update (delta:Float):Void {
|
||||
time += delta;
|
||||
}
|
||||
|
||||
/** Calls {@link PhysicsConstraint#translate(float, float)} for each physics constraint. */
|
||||
public function physicsTranslate (x:Float, y:Float):Void {
|
||||
for (physicsConstraint in physicsConstraints)
|
||||
physicsConstraint.translate(x, y);
|
||||
}
|
||||
|
||||
/** Calls {@link PhysicsConstraint#rotate(float, float, float)} for each physics constraint. */
|
||||
public function physicsRotate (x:Float, y:Float, degrees:Float):Void {
|
||||
for (physicsConstraint in physicsConstraints)
|
||||
physicsConstraint.rotate(x, y, degrees);
|
||||
|
||||
@ -35,29 +35,57 @@ import spine.animation.Animation;
|
||||
import spine.atlas.TextureAtlas;
|
||||
import spine.attachments.AtlasAttachmentLoader;
|
||||
|
||||
/** Stores the setup pose and all of the stateless data for a skeleton.
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-runtime-architecture#Data-objects">Data objects</a> in the Spine Runtimes
|
||||
* Guide. */
|
||||
class SkeletonData {
|
||||
/** May be null. */
|
||||
/** The skeleton's name, which by default is the name of the skeleton data file when possible, or null when a name hasn't been
|
||||
* set. */
|
||||
public var name:String;
|
||||
|
||||
/** The skeleton's bones, sorted parent first. The root bone is always the first bone. */
|
||||
public var bones:Array<BoneData> = new Array<BoneData>(); // Ordered parents first.
|
||||
/** The skeleton's slots in the setup pose draw order. */
|
||||
public var slots:Array<SlotData> = new Array<SlotData>(); // Setup pose draw order.
|
||||
/** All skins, including the default skin. */
|
||||
public var skins:Array<Skin> = new Array<Skin>();
|
||||
/** 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)}. */
|
||||
public var defaultSkin:Skin;
|
||||
/** The skeleton's events. */
|
||||
public var events:Array<EventData> = new Array<EventData>();
|
||||
/** The skeleton's animations. */
|
||||
public var animations:Array<Animation> = new Array<Animation>();
|
||||
/** The skeleton's IK constraints. */
|
||||
public var ikConstraints:Array<IkConstraintData> = new Array<IkConstraintData>();
|
||||
/** The skeleton's transform constraints. */
|
||||
public var transformConstraints:Array<TransformConstraintData> = new Array<TransformConstraintData>();
|
||||
/** The skeleton's path constraints. */
|
||||
public var pathConstraints:Array<PathConstraintData> = new Array<PathConstraintData>();
|
||||
/** The skeleton's physics constraints. */
|
||||
public var physicsConstraints:Array<PhysicsConstraintData> = new Array<PhysicsConstraintData>();
|
||||
/** The X coordinate of the skeleton's axis aligned bounding box in the setup pose. */
|
||||
public var x:Float = 0;
|
||||
/** The Y coordinate of the skeleton's axis aligned bounding box in the setup pose. */
|
||||
public var y:Float = 0;
|
||||
/** The width of the skeleton's axis aligned bounding box in the setup pose. */
|
||||
public var width:Float = 0;
|
||||
/** The height of the skeleton's axis aligned bounding box in the setup pose. */
|
||||
public var height:Float = 0;
|
||||
/** Baseline scale factor for applying physics and other effects based on distance to non-scalable properties, such as angle or
|
||||
* scale. Default is 100. */
|
||||
public var referenceScale:Float = 100;
|
||||
/** The Spine version used to export the skeleton data, or null. */
|
||||
public var version:String;
|
||||
/** The skeleton data hash. This value will change if any of the skeleton data has changed. */
|
||||
public var hash:String;
|
||||
/** The dopesheet FPS in Spine, or zero if nonessential data was not exported. */
|
||||
public var fps:Float = 0;
|
||||
/** The path to the images directory as defined in Spine, or null if nonessential data was not exported. */
|
||||
public var imagesPath:String;
|
||||
/** The path to the audio directory as defined in Spine, or null if nonessential data was not exported. */
|
||||
public var audioPath:String;
|
||||
|
||||
public static function from(data:Dynamic, atlas:TextureAtlas, scale:Float = 1.0):SkeletonData {
|
||||
@ -78,7 +106,9 @@ class SkeletonData {
|
||||
|
||||
// --- 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 function findBone(boneName:String):BoneData {
|
||||
if (boneName == null)
|
||||
throw new SpineException("boneName cannot be null.");
|
||||
@ -90,7 +120,8 @@ class SkeletonData {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @return -1 if the bone was not found. */
|
||||
/** Finds the index of a bone by comparing each bone's name.
|
||||
* @return -1 if the bone was not found. */
|
||||
public function findBoneIndex(boneName:String):Int {
|
||||
if (boneName == null)
|
||||
throw new SpineException("boneName cannot be null.");
|
||||
@ -103,7 +134,9 @@ class SkeletonData {
|
||||
|
||||
// --- 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 function findSlot(slotName:String):SlotData {
|
||||
if (slotName == null)
|
||||
throw new SpineException("slotName cannot be null.");
|
||||
@ -117,7 +150,9 @@ class SkeletonData {
|
||||
|
||||
// --- Skins.
|
||||
|
||||
/** @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 function findSkin(skinName:String):Skin {
|
||||
if (skinName == null)
|
||||
throw new SpineException("skinName cannot be null.");
|
||||
@ -130,7 +165,9 @@ class SkeletonData {
|
||||
|
||||
// --- 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 function findEvent(eventName:String):EventData {
|
||||
if (eventName == null)
|
||||
throw new SpineException("eventName cannot be null.");
|
||||
@ -143,7 +180,9 @@ class SkeletonData {
|
||||
|
||||
// --- 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 function findAnimation(animationName:String):Animation {
|
||||
if (animationName == null)
|
||||
throw new SpineException("animationName cannot be null.");
|
||||
@ -156,7 +195,9 @@ class SkeletonData {
|
||||
|
||||
// --- IK constraints.
|
||||
|
||||
/** @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 function findIkConstraint(constraintName:String):IkConstraintData {
|
||||
if (constraintName == null)
|
||||
throw new SpineException("constraintName cannot be null.");
|
||||
@ -169,7 +210,9 @@ class SkeletonData {
|
||||
|
||||
// --- Transform constraints.
|
||||
|
||||
/** @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 function findTransformConstraint(constraintName:String):TransformConstraintData {
|
||||
if (constraintName == null)
|
||||
throw new SpineException("constraintName cannot be null.");
|
||||
@ -180,7 +223,8 @@ class SkeletonData {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @return -1 if the transform constraint was not found. */
|
||||
/** Finds the index of a transform constraint by comparing each transform constraint's name.
|
||||
* @return -1 if the transform constraint was not found. */
|
||||
public function findTransformConstraintIndex(transformConstraintName:String):Int {
|
||||
if (transformConstraintName == null)
|
||||
throw new SpineException("transformConstraintName cannot be null.");
|
||||
@ -193,7 +237,9 @@ class SkeletonData {
|
||||
|
||||
// --- Path constraints.
|
||||
|
||||
/** @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 function findPathConstraint(constraintName:String):PathConstraintData {
|
||||
if (constraintName == null)
|
||||
throw new SpineException("constraintName cannot be null.");
|
||||
@ -205,7 +251,8 @@ class SkeletonData {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @return -1 if the path constraint was not found. */
|
||||
/** Finds the index of a path constraint by comparing each path constraint's name.
|
||||
* @return -1 if the path constraint was not found. */
|
||||
public function findPathConstraintIndex(pathConstraintName:String):Int {
|
||||
if (pathConstraintName == null)
|
||||
throw new SpineException("pathConstraintName cannot be null.");
|
||||
@ -218,7 +265,9 @@ class SkeletonData {
|
||||
|
||||
// --- Physics constraints.
|
||||
|
||||
/** @return May be null. */
|
||||
/** Finds a physics constraint by comparing each physics 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 function findPhysicsConstraint(constraintName:String):PhysicsConstraintData {
|
||||
if (constraintName == null)
|
||||
throw new SpineException("physicsConstraintName cannot be null.");
|
||||
@ -230,7 +279,8 @@ class SkeletonData {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @return -1 if the path constraint was not found. */
|
||||
/** Finds the index of a physics constraint by comparing each physics constraint's name.
|
||||
* @return -1 if the physics constraint was not found. */
|
||||
public function findPhysicsConstraintIndex(constraintName:String):Int {
|
||||
if (constraintName == null)
|
||||
throw new SpineException("constraintName cannot be null.");
|
||||
|
||||
@ -33,7 +33,10 @@ import haxe.ds.StringMap;
|
||||
import spine.attachments.Attachment;
|
||||
import spine.attachments.MeshAttachment;
|
||||
|
||||
/** Stores attachments by slot index and attachment name. */
|
||||
/** Stores attachments by slot index and attachment name.
|
||||
*
|
||||
* See SkeletonData {@link SkeletonData#defaultSkin}, Skeleton {@link Skeleton#skin}, and
|
||||
* <a href="https://esotericsoftware.com/spine-runtime-skins">Runtime skins</a> in the Spine Runtimes Guide. */
|
||||
class Skin {
|
||||
private var _name:String;
|
||||
private var _attachments:Array<StringMap<Attachment>> = new Array<StringMap<Attachment>>();
|
||||
@ -47,6 +50,7 @@ class Skin {
|
||||
_name = name;
|
||||
}
|
||||
|
||||
/** Adds an attachment to the skin for the specified slot index and name. */
|
||||
public function setAttachment(slotIndex:Int, name:String, attachment:Attachment):Void {
|
||||
if (attachment == null)
|
||||
throw new SpineException("attachment cannot be null.");
|
||||
@ -57,6 +61,7 @@ class Skin {
|
||||
_attachments[slotIndex].set(name, attachment);
|
||||
}
|
||||
|
||||
/** Adds all attachments, bones, and constraints from the specified skin to this skin. */
|
||||
public function addSkin(skin:Skin):Void {
|
||||
var contained:Bool = false;
|
||||
for (i in 0...skin.bones.length) {
|
||||
@ -92,6 +97,8 @@ class Skin {
|
||||
}
|
||||
}
|
||||
|
||||
/** Adds all bones and constraints and copies of all attachments from the specified skin to this skin. Mesh attachments are not
|
||||
* copied, instead a new linked mesh is created. The attachment copies can be modified without affecting the originals. */
|
||||
public function copySkin(skin:Skin):Void {
|
||||
var contained:Bool = false;
|
||||
var attachment:SkinEntry;
|
||||
@ -138,6 +145,7 @@ class Skin {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the attachment for the specified slot index and name, or null. */
|
||||
public function getAttachment(slotIndex:Int, name:String):Attachment {
|
||||
if (slotIndex >= _attachments.length)
|
||||
return null;
|
||||
@ -145,12 +153,14 @@ class Skin {
|
||||
return dictionary != null ? dictionary.get(name) : null;
|
||||
}
|
||||
|
||||
/** Removes the attachment in the skin for the specified slot index and name, if any. */
|
||||
public function removeAttachment(slotIndex:Int, name:String):Void {
|
||||
var dictionary:StringMap<Attachment> = _attachments[slotIndex];
|
||||
if (dictionary != null)
|
||||
dictionary.remove(name);
|
||||
}
|
||||
|
||||
/** Returns all attachments in this skin. */
|
||||
public function getAttachments():Array<SkinEntry> {
|
||||
var entries:Array<SkinEntry> = new Array<SkinEntry>();
|
||||
for (slotIndex in 0..._attachments.length) {
|
||||
@ -166,6 +176,7 @@ class Skin {
|
||||
return entries;
|
||||
}
|
||||
|
||||
/** Returns all attachments in this skin for the specified slot index. */
|
||||
public function getAttachmentsForSlot(slotIndex:Int):Array<SkinEntry> {
|
||||
var entries:Array<SkinEntry> = new Array<SkinEntry>();
|
||||
var attachments:StringMap<Attachment> = _attachments[slotIndex];
|
||||
@ -179,6 +190,7 @@ class Skin {
|
||||
return entries;
|
||||
}
|
||||
|
||||
/** Clears all attachments, bones, and constraints. */
|
||||
public function clear():Void {
|
||||
_attachments.resize(0);
|
||||
_bones.resize(0);
|
||||
@ -205,12 +217,14 @@ class Skin {
|
||||
|
||||
public var name(get, never):String;
|
||||
|
||||
/** The skin's name, which is unique across all skins in the skeleton. */
|
||||
private function get_name():String {
|
||||
return _name;
|
||||
}
|
||||
|
||||
public var color(get, never):Color;
|
||||
|
||||
/** The color of the skin as it was in Spine, or a default color if nonessential data was not exported. */
|
||||
private function get_color():Color {
|
||||
return _color;
|
||||
}
|
||||
|
||||
@ -31,8 +31,10 @@ package spine;
|
||||
|
||||
import spine.attachments.Attachment;
|
||||
|
||||
/** Stores an entry in the skin consisting of the slot index and the attachment name. */
|
||||
class SkinEntry {
|
||||
public var slotIndex:Int = 0;
|
||||
/** The name the attachment is associated with, equivalent to the skin placeholder name in the Spine editor. */
|
||||
public var name:String;
|
||||
public var attachment:Attachment;
|
||||
|
||||
|
||||
@ -32,20 +32,35 @@ package spine;
|
||||
import spine.attachments.Attachment;
|
||||
import 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. */
|
||||
class Slot {
|
||||
private var _data:SlotData;
|
||||
private var _bone:Bone;
|
||||
|
||||
/** The color used to tint the slot's attachment. If {@link #darkColor} is set, this is used as the light color for two
|
||||
* color tinting. */
|
||||
public var color:Color;
|
||||
/** The dark color used to tint the slot's attachment for two color tinting, or null if two color tinting is not used. The dark
|
||||
* color's alpha is not used. */
|
||||
public var darkColor:Color;
|
||||
|
||||
private var _attachment:Attachment;
|
||||
|
||||
/** The index of the texture region to display when the slot's attachment has a {@link Sequence}. -1 represents the
|
||||
* {@link Sequence#setupIndex}. */
|
||||
public var sequenceIndex = -1;
|
||||
|
||||
public var attachmentState:Int = 0;
|
||||
/** Values to deform the slot's attachment. For an unweighted mesh, the entries are local positions for each vertex. For a
|
||||
* weighted mesh, the entries are an offset for each vertex which will be added to the mesh's local vertex positions.
|
||||
* <p>
|
||||
* See {@link VertexAttachment#computeWorldVertices(Slot, int, int, float[], int, int)} and {@link DeformTimeline}. */
|
||||
|
||||
public var deform:Array<Float> = new Array<Float>();
|
||||
|
||||
/** Copy constructor. */
|
||||
public function new(data:SlotData, bone:Bone) {
|
||||
if (data == null)
|
||||
throw new SpineException("data cannot be null.");
|
||||
@ -58,34 +73,37 @@ class Slot {
|
||||
setToSetupPose();
|
||||
}
|
||||
|
||||
/** The slot's setup pose data. */
|
||||
public var data(get, never):SlotData;
|
||||
|
||||
private function get_data():SlotData {
|
||||
return _data;
|
||||
}
|
||||
|
||||
/** The bone this slot belongs to. */
|
||||
public var bone(get, never):Bone;
|
||||
|
||||
private function get_bone():Bone {
|
||||
return _bone;
|
||||
}
|
||||
|
||||
/** The skeleton this slot belongs to. */
|
||||
public var skeleton(get, never):Skeleton;
|
||||
|
||||
private function get_skeleton():Skeleton {
|
||||
return _bone.skeleton;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
/** The current attachment for the slot, or null if the slot has no attachment. */
|
||||
public var attachment(get, set):Attachment;
|
||||
|
||||
private function get_attachment():Attachment {
|
||||
return _attachment;
|
||||
}
|
||||
|
||||
/** Sets the slot's attachment and, if the attachment changed, resets {@link #attachmentTime} and clears the {@link #deform}.
|
||||
* The deform is not cleared if the old attachment has the same {@link VertexAttachment#getDeformAttachment()} as the specified attachment.
|
||||
* @param attachment May be null. */
|
||||
/** Sets the slot's attachment and, if the attachment changed, resets {@link #sequenceIndex} and clears the {@link #deform}.
|
||||
* The deform is not cleared if the old attachment has the same {@link VertexAttachment#timelineAttachment} as the
|
||||
* specified attachment. */
|
||||
public function set_attachment(attachmentNew:Attachment):Attachment {
|
||||
if (attachment == attachmentNew)
|
||||
return attachmentNew;
|
||||
@ -99,6 +117,7 @@ class Slot {
|
||||
return attachmentNew;
|
||||
}
|
||||
|
||||
/** Sets this slot to the setup pose. */
|
||||
public function setToSetupPose():Void {
|
||||
color.setFromColor(data.color);
|
||||
if (darkColor != null)
|
||||
|
||||
@ -29,15 +29,23 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** Stores the setup pose for a {@link Slot}. */
|
||||
class SlotData {
|
||||
private var _index:Int;
|
||||
private var _name:String;
|
||||
private var _boneData:BoneData;
|
||||
|
||||
/** The color used to tint the slot's attachment. If {@link #getDarkColor()} is set, this is used as the light color for two
|
||||
* color tinting. */
|
||||
public var color:Color = new Color(1, 1, 1, 1);
|
||||
/** The dark color used to tint the slot's attachment for two color tinting, or null if two color tinting is not used. The dark
|
||||
* color's alpha is not used. */
|
||||
public var darkColor:Color = null;
|
||||
/** The name of the attachment that is visible for this slot in the setup pose, or null if no attachment is visible. */
|
||||
public var attachmentName:String;
|
||||
/** The blend mode for drawing the slot's attachment. */
|
||||
public var blendMode:BlendMode = BlendMode.normal;
|
||||
/** False if the slot was hidden in Spine and nonessential data was exported. Does not affect runtime rendering. */
|
||||
public var visible:Bool = true;
|
||||
|
||||
public function new(index:Int, name:String, boneData:BoneData) {
|
||||
@ -52,18 +60,21 @@ class SlotData {
|
||||
_boneData = boneData;
|
||||
}
|
||||
|
||||
/** The index of the slot in {@link Skeleton#getSlots()}. */
|
||||
public var index(get, never):Int;
|
||||
|
||||
private function get_index():Int {
|
||||
return _index;
|
||||
}
|
||||
|
||||
/** The name of the slot, which is unique across all slots in the skeleton. */
|
||||
public var name(get, never):String;
|
||||
|
||||
private function get_name():String {
|
||||
return _name;
|
||||
}
|
||||
|
||||
/** The bone this slot belongs to. */
|
||||
public var boneData(get, never):BoneData;
|
||||
|
||||
private function get_boneData():BoneData {
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** Controls how bones after the first bone are positioned along the path.
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-path-constraints#Spacing-mode">Spacing mode</a> in the Spine User Guide. */
|
||||
class SpacingMode {
|
||||
public static var length(default, never):SpacingMode = new SpacingMode("length");
|
||||
public static var fixed(default, never):SpacingMode = new SpacingMode("fixed");
|
||||
|
||||
@ -29,22 +29,34 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** 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="https://esotericsoftware.com/spine-transform-constraints">Transform constraints</a> in the Spine User Guide. */
|
||||
class TransformConstraint implements Updatable {
|
||||
private var _data:TransformConstraintData;
|
||||
private var _bones:Array<Bone>;
|
||||
|
||||
/** The target bone whose world transform will be copied to the constrained bones. */
|
||||
public var target:Bone;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. */
|
||||
public var mixRotate:Float = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. */
|
||||
public var mixX:Float = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. */
|
||||
public var mixY:Float = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained scale X. */
|
||||
public var mixScaleX:Float = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained scale Y. */
|
||||
public var mixScaleY:Float = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained shear Y. */
|
||||
public var mixShearY:Float = 0;
|
||||
|
||||
private var _temp:Array<Float> = new Array<Float>();
|
||||
|
||||
public var active:Bool = false;
|
||||
|
||||
/** Copy constructor. */
|
||||
public function new(data:TransformConstraintData, skeleton:Skeleton) {
|
||||
if (data == null)
|
||||
throw new SpineException("data cannot be null.");
|
||||
@ -80,6 +92,7 @@ class TransformConstraint implements Updatable {
|
||||
mixShearY = data.mixShearY;
|
||||
}
|
||||
|
||||
/** Applies the constraint to the constrained bones. */
|
||||
public function update(physics:Physics):Void {
|
||||
if (mixRotate == 0 && mixX == 0 && mixY == 0 && mixScaleX == 0 && mixScaleY == 0 && mixShearY == 0)
|
||||
return;
|
||||
@ -271,12 +284,14 @@ class TransformConstraint implements Updatable {
|
||||
}
|
||||
}
|
||||
|
||||
/** The transform constraint's setup pose data. */
|
||||
public var data(get, never):TransformConstraintData;
|
||||
|
||||
private function get_data():TransformConstraintData {
|
||||
return _data;
|
||||
}
|
||||
|
||||
/** The bones that will be modified by this transform constraint. */
|
||||
public var bones(get, never):Array<Bone>;
|
||||
|
||||
private function get_bones():Array<Bone> {
|
||||
|
||||
@ -29,21 +29,37 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** Stores the setup pose for a {@link TransformConstraint}.
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-transform-constraints">Transform constraints</a> in the Spine User Guide. */
|
||||
class TransformConstraintData extends ConstraintData {
|
||||
private var _bones:Array<BoneData> = new Array<BoneData>();
|
||||
|
||||
/** The target bone whose world transform will be copied to the constrained bones. */
|
||||
public var target:BoneData;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. */
|
||||
public var mixRotate:Float = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. */
|
||||
public var mixX:Float = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. */
|
||||
public var mixY:Float = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained scale X. */
|
||||
public var mixScaleX:Float = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained scale Y. */
|
||||
public var mixScaleY:Float = 0;
|
||||
/** A percentage (0-1) that controls the mix between the constrained and unconstrained shear Y. */
|
||||
public var mixShearY:Float = 0;
|
||||
/** An offset added to the constrained bone rotation. */
|
||||
public var offsetRotation:Float = 0;
|
||||
/** An offset added to the constrained bone X translation. */
|
||||
public var offsetX:Float = 0;
|
||||
/** An offset added to the constrained bone Y translation. */
|
||||
public var offsetY:Float = 0;
|
||||
/** An offset added to the constrained bone scaleX. */
|
||||
public var offsetScaleX:Float = 0;
|
||||
/** An offset added to the constrained bone scaleY. */
|
||||
public var offsetScaleY:Float = 0;
|
||||
/** An offset added to the constrained bone shearY. */
|
||||
public var offsetShearY:Float = 0;
|
||||
public var relative:Bool = false;
|
||||
public var local:Bool = false;
|
||||
@ -52,6 +68,7 @@ class TransformConstraintData extends ConstraintData {
|
||||
super(name, 0, false);
|
||||
}
|
||||
|
||||
/** The bones that will be modified by this transform constraint. */
|
||||
public var bones(get, never):Array<BoneData>;
|
||||
|
||||
private function get_bones():Array<BoneData> {
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/**
|
||||
* Triangulator class used for polygon triangulation and decomposition.
|
||||
*/
|
||||
class Triangulator {
|
||||
private var convexPolygons:Array<Array<Float>> = new Array<Array<Float>>();
|
||||
private var convexPolygonsIndices:Array<Array<Int>> = new Array<Array<Int>>();
|
||||
@ -44,6 +47,11 @@ class Triangulator {
|
||||
|
||||
public function new() {}
|
||||
|
||||
/**
|
||||
* Triangulates a convex or concave polygon.
|
||||
* @param vertices List of polygon vertices in x,y order.
|
||||
* @return Indices of triangle vertices in clockwise order.
|
||||
*/
|
||||
public function triangulate(vertices:Array<Float>):Array<Int> {
|
||||
var vertexCount:Int = vertices.length >> 1;
|
||||
|
||||
@ -129,6 +137,12 @@ class Triangulator {
|
||||
return triangles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decomposes a polygon into convex polygons.
|
||||
* @param vertices List of polygon vertices in x,y order.
|
||||
* @param triangles Indices of triangle vertices in clockwise order.
|
||||
* @return List of convex polygons.
|
||||
*/
|
||||
public function decompose(vertices:Array<Float>, triangles:Array<Int>):Array<Array<Float>> {
|
||||
for (i in 0...convexPolygons.length) {
|
||||
this.polygonPool.free(convexPolygons[i]);
|
||||
|
||||
@ -29,8 +29,17 @@
|
||||
|
||||
package spine;
|
||||
|
||||
/** The interface for items updated by {@link Skeleton#updateWorldTransform(Physics)}. */
|
||||
interface Updatable {
|
||||
/** @param physics Determines how physics and other non-deterministic updates are applied. */
|
||||
function update(physics:Physics):Void;
|
||||
|
||||
/** Returns false when this item won't be updated by
|
||||
* {@link Skeleton#updateWorldTransform(Physics)} because a skin is required and the
|
||||
* {@link Skeleton#getSkin() active skin} does not contain this item.
|
||||
* @see Skin#getBones()
|
||||
* @see Skin#getConstraints()
|
||||
* @see BoneData#getSkinRequired()
|
||||
* @see ConstraintData#getSkinRequired() */
|
||||
function isActive():Bool;
|
||||
}
|
||||
|
||||
@ -33,6 +33,7 @@ import spine.Event;
|
||||
import spine.Skeleton;
|
||||
import spine.Slot;
|
||||
|
||||
/** Changes the alpha for a slot's {@link Slot#color}. */
|
||||
class AlphaTimeline extends CurveTimeline1 implements SlotTimeline {
|
||||
private static inline var ENTRIES:Int = 4;
|
||||
private static inline var R:Float = 1;
|
||||
|
||||
@ -33,11 +33,14 @@ import haxe.ds.StringMap;
|
||||
import spine.Event;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Stores a list of timelines to animate a skeleton's pose over time. */
|
||||
class Animation {
|
||||
private var _name:String;
|
||||
private var _timelines:Array<Timeline>;
|
||||
private var _timelineIds:StringMap<Bool> = new StringMap<Bool>();
|
||||
|
||||
/** The duration of the animation in seconds, which is usually the highest time of all frames in the timeline. The duration is
|
||||
* used to know when it has completed and when it should loop back to the start. */
|
||||
public var duration:Float = 0;
|
||||
|
||||
public function new(name:String, timelines:Array<Timeline>, duration:Float) {
|
||||
@ -61,6 +64,7 @@ class Animation {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns true if this animation contains a timeline with any of the specified property IDs. */
|
||||
public function hasTimeline(ids:Array<String>):Bool {
|
||||
for (id in ids) {
|
||||
if (_timelineIds.exists(id))
|
||||
@ -69,7 +73,26 @@ class Animation {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Poses the skeleton at the specified time for this animation. */
|
||||
/** Applies the animation's timelines to the specified skeleton.
|
||||
* <p>
|
||||
* See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}.
|
||||
* @param skeleton The skeleton the animation is being applied to. This provides access to the bones, slots, and other skeleton
|
||||
* components the timelines may change.
|
||||
* @param lastTime The last time in seconds this animation was applied. Some timelines trigger only at specific times rather
|
||||
* than every frame. Pass -1 the first time an animation is applied to ensure frame 0 is triggered.
|
||||
* @param time The time in seconds the skeleton is being posed for. Most timelines find the frame before and the frame after
|
||||
* this time and interpolate between the frame values. If beyond the {@link #getDuration()} and <code>loop</code> is
|
||||
* true then the animation will repeat, else the last frame will be applied.
|
||||
* @param loop If true, the animation repeats after the {@link #getDuration()}.
|
||||
* @param events If any events are fired, they are added to this list. Can be null to ignore fired events or if no timelines
|
||||
* fire events.
|
||||
* @param alpha 0 applies the current or setup values (depending on <code>blend</code>). 1 applies the timeline values. Between
|
||||
* 0 and 1 applies values between the current or setup values and the timeline values. 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 (layering).
|
||||
* @param blend Controls how mixing is applied when <code>alpha</code> < 1.
|
||||
* @param direction Indicates whether the timelines are mixing in or out. Used by timelines which perform instant transitions,
|
||||
* such as {@link DrawOrderTimeline} or {@link AttachmentTimeline}. */
|
||||
public function apply(skeleton:Skeleton, lastTime:Float, time:Float, loop:Bool, events:Array<Event>, alpha:Float, blend:MixBlend,
|
||||
direction:MixDirection):Void {
|
||||
if (skeleton == null)
|
||||
@ -88,6 +111,7 @@ class Animation {
|
||||
|
||||
public var name(get, never):String;
|
||||
|
||||
/** The animation's name, which is unique across all animations in the skeleton. */
|
||||
private function get_name():String {
|
||||
return _name;
|
||||
}
|
||||
@ -98,6 +122,7 @@ class Animation {
|
||||
|
||||
public var timelines(get, never):Array<Timeline>;
|
||||
|
||||
/** If the returned array or the timelines it contains are modified, {@link #setTimelines(Array)} must be called. */
|
||||
private function get_timelines():Array<Timeline> {
|
||||
return _timelines;
|
||||
}
|
||||
|
||||
@ -32,22 +32,28 @@ package spine.animation;
|
||||
import haxe.ds.StringMap;
|
||||
import spine.SkeletonData;
|
||||
|
||||
/** Stores mix (crossfade) durations to be applied when {@link AnimationState} animations are changed. */
|
||||
class AnimationStateData {
|
||||
private var _skeletonData:SkeletonData;
|
||||
private var animationToMixTime:StringMap<Float> = new StringMap<Float>();
|
||||
|
||||
/** The mix duration to use when no mix duration has been defined between two animations. */
|
||||
public var defaultMix:Float = 0;
|
||||
|
||||
public function new(skeletonData:SkeletonData) {
|
||||
_skeletonData = skeletonData;
|
||||
}
|
||||
|
||||
/** The SkeletonData to look up animations when they are specified by name. */
|
||||
public var skeletonData(get, never):SkeletonData;
|
||||
|
||||
private function get_skeletonData():SkeletonData {
|
||||
return _skeletonData;
|
||||
}
|
||||
|
||||
/** Sets a mix duration by animation name.
|
||||
*
|
||||
* See {@link #setMix(Animation, Animation, float)}. */
|
||||
public function setMixByName(fromName:String, toName:String, duration:Float):Void {
|
||||
var from:Animation = _skeletonData.findAnimation(fromName);
|
||||
if (from == null)
|
||||
@ -58,6 +64,9 @@ class AnimationStateData {
|
||||
setMix(from, to, duration);
|
||||
}
|
||||
|
||||
/** Sets the mix duration when changing from the specified animation to the other.
|
||||
*
|
||||
* See {@link TrackEntry#mixDuration}. */
|
||||
public function setMix(from:Animation, to:Animation, duration:Float):Void {
|
||||
if (from == null)
|
||||
throw new SpineException("from cannot be null.");
|
||||
@ -66,6 +75,8 @@ class AnimationStateData {
|
||||
animationToMixTime.set(from.name + ":" + to.name, duration);
|
||||
}
|
||||
|
||||
/** Returns the mix duration to use when changing from the specified animation to the other, or the {@link #defaultMix} if
|
||||
* no mix duration has been set. */
|
||||
public function getMix(from:Animation, to:Animation):Float {
|
||||
if (animationToMixTime.exists(from.name + ":" + to.name))
|
||||
return animationToMixTime.get(from.name + ":" + to.name);
|
||||
|
||||
@ -33,10 +33,11 @@ import spine.Event;
|
||||
import spine.Skeleton;
|
||||
import spine.Slot;
|
||||
|
||||
/** Changes a slot's attachment. */
|
||||
class AttachmentTimeline extends Timeline implements SlotTimeline {
|
||||
public var slotIndex:Int = 0;
|
||||
|
||||
/** The attachment name for each key frame. May contain null values to clear the attachment. */
|
||||
/** The attachment name for each frame. May contain null values to clear the attachment. */
|
||||
public var attachmentNames:Array<String>;
|
||||
|
||||
public function new(frameCount:Int, slotIndex:Int) {
|
||||
@ -54,7 +55,9 @@ class AttachmentTimeline extends Timeline implements SlotTimeline {
|
||||
return slotIndex;
|
||||
}
|
||||
|
||||
/** Sets the time in seconds and the attachment name for the specified key frame. */
|
||||
/** Sets the time and attachment name for the specified frame.
|
||||
* @param frame Between 0 and <code>frameCount</code>, inclusive.
|
||||
* @param time The frame time in seconds. */
|
||||
public function setFrame(frame:Int, time:Float, attachmentName:String):Void {
|
||||
frames[frame] = time;
|
||||
attachmentNames[frame] = attachmentName;
|
||||
|
||||
@ -29,6 +29,8 @@
|
||||
|
||||
package spine.animation;
|
||||
|
||||
/** An interface for timelines which change the property of a bone. */
|
||||
interface BoneTimeline {
|
||||
/** The index of the bone in {@link Skeleton#getBones()} that will be changed when this timeline is applied. */
|
||||
function getBoneIndex():Int;
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
|
||||
package spine.animation;
|
||||
|
||||
/** Base class for frames that use an interpolation bezier curve. */
|
||||
/** The base class for timelines that interpolate between frame values using stepped, linear, or a Bezier curve. */
|
||||
class CurveTimeline extends Timeline {
|
||||
private static inline var LINEAR:Int = 0;
|
||||
private static inline var STEPPED:Int = 1;
|
||||
@ -38,6 +38,8 @@ class CurveTimeline extends Timeline {
|
||||
|
||||
private var curves:Array<Float>; // type, x, y, ...
|
||||
|
||||
/** @param bezierCount The maximum number of Bezier curves. See {@link #shrink(int)}.
|
||||
* @param propertyIds Unique identifiers for the properties the timeline modifies. */
|
||||
public function new(frameCount:Int, bezierCount:Int, propertyIds:Array<String>) {
|
||||
super(frameCount, propertyIds);
|
||||
curves = new Array<Float>();
|
||||
@ -45,10 +47,14 @@ class CurveTimeline extends Timeline {
|
||||
curves[frameCount - 1] = STEPPED;
|
||||
}
|
||||
|
||||
/** Sets the specified frame to linear interpolation.
|
||||
* @param frame Between 0 and <code>frameCount - 1</code>, inclusive. */
|
||||
public function setLinear(frame:Int):Void {
|
||||
curves[frame] = LINEAR;
|
||||
}
|
||||
|
||||
/** Sets the specified frame to stepped interpolation.
|
||||
* @param frame Between 0 and <code>frameCount - 1</code>, inclusive. */
|
||||
public function setStepped(frame:Int):Void {
|
||||
curves[frame] = STEPPED;
|
||||
}
|
||||
@ -65,7 +71,7 @@ class CurveTimeline extends Timeline {
|
||||
* @param bezier The ordinal of this Bezier curve for this timeline, between 0 and <code>bezierCount - 1</code> (specified
|
||||
* in the constructor), inclusive.
|
||||
* @param frame Between 0 and <code>frameCount - 1</code>, inclusive.
|
||||
* @param value The index of the value for this frame that this curve is used for.
|
||||
* @param value The index of the value for the frame this curve is used for.
|
||||
* @param time1 The time for the first key.
|
||||
* @param value1 The value for the first key.
|
||||
* @param cx1 The time for the first Bezier handle.
|
||||
@ -105,7 +111,7 @@ class CurveTimeline extends Timeline {
|
||||
/** Returns the Bezier interpolated value for the specified time.
|
||||
* @param frameIndex The index into {@link #getFrames()} for the values of the frame before <code>time</code>.
|
||||
* @param valueOffset The offset from <code>frameIndex</code> to the value this curve is used for.
|
||||
* @param i The index of the Bezier segments. See {@link #getCurveType(int)}. */
|
||||
* @param i The index of the Bezier segments. See {@link #getCurveType}. */
|
||||
public function getBezierValue(time:Float, frameIndex:Int, valueOffset:Int, i:Int):Float {
|
||||
var x:Float, y:Float;
|
||||
if (curves[i] > time) {
|
||||
|
||||
@ -44,7 +44,7 @@ class CurveTimeline1 extends CurveTimeline {
|
||||
return ENTRIES;
|
||||
}
|
||||
|
||||
/** Sets the time and values for the specified frame.
|
||||
/** Sets the time and value for the specified frame.
|
||||
* @param frame Between 0 and <code>frameCount</code>, inclusive.
|
||||
* @param time The frame time in seconds. */
|
||||
public function setFrame(frame:Int, time:Float, value1:Float):Void {
|
||||
|
||||
@ -36,13 +36,16 @@ import spine.Event;
|
||||
import spine.Skeleton;
|
||||
import spine.Slot;
|
||||
|
||||
/** Changes a slot's {@link Slot#getDeform()} to deform a {@link VertexAttachment}. */
|
||||
class DeformTimeline extends CurveTimeline implements SlotTimeline {
|
||||
public var slotIndex:Int = 0;
|
||||
|
||||
/** The attachment that will be deformed. */
|
||||
/** The attachment that will be deformed.
|
||||
* <p>
|
||||
* See {@link VertexAttachment#getTimelineAttachment()}. */
|
||||
public var attachment:VertexAttachment;
|
||||
|
||||
/** The vertices for each key frame. */
|
||||
/** The vertices for each frame. */
|
||||
public var vertices:Array<Array<Float>>;
|
||||
|
||||
public function new(frameCount:Int, bezierCount:Int, slotIndex:Int, attachment:VertexAttachment) {
|
||||
@ -61,14 +64,25 @@ class DeformTimeline extends CurveTimeline implements SlotTimeline {
|
||||
return slotIndex;
|
||||
}
|
||||
|
||||
/** 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. */
|
||||
/** Sets the time and vertices for the specified frame.
|
||||
* @param frame Between 0 and <code>frameCount</code>, inclusive.
|
||||
* @param time The frame time in seconds.
|
||||
* @param verticesOrDeform Vertex positions for an unweighted VertexAttachment, or deform offsets if it has weights. */
|
||||
public function setFrame(frame:Int, time:Float, verticesOrDeform:Array<Float>):Void {
|
||||
frames[frame] = time;
|
||||
vertices[frame] = verticesOrDeform;
|
||||
}
|
||||
|
||||
/** @param value1 Ignored (0 is used for a deform timeline).
|
||||
/** @param bezier The bezier index.
|
||||
* @param frame The frame index.
|
||||
* @param value Ignored (0 is used for a deform timeline).
|
||||
* @param time1 The first time.
|
||||
* @param value1 Ignored (0 is used for a deform timeline).
|
||||
* @param cx1 The first control point x.
|
||||
* @param cy1 The first control point y.
|
||||
* @param cx2 The second control point x.
|
||||
* @param cy2 The second control point y.
|
||||
* @param time2 The second time.
|
||||
* @param value2 Ignored (1 is used for a deform timeline). */
|
||||
public override function setBezier(bezier:Int, frame:Int, value:Float, time1:Float, value1:Float, cx1:Float, cy1:Float, cx2:Float, cy2:Float, time2:Float,
|
||||
value2:Float):Void {
|
||||
@ -98,6 +112,8 @@ class DeformTimeline extends CurveTimeline implements SlotTimeline {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the interpolated percentage for the specified time.
|
||||
* @param frame The frame before <code>time</code>. */
|
||||
private function getCurvePercent(time:Float, frame:Int):Float {
|
||||
var i:Int = Std.int(curves[frame]);
|
||||
var x:Float;
|
||||
|
||||
@ -33,7 +33,9 @@ import spine.Event;
|
||||
import spine.Skeleton;
|
||||
import spine.Slot;
|
||||
|
||||
/** Changes a skeleton's {@link Skeleton#drawOrder}. */
|
||||
class DrawOrderTimeline extends Timeline {
|
||||
/** The draw order for each frame. See {@link #setFrame(Int, Float, Array<Int>)}. */
|
||||
public var drawOrders:Array<Array<Int>>;
|
||||
|
||||
public function new(frameCount:Int) {
|
||||
@ -48,7 +50,10 @@ class DrawOrderTimeline extends Timeline {
|
||||
return frames.length;
|
||||
}
|
||||
|
||||
/** Sets the time and value of the specified keyframe. */
|
||||
/** Sets the time and draw order for the specified frame.
|
||||
* @param frame Between 0 and <code>frameCount</code>, inclusive.
|
||||
* @param time The frame time in seconds.
|
||||
* @param drawOrder For each slot in {@link Skeleton#slots}, the index of the slot in the new draw order. May be null to use setup pose draw order. */
|
||||
public function setFrame(frame:Int, time:Float, drawOrder:Array<Int>):Void {
|
||||
frames[frame] = time;
|
||||
drawOrders[frame] = drawOrder;
|
||||
|
||||
@ -31,6 +31,9 @@ package spine.animation;
|
||||
|
||||
import spine.Event;
|
||||
|
||||
/**
|
||||
* Stores events raised by AnimationState and allows them to be processed later.
|
||||
*/
|
||||
class EventQueue {
|
||||
private var objects:Array<Dynamic>;
|
||||
private var animationState:AnimationState;
|
||||
|
||||
@ -33,7 +33,9 @@ import spine.animation.Timeline;
|
||||
import spine.Event;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Fires an {@link Event} when specific animation times are reached. */
|
||||
class EventTimeline extends Timeline {
|
||||
/** The event for each frame. */
|
||||
public var events:Array<Event>;
|
||||
|
||||
public function new(frameCount:Int) {
|
||||
@ -46,13 +48,15 @@ class EventTimeline extends Timeline {
|
||||
return frames.length;
|
||||
}
|
||||
|
||||
/** Sets the time in seconds and the event for the specified key frame. */
|
||||
/** Sets the time and event for the specified frame.
|
||||
* @param frame Between 0 and <code>frameCount</code>, inclusive.
|
||||
* @param event The event to set for the frame. */
|
||||
public function setFrame(frame:Int, event:Event):Void {
|
||||
frames[frame] = event.time;
|
||||
events[frame] = event;
|
||||
}
|
||||
|
||||
/** Fires events for frames > `lastTime` and <= `time`. */
|
||||
/** Fires events for frames > <code>lastTime</code> and <= <code>time</code>. */
|
||||
public override function apply(skeleton:Skeleton, lastTime:Float, time:Float, events:Array<Event>, alpha:Float, blend:MixBlend,
|
||||
direction:MixDirection):Void {
|
||||
if (events == null)
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
|
||||
package spine.animation;
|
||||
|
||||
/**
|
||||
* Animation state event type.
|
||||
*/
|
||||
class EventType {
|
||||
public static var start(default, never):EventType = new EventType();
|
||||
public static var interrupt(default, never):EventType = new EventType();
|
||||
|
||||
@ -33,6 +33,8 @@ import spine.Event;
|
||||
import spine.IkConstraint;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Changes an IK constraint's {@link IkConstraint#mix}, {@link IkConstraint#softness},
|
||||
* {@link IkConstraint#bendDirection}, {@link IkConstraint#stretch}, and {@link IkConstraint#compress}. */
|
||||
class IkConstraintTimeline extends CurveTimeline {
|
||||
private static inline var ENTRIES:Int = 6;
|
||||
private static inline var MIX:Int = 1;
|
||||
@ -41,7 +43,8 @@ class IkConstraintTimeline extends CurveTimeline {
|
||||
private static inline var COMPRESS:Int = 4;
|
||||
private static inline var STRETCH:Int = 5;
|
||||
|
||||
/** The index of the IK constraint in {@link Skeleton#ikConstraints} when this timeline is applied. */
|
||||
/** The index of the IK constraint in {@link Skeleton#ikConstraints} that will be changed when this timeline is
|
||||
* applied. */
|
||||
public var constraintIndex:Int = 0;
|
||||
|
||||
public function new(frameCount:Int, bezierCount:Int, ikConstraintIndex:Int) {
|
||||
@ -53,7 +56,14 @@ class IkConstraintTimeline extends CurveTimeline {
|
||||
return ENTRIES;
|
||||
}
|
||||
|
||||
/** Sets the time in seconds, mix, softness, bend direction, compress, and stretch for the specified key frame. */
|
||||
/** Sets the time, mix, softness, bend direction, compress, and stretch for the specified frame.
|
||||
* @param frame Between 0 and <code>frameCount</code>, inclusive.
|
||||
* @param time The frame time in seconds.
|
||||
* @param mix The mix value.
|
||||
* @param softness The softness value.
|
||||
* @param bendDirection 1 or -1.
|
||||
* @param compress Whether to compress.
|
||||
* @param stretch Whether to stretch. */
|
||||
public function setFrame(frame:Int, time:Float, mix:Float, softness:Float, bendDirection:Int, compress:Bool, stretch:Bool):Void {
|
||||
frame *= ENTRIES;
|
||||
frames[frame] = time;
|
||||
|
||||
@ -33,6 +33,7 @@ import spine.Bone;
|
||||
import spine.Event;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Changes a bone's {@link Bone#getInherit()}. */
|
||||
class InheritTimeline extends Timeline implements BoneTimeline {
|
||||
public static inline var ENTRIES:Int = 2;
|
||||
private static inline var INHERIT:Int = 1;
|
||||
@ -52,6 +53,10 @@ class InheritTimeline extends Timeline implements BoneTimeline {
|
||||
return boneIndex;
|
||||
}
|
||||
|
||||
/** Sets the inherit value for the specified frame.
|
||||
* @param frame Between 0 and <code>frameCount</code>, inclusive.
|
||||
* @param time The frame time in seconds.
|
||||
* @param inherit The inherit value for this frame. */
|
||||
public function setFrame(frame:Int, time:Float, inherit: Inherit):Void {
|
||||
frame *= ENTRIES;
|
||||
frames[frame] = time;
|
||||
|
||||
@ -29,6 +29,14 @@
|
||||
|
||||
package spine.animation;
|
||||
|
||||
/** The interface to implement for receiving TrackEntry events. It is always safe to call AnimationState methods when receiving
|
||||
* events.
|
||||
* <p>
|
||||
* TrackEntry events are collected during {@link AnimationState#update(float)} and {@link AnimationState#apply(Skeleton)} and
|
||||
* fired only after those methods are finished.
|
||||
* <p>
|
||||
* See TrackEntry {@link TrackEntry#setListener(AnimationStateListener)} and AnimationState
|
||||
* {@link AnimationState#addListener(AnimationStateListener)}. */
|
||||
class Listeners {
|
||||
private var _listeners:Array<TrackEntry->Void>;
|
||||
|
||||
@ -42,6 +50,8 @@ class Listeners {
|
||||
_listeners = new Array<TrackEntry->Void>();
|
||||
}
|
||||
|
||||
/** Invoked when this entry has been set as the current entry. {@link #end(TrackEntry)} will occur when this entry will no
|
||||
* longer be applied. */
|
||||
public function invoke(entry:TrackEntry) {
|
||||
for (listener in _listeners) {
|
||||
listener(entry);
|
||||
@ -65,6 +75,14 @@ class Listeners {
|
||||
}
|
||||
}
|
||||
|
||||
/** The interface to implement for receiving TrackEntry events. It is always safe to call AnimationState methods when receiving
|
||||
* events.
|
||||
* <p>
|
||||
* TrackEntry events are collected during {@link AnimationState#update(float)} and {@link AnimationState#apply(Skeleton)} and
|
||||
* fired only after those methods are finished.
|
||||
* <p>
|
||||
* See TrackEntry {@link TrackEntry#setListener(AnimationStateListener)} and AnimationState
|
||||
* {@link AnimationState#addListener(AnimationStateListener)}. */
|
||||
class EventListeners {
|
||||
private var _listeners:Array<TrackEntry->Event->Void>;
|
||||
|
||||
@ -78,6 +96,11 @@ class EventListeners {
|
||||
_listeners = new Array<TrackEntry->Event->Void>();
|
||||
}
|
||||
|
||||
/** Invoked when this entry's animation triggers an event. This may occur during mixing (after
|
||||
* {@link #interrupt(TrackEntry)}), see {@link TrackEntry#eventThreshold}.
|
||||
* <p>
|
||||
* Because this event is triggered at the end of {@link AnimationState#apply(Skeleton)}, any animations set in response to
|
||||
* the event won't be applied until the next time the AnimationState is applied. */
|
||||
public function invoke(entry:TrackEntry, event:Event) {
|
||||
for (listener in _listeners) {
|
||||
listener(entry, event);
|
||||
|
||||
@ -29,6 +29,10 @@
|
||||
|
||||
package spine.animation;
|
||||
|
||||
/** Controls how timeline values are mixed with setup pose values or current pose values when a timeline is applied with
|
||||
* <code>alpha</code> < 1.
|
||||
*
|
||||
* See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}. */
|
||||
class MixBlend {
|
||||
public var ordinal:Int = 0;
|
||||
|
||||
@ -36,8 +40,25 @@ class MixBlend {
|
||||
this.ordinal = ordinal;
|
||||
}
|
||||
|
||||
/** Transitions from the setup value to the timeline value (the current value is not used). Before the first frame, the
|
||||
* setup value is set. */
|
||||
public static var setup(default, never):MixBlend = new MixBlend(0);
|
||||
/** Transitions from the current value to the timeline value. Before the first frame, transitions from the current value to
|
||||
* the setup value. Timelines which perform instant transitions, such as {@link DrawOrderTimeline} or
|
||||
* {@link AttachmentTimeline}, use the setup value before the first frame.
|
||||
*
|
||||
* <code>first</code> is intended for the first animations applied, not for animations layered on top of those. */
|
||||
public static var first(default, never):MixBlend = new MixBlend(1);
|
||||
/** Transitions from the current value to the timeline value. No change is made before the first frame (the current value is
|
||||
* kept until the first frame).
|
||||
*
|
||||
* <code>replace</code> is intended for animations layered on top of others, not for the first animations applied. */
|
||||
public static var replace(default, never):MixBlend = new MixBlend(2);
|
||||
/** Transitions from the current value to the current value plus the timeline value. No change is made before the first
|
||||
* frame (the current value is kept until the first frame).
|
||||
*
|
||||
* <code>add</code> is intended for animations layered on top of others, not for the first animations applied. Properties
|
||||
* set by additive animations must be set manually or by another animation before applying the additive animations, else the
|
||||
* property values will increase each time the additive animations are applied. */
|
||||
public static var add(default, never):MixBlend = new MixBlend(3);
|
||||
}
|
||||
|
||||
@ -29,6 +29,10 @@
|
||||
|
||||
package spine.animation;
|
||||
|
||||
/** Indicates whether a timeline's alpha is mixing out over time toward 0 (the setup or current pose value) or
|
||||
* mixing in toward 1 (the timeline's value). Some timelines use this to decide how values are applied.
|
||||
*
|
||||
* See Timeline apply(Skeleton, float, float, Array, float, MixBlend, MixDirection). */
|
||||
class MixDirection {
|
||||
public var ordinal:Int = 0;
|
||||
|
||||
|
||||
@ -33,13 +33,16 @@ import spine.Event;
|
||||
import spine.PathConstraint;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Changes a path constraint's {@link PathConstraint#getMixRotate()}, {@link PathConstraint#getMixX()}, and
|
||||
* {@link PathConstraint#getMixY()}. */
|
||||
class PathConstraintMixTimeline extends CurveTimeline {
|
||||
private static inline var ENTRIES:Int = 4;
|
||||
private static inline var ROTATE:Int = 1;
|
||||
private static inline var X:Int = 2;
|
||||
private static inline var Y:Int = 3;
|
||||
|
||||
/** The index of the path constraint in {@link Skeleton#getPathConstraints()} when this timeline is applied. */
|
||||
/** The index of the path constraint in {@link Skeleton#getPathConstraints()} that will be changed when this timeline is
|
||||
* applied. */
|
||||
public var constraintIndex:Int = 0;
|
||||
|
||||
public function new(frameCount:Int, bezierCount:Int, pathConstraintIndex:Int) {
|
||||
@ -51,6 +54,9 @@ class PathConstraintMixTimeline extends CurveTimeline {
|
||||
return ENTRIES;
|
||||
}
|
||||
|
||||
/** Sets the time and mix values for the specified frame.
|
||||
* @param frame Between 0 and <code>frameCount</code>, inclusive.
|
||||
* @param time The frame time in seconds. */
|
||||
public function setFrame(frame:Int, time:Float, mixRotate:Float, mixX:Float, mixY:Float):Void {
|
||||
frame <<= 2;
|
||||
frames[frame] = time;
|
||||
|
||||
@ -33,8 +33,10 @@ import spine.Event;
|
||||
import spine.PathConstraint;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Changes a path constraint's {@link PathConstraint#position}. */
|
||||
class PathConstraintPositionTimeline extends CurveTimeline1 {
|
||||
/** The index of the path constraint in {@link Skeleton#pathConstraints} when this timeline is applied. */
|
||||
/** The index of the path constraint in {@link Skeleton#pathConstraints} that will be changed when this timeline is
|
||||
* applied. */
|
||||
public var constraintIndex:Int = 0;
|
||||
|
||||
public function new(frameCount:Int, bezierCount:Int, pathConstraintIndex:Int) {
|
||||
|
||||
@ -33,8 +33,10 @@ import spine.Event;
|
||||
import spine.PathConstraint;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Changes a path constraint's {@link PathConstraint#spacing}. */
|
||||
class PathConstraintSpacingTimeline extends CurveTimeline1 {
|
||||
/** The index of the path constraint in {@link Skeleton#pathConstraints} when this timeline is applied. */
|
||||
/** The index of the path constraint in {@link Skeleton#pathConstraints} that will be changed when this timeline is
|
||||
* applied. */
|
||||
public var constraintIndex:Int = 0;
|
||||
|
||||
public function new(frameCount:Int, bezierCount:Int, pathConstraintIndex:Int) {
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
|
||||
package spine.animation;
|
||||
|
||||
/** Changes a physics constraint's {@link PhysicsConstraint#getWind()}. */
|
||||
/** Changes a physics constraint's {@link PhysicsConstraint#getGravity()}. */
|
||||
class PhysicsConstraintGravityTimeline extends PhysicsConstraintTimeline {
|
||||
public function new(frameCount:Int, bezierCount:Int, physicsConstraintIndex:Int) {
|
||||
super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintGravity);
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
|
||||
package spine.animation;
|
||||
|
||||
/** Changes a physics constraint's {@link PhysicsConstraint#getWind()}. */
|
||||
/** Changes a physics constraint's {@link PhysicsConstraint#getMix()}. */
|
||||
class PhysicsConstraintMixTimeline extends PhysicsConstraintTimeline {
|
||||
public function new(frameCount:Int, bezierCount:Int, physicsConstraintIndex:Int) {
|
||||
super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintMix);
|
||||
|
||||
@ -33,11 +33,13 @@ import spine.animation.Timeline;
|
||||
import spine.Event;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Resets a physics constraint when specific animation times are reached. */
|
||||
class PhysicsConstraintResetTimeline extends Timeline {
|
||||
/** The index of the physics constraint in {@link Skeleton#physicsConstraints} that will be reset when this timeline is
|
||||
* applied, or -1 if all physics constraints in the skeleton will be reset. */
|
||||
* applied, or -1 if all physics constraints in the skeleton will be reset. */
|
||||
public var constraintIndex:Int = 0;
|
||||
|
||||
/** @param physicsConstraintIndex -1 for all physics constraints in the skeleton. */
|
||||
public function new(frameCount:Int, physicsConstraintIndex:Int) {
|
||||
propertyIds = [Std.string(Property.physicsConstraintReset)];
|
||||
super(frameCount, propertyIds);
|
||||
@ -48,12 +50,13 @@ class PhysicsConstraintResetTimeline extends Timeline {
|
||||
return frames.length;
|
||||
}
|
||||
|
||||
/** Sets the time in seconds and the event for the specified key frame. */
|
||||
/** Sets the time for the specified frame.
|
||||
* @param frame Between 0 and <code>frameCount</code>, inclusive. */
|
||||
public function setFrame(frame:Int, time:Float):Void {
|
||||
frames[frame] = time;
|
||||
}
|
||||
|
||||
/** Resets the physics constraint when frames > lastTime and <= time. */
|
||||
/** Resets the physics constraint when frames > <code>lastTime</code> and <= <code>time</code>. */
|
||||
public override function apply(skeleton:Skeleton, lastTime:Float, time:Float, firedEvents:Array<Event>, alpha:Float, blend:MixBlend,
|
||||
direction:MixDirection):Void {
|
||||
var constraint:PhysicsConstraint = null;
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
|
||||
package spine.animation;
|
||||
|
||||
/**
|
||||
* Constants for animation property types.
|
||||
*/
|
||||
class Property {
|
||||
public static inline var rotate:Int = 0;
|
||||
public static inline var x:Int = 1;
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
|
||||
package spine.animation;
|
||||
|
||||
/** Changes the RGB for a slot's {@link Slot#getColor()} and {@link Slot#getDarkColor()} for two color tinting. */
|
||||
class RGB2Timeline extends CurveTimeline implements SlotTimeline {
|
||||
private static inline var ENTRIES:Int = 7;
|
||||
private static inline var R:Int = 1;
|
||||
@ -49,11 +50,21 @@ class RGB2Timeline extends CurveTimeline implements SlotTimeline {
|
||||
return ENTRIES;
|
||||
}
|
||||
|
||||
/** The index of the slot in {@link Skeleton#getSlots()} that will be changed when this timeline is applied. The
|
||||
* {@link Slot#getDarkColor()} must not be null. */
|
||||
public function getSlotIndex():Int {
|
||||
return slotIndex;
|
||||
}
|
||||
|
||||
/** Sets the time in seconds, light, and dark colors for the specified key frame. */
|
||||
/** Sets the time, light color, and dark color for the specified frame.
|
||||
* @param frame Between 0 and <code>frameCount</code>, inclusive.
|
||||
* @param time The frame time in seconds.
|
||||
* @param r Red component for the light color (0-1).
|
||||
* @param g Green component for the light color (0-1).
|
||||
* @param b Blue component for the light color (0-1).
|
||||
* @param r2 Red component for the dark color (0-1).
|
||||
* @param g2 Green component for the dark color (0-1).
|
||||
* @param b2 Blue component for the dark color (0-1). */
|
||||
public function setFrame(frame:Int, time:Float, r:Float, g:Float, b:Float, r2:Float, g2:Float, b2:Float):Void {
|
||||
frame *= ENTRIES;
|
||||
frames[frame] = time;
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
|
||||
package spine.animation;
|
||||
|
||||
/** Changes a slot's {@link Slot#getColor()} and {@link Slot#getDarkColor()} for two color tinting. */
|
||||
class RGBA2Timeline extends CurveTimeline implements SlotTimeline {
|
||||
private static inline var ENTRIES:Int = 8;
|
||||
private static inline var R:Int = 1;
|
||||
@ -54,11 +55,15 @@ class RGBA2Timeline extends CurveTimeline implements SlotTimeline {
|
||||
return ENTRIES;
|
||||
}
|
||||
|
||||
/** The index of the slot in {@link Skeleton#getSlots()} that will be changed when this timeline is applied. The
|
||||
* {@link Slot#getDarkColor()} must not be null. */
|
||||
public function getSlotIndex():Int {
|
||||
return slotIndex;
|
||||
}
|
||||
|
||||
/** Sets the time in seconds, light, and dark colors for the specified key frame. */
|
||||
/** Sets the time, light color, and dark color for the specified frame.
|
||||
* @param frame Between 0 and <code>frameCount</code>, inclusive.
|
||||
* @param time The frame time in seconds. */
|
||||
public function setFrame(frame:Int, time:Float, r:Float, g:Float, b:Float, a:Float, r2:Float, g2:Float, b2:Float):Void {
|
||||
frame <<= 3;
|
||||
frames[frame] = time;
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
|
||||
package spine.animation;
|
||||
|
||||
/** Changes a slot's {@link Slot#getColor()}. */
|
||||
class RGBATimeline extends CurveTimeline implements SlotTimeline {
|
||||
private static inline var ENTRIES:Int = 5;
|
||||
private static inline var R:Int = 1;
|
||||
@ -51,7 +52,13 @@ class RGBATimeline extends CurveTimeline implements SlotTimeline {
|
||||
return slotIndex;
|
||||
}
|
||||
|
||||
/** Sets the time in seconds, light, and dark colors for the specified key frame. */
|
||||
/** Sets the time and color for the specified frame.
|
||||
* @param frame Between 0 and <code>frameCount</code>, inclusive.
|
||||
* @param time The frame time in seconds.
|
||||
* @param r The red component.
|
||||
* @param g The green component.
|
||||
* @param b The blue component.
|
||||
* @param a The alpha component. */
|
||||
public function setFrame(frame:Int, time:Float, r:Float, g:Float, b:Float, a:Float):Void {
|
||||
frame *= ENTRIES;
|
||||
frames[frame] = time;
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
|
||||
package spine.animation;
|
||||
|
||||
/** Changes the RGB for a slot's {@link Slot#getColor()}. */
|
||||
class RGBTimeline extends CurveTimeline implements SlotTimeline {
|
||||
private static inline var ENTRIES:Int = 4;
|
||||
private static inline var R:Int = 1;
|
||||
@ -50,7 +51,9 @@ class RGBTimeline extends CurveTimeline implements SlotTimeline {
|
||||
return slotIndex;
|
||||
}
|
||||
|
||||
/** Sets the time in seconds, light, and dark colors for the specified key frame. */
|
||||
/** Sets the time and color for the specified frame.
|
||||
* @param frame Between 0 and <code>frameCount</code>, inclusive.
|
||||
* @param time The frame time in seconds. */
|
||||
public function setFrame(frame:Int, time:Float, r:Float, g:Float, b:Float):Void {
|
||||
frame <<= 2;
|
||||
frames[frame] = time;
|
||||
|
||||
@ -33,6 +33,7 @@ import spine.Bone;
|
||||
import spine.Event;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Changes a bone's local {@link Bone#rotation}. */
|
||||
class RotateTimeline extends CurveTimeline1 implements BoneTimeline {
|
||||
public var boneIndex:Int = 0;
|
||||
|
||||
|
||||
@ -34,6 +34,7 @@ import spine.Event;
|
||||
import spine.MathUtils;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Changes a bone's local {@link Bone#scaleX} and {@link Bone#scaleY}. */
|
||||
class ScaleTimeline extends CurveTimeline2 implements BoneTimeline {
|
||||
private var boneIndex:Int = 0;
|
||||
|
||||
|
||||
@ -34,6 +34,7 @@ import spine.Event;
|
||||
import spine.MathUtils;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Changes a bone's local {@link Bone#scaleX}. */
|
||||
class ScaleXTimeline extends CurveTimeline1 implements BoneTimeline {
|
||||
private var boneIndex:Int = 0;
|
||||
|
||||
|
||||
@ -34,6 +34,7 @@ import spine.Event;
|
||||
import spine.MathUtils;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Changes a bone's local {@link Bone#scaleY}. */
|
||||
class ScaleYTimeline extends CurveTimeline1 implements BoneTimeline {
|
||||
private var boneIndex:Int = 0;
|
||||
|
||||
|
||||
@ -32,6 +32,7 @@ package spine.animation;
|
||||
import spine.attachments.VertexAttachment;
|
||||
import spine.attachments.Attachment;
|
||||
|
||||
/** Changes a slot's {@link Slot#getSequenceIndex()} for an attachment's {@link Sequence}. */
|
||||
class SequenceTimeline extends Timeline implements SlotTimeline {
|
||||
static var ENTRIES = 3;
|
||||
static var MODE = 1;
|
||||
@ -62,7 +63,10 @@ class SequenceTimeline extends Timeline implements SlotTimeline {
|
||||
|
||||
/** Sets the time, mode, index, and frame time for the specified frame.
|
||||
* @param frame Between 0 and <code>frameCount</code>, inclusive.
|
||||
* @param time Seconds between frames. */
|
||||
* @param time Seconds between frames.
|
||||
* @param mode The sequence mode.
|
||||
* @param index The sequence index.
|
||||
* @param delay The delay between frames. */
|
||||
public function setFrame(frame:Int, time:Float, mode:SequenceMode, index:Int, delay:Float) {
|
||||
frame *= SequenceTimeline.ENTRIES;
|
||||
frames[frame] = time;
|
||||
|
||||
@ -33,6 +33,7 @@ import spine.Bone;
|
||||
import spine.Event;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Changes a bone's local {@link Bone#shearX} and {@link Bone#shearY}. */
|
||||
class ShearTimeline extends CurveTimeline2 implements BoneTimeline {
|
||||
private var boneIndex:Int = 0;
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ import spine.Bone;
|
||||
import spine.Event;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Changes a bone's local {@link Bone#shearX}. */
|
||||
class ShearXTimeline extends CurveTimeline1 implements BoneTimeline {
|
||||
private var boneIndex:Int = 0;
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ import spine.Bone;
|
||||
import spine.Event;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Changes a bone's local {@link Bone#shearY}. */
|
||||
class ShearYTimeline extends CurveTimeline1 implements BoneTimeline {
|
||||
private var boneIndex:Int = 0;
|
||||
|
||||
|
||||
@ -29,6 +29,8 @@
|
||||
|
||||
package spine.animation;
|
||||
|
||||
/** An interface for timelines which change the property of a slot. */
|
||||
interface SlotTimeline {
|
||||
/** The index of the slot in {@link Skeleton#getSlots()} that will be changed when this timeline is applied. */
|
||||
function getSlotIndex():Int;
|
||||
}
|
||||
|
||||
@ -32,32 +32,66 @@ package spine.animation;
|
||||
import spine.Event;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** The base class for all timelines. */
|
||||
class Timeline {
|
||||
/** Uniquely encodes both the type of this timeline and the skeleton properties that it affects. */
|
||||
public var propertyIds:Array<String>;
|
||||
/** The time in seconds and any other values for each frame. */
|
||||
public var frames:Array<Float>;
|
||||
|
||||
/**
|
||||
* @param propertyIds Unique identifiers for the properties the timeline modifies.
|
||||
* @param frameCount The number of frames for this timeline.
|
||||
*/
|
||||
public function new(frameCount:Int, propertyIds:Array<String>) {
|
||||
this.propertyIds = propertyIds;
|
||||
frames = new Array<Float>();
|
||||
frames.resize(frameCount * getFrameEntries());
|
||||
}
|
||||
|
||||
/** The number of entries stored per frame. */
|
||||
public function getFrameEntries():Int {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** The number of frames for this timeline. */
|
||||
public function getFrameCount():Int {
|
||||
return Std.int(frames.length / getFrameEntries());
|
||||
}
|
||||
|
||||
/** Returns the duration of this timeline in seconds. */
|
||||
public function getDuration():Float {
|
||||
return frames[frames.length - getFrameEntries()];
|
||||
}
|
||||
|
||||
/** Applies this timeline to the skeleton.
|
||||
* @param skeleton The skeleton to which the timeline is being applied. This provides access to the bones, slots, and other
|
||||
* skeleton components that the timeline may change.
|
||||
* @param lastTime The last time in seconds this timeline was 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). Pass -1 the first time an animation is
|
||||
* applied to ensure frame 0 is triggered.
|
||||
* @param time The time in seconds that the skeleton is being posed for. Most timelines find the frame before and the frame
|
||||
* after this time and interpolate between the frame values. If beyond the last frame, the last frame will be
|
||||
* applied.
|
||||
* @param events If any events are fired, they are added to this list. Can be null to ignore fired events or if the timeline
|
||||
* does not fire events.
|
||||
* @param alpha 0 applies the current or setup value (depending on <code>blend</code>). 1 applies the timeline value.
|
||||
* Between 0 and 1 applies a value between the current or setup value and the timeline value. 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 (layering).
|
||||
* @param blend Controls how mixing is applied when <code>alpha</code> < 1.
|
||||
* @param direction Indicates whether the timeline is mixing in or out. Used by timelines which perform instant transitions,
|
||||
* such as {@link DrawOrderTimeline} or {@link AttachmentTimeline}, and others such as {@link ScaleTimeline}.
|
||||
*/
|
||||
public function apply(skeleton:Skeleton, lastTime:Float, time:Float, events:Array<Event>, alpha:Float, blend:MixBlend, direction:MixDirection):Void {
|
||||
throw new SpineException("Timeline implementations must override apply()");
|
||||
}
|
||||
|
||||
/** Linear search using a stride of 1.
|
||||
* @param time Must be >= the first value in <code>frames</code>.
|
||||
* @return The index of the first value <= <code>time</code>.
|
||||
*/
|
||||
public static function search1(frames:Array<Float>, time:Float):Int {
|
||||
var n:Int = frames.length;
|
||||
for (i in 1...n) {
|
||||
@ -67,6 +101,10 @@ class Timeline {
|
||||
return n - 1;
|
||||
}
|
||||
|
||||
/** Linear search using the specified stride.
|
||||
* @param time Must be >= the first value in <code>frames</code>.
|
||||
* @return The index of the first value <= <code>time</code>.
|
||||
*/
|
||||
public static function search(values:Array<Float>, time:Float, step:Int):Int {
|
||||
var n:Int = values.length;
|
||||
var i:Int = step;
|
||||
|
||||
@ -32,11 +32,24 @@ package spine.animation;
|
||||
import spine.animation.Listeners.EventListeners;
|
||||
import spine.Poolable;
|
||||
|
||||
/** 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. */
|
||||
class TrackEntry implements Poolable {
|
||||
/** The animation to apply for this track entry. */
|
||||
public var animation:Animation;
|
||||
/** The animation queued to start after this animation, or null if there is none. <code>next</code> makes up a doubly linked
|
||||
* list.
|
||||
* <p>
|
||||
* See {@link AnimationState#clearNext(TrackEntry)} to truncate the list. */
|
||||
public var next:TrackEntry;
|
||||
/** The animation queued to play before this animation, or null. <code>previous</code> makes up a doubly linked list. */
|
||||
public var previous:TrackEntry;
|
||||
/** The track entry for the previous animation when mixing from the previous animation to this animation, or null if no
|
||||
* mixing is currently occurring. When mixing from multiple animations, <code>mixingFrom</code> makes up a linked list. */
|
||||
public var mixingFrom:TrackEntry;
|
||||
/** The track entry for the next animation when mixing from this animation to the next animation, or null if no mixing is
|
||||
* currently occurring. When mixing to multiple animations, <code>mixingTo</code> makes up a linked list. */
|
||||
public var mixingTo:TrackEntry;
|
||||
public var onStart:Listeners = new Listeners();
|
||||
public var onInterrupt:Listeners = new Listeners();
|
||||
@ -44,16 +57,54 @@ class TrackEntry implements Poolable {
|
||||
public var onDispose:Listeners = new Listeners();
|
||||
public var onComplete:Listeners = new Listeners();
|
||||
public var onEvent:EventListeners = new EventListeners();
|
||||
/** The index of the track where this track entry is either current or queued.
|
||||
* <p>
|
||||
* See {@link AnimationState#getCurrent(int)}. */
|
||||
public var trackIndex:Int = 0;
|
||||
/** If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its
|
||||
* duration. */
|
||||
public var loop:Bool = false;
|
||||
/** If true, the animation will be applied in reverse. Events are not fired when an animation is applied in reverse. */
|
||||
public var reverse:Bool = false;
|
||||
/** If true, when mixing from the previous animation to this animation, the previous animation is applied as normal instead
|
||||
* of being mixed out.
|
||||
* <p>
|
||||
* When mixing between animations that key the same property, if a lower track also keys that property then the value will
|
||||
* briefly dip toward the lower track value during the mix. This happens because the first animation mixes from 100% to 0%
|
||||
* while the second animation mixes from 0% to 100%. Setting <code>holdPrevious</code> to true applies the first animation
|
||||
* at 100% during the mix so the lower track value is overwritten. Such dipping does not occur on the lowest track which
|
||||
* keys the property, only when a higher track also keys the property.
|
||||
* <p>
|
||||
* Snapping will occur if <code>holdPrevious</code> is true and this animation does not key all the same properties as the
|
||||
* previous animation. */
|
||||
public var holdPrevious:Bool = false;
|
||||
/** When the mix percentage ({@link #getMixTime()} / {@link #getMixDuration()}) is less than the
|
||||
* <code>eventThreshold</code>, event timelines are applied while this animation is being mixed out. Defaults to 0, so event
|
||||
* timelines are not applied while this animation is being mixed out. */
|
||||
public var eventThreshold:Float = 0;
|
||||
/** When the mix percentage ({@link #getMixTime()} / {@link #getMixDuration()}) is less than the
|
||||
* <code>mixAttachmentThreshold</code>, attachment timelines are applied while this animation is being mixed out. Defaults
|
||||
* to 0, so attachment timelines are not applied while this animation is being mixed out. */
|
||||
public var mixAttachmentThreshold:Float = 0;
|
||||
/** When {@link #getAlpha()} is greater than <code>alphaAttachmentThreshold</code>, attachment timelines are applied.
|
||||
* Defaults to 0, so attachment timelines are always applied. */
|
||||
public var alphaAttachmentThreshold:Float = 0;
|
||||
/** When the mix percentage ({@link #getMixTime()} / {@link #getMixDuration()}) is less than the
|
||||
* <code>mixDrawOrderThreshold</code>, draw order timelines are applied while this animation is being mixed out. Defaults to
|
||||
* 0, so draw order timelines are not applied while this animation is being mixed out. */
|
||||
public var mixDrawOrderThreshold:Float = 0;
|
||||
/** Seconds when this animation starts, both initially and after looping. Defaults to 0.
|
||||
* <p>
|
||||
* 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 var animationStart:Float = 0;
|
||||
/** 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 {@link Animation#duration}. */
|
||||
public var animationEnd:Float = 0;
|
||||
/** 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 <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 var animationLast:Float = 0;
|
||||
public var nextAnimationLast:Float = 0;
|
||||
|
||||
@ -70,20 +121,78 @@ class TrackEntry implements Poolable {
|
||||
* afterward, use {@link #setMixDuration(float, float)} so this <code>delay</code> is adjusted. */
|
||||
public var delay(default, set):Float = 0;
|
||||
|
||||
/** Current time in seconds this track entry has been the current track entry. The track time determines
|
||||
* {@link #getAnimationTime()}. The track time can be set to start the animation at a time other than 0, without affecting
|
||||
* looping. */
|
||||
public var trackTime:Float = 0;
|
||||
public var trackLast:Float = 0;
|
||||
public var nextTrackLast:Float = 0;
|
||||
/** The track time in seconds when this animation will be removed from the track. Defaults to the highest possible float
|
||||
* value, meaning the animation will be applied until a new animation is set or the track is cleared. If the track end time
|
||||
* is reached, no other animations are queued for playback, and mixing from any previous animations is complete, then the
|
||||
* properties keyed by the animation are set to the setup pose and the track is cleared.
|
||||
* <p>
|
||||
* It may be desired to use {@link AnimationState#addEmptyAnimation(int, float, float)} rather than have the animation
|
||||
* abruptly cease being applied. */
|
||||
public var trackEnd:Float = 0;
|
||||
/** Multiplier for the delta time when this track entry is updated, causing time for this animation to pass slower or
|
||||
* faster. Defaults to 1.
|
||||
* <p>
|
||||
* Values < 0 are not supported. To play an animation in reverse, use {@link #getReverse()}.
|
||||
* <p>
|
||||
* {@link #getMixTime()} is not affected by track entry time scale, so {@link #getMixDuration()} may need to be adjusted to
|
||||
* match the animation speed.
|
||||
* <p>
|
||||
* When using {@link AnimationState#addAnimation(int, Animation, boolean, float)} with a <code>delay</code> <= 0, the
|
||||
* {@link #getDelay()} is set using the mix duration from the {@link AnimationStateData}, assuming time scale to be 1. If
|
||||
* the time scale is not 1, the delay may need to be adjusted.
|
||||
* <p>
|
||||
* See AnimationState {@link AnimationState#getTimeScale()} for affecting all animations. */
|
||||
public var timeScale:Float = 0;
|
||||
/** Values < 1 mix this animation with the skeleton's current pose (usually the pose resulting from lower tracks). Defaults
|
||||
* to 1, which overwrites the skeleton's current pose with this animation.
|
||||
* <p>
|
||||
* Typically track 0 is used to completely pose the skeleton, then alpha is used on higher tracks. It doesn't make sense to
|
||||
* use alpha on track 0 if the skeleton pose is from the last frame render. */
|
||||
public var alpha:Float = 0;
|
||||
/** 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. */
|
||||
public var mixTime:Float = 0;
|
||||
/** 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>
|
||||
* A mix duration of 0 still mixes out over one frame to provide the track entry being mixed out a chance to revert the
|
||||
* properties it was animating. A mix duration of 0 can be set at any time to end the mix on the next
|
||||
* {@link AnimationState#update(float) update}.
|
||||
* <p>
|
||||
* The <code>mixDuration</code> can be set manually rather than use the value from
|
||||
* {@link AnimationStateData#getMix(Animation, Animation)}. In that case, the <code>mixDuration</code> can be set for a new
|
||||
* track entry only before {@link AnimationState#update(float)} is first called.
|
||||
* <p>
|
||||
* When using {@link AnimationState#addAnimation(int, Animation, boolean, float)} with a <code>delay</code> <= 0, the
|
||||
* {@link #getDelay()} is set using the mix duration from the {@link AnimationStateData}. If <code>mixDuration</code> is set
|
||||
* afterward, the delay may need to be adjusted. For example:<br>
|
||||
* <code>entry.delay = entry.previous.getTrackComplete() - entry.mixDuration;</code><br>
|
||||
* Alternatively, {@link #setMixDuration(float, float)} can be used to recompute the delay:<br>
|
||||
* <code>entry.setMixDuration(0.25f, 0);</code> */
|
||||
public var mixDuration:Float = 0;
|
||||
public var interruptAlpha:Float = 0;
|
||||
public var totalAlpha:Float = 0;
|
||||
/** Controls how properties keyed in the animation are mixed with lower tracks. Defaults to {@link MixBlend#replace}.
|
||||
* <p>
|
||||
* Track entries on track 0 ignore this setting and always use {@link MixBlend#first}.
|
||||
* <p>
|
||||
* The <code>mixBlend</code> can be set for a new track entry only before {@link AnimationState#apply(Skeleton)} is first
|
||||
* called. */
|
||||
public var mixBlend:MixBlend = MixBlend.replace;
|
||||
public var timelineMode:Array<Int> = new Array<Int>();
|
||||
public var timelineHoldMix:Array<TrackEntry> = new Array<TrackEntry>();
|
||||
public var timelinesRotation:Array<Float> = new Array<Float>();
|
||||
/** If true, mixing rotation between tracks always uses the shortest rotation direction. If the rotation is animated, the
|
||||
* shortest rotation direction may change during the mix.
|
||||
* <p>
|
||||
* If false, the shortest rotation direction is remembered when the mix starts and the same direction is used for the rest
|
||||
* of the mix. Defaults to false. */
|
||||
public var shortestRotation = false;
|
||||
|
||||
function set_delay(delay:Float):Float {
|
||||
@ -93,6 +202,12 @@ class TrackEntry implements Poolable {
|
||||
|
||||
public function new() {}
|
||||
|
||||
/** Uses {@link #getTrackTime()} to compute the <code>animationTime</code>. When the <code>trackTime</code> is 0, the
|
||||
* <code>animationTime</code> is equal to the <code>animationStart</code> time.
|
||||
* <p>
|
||||
* The <code>animationTime</code> is between {@link #getAnimationStart()} and {@link #getAnimationEnd()}, except if this
|
||||
* track entry is non-looping and {@link #getAnimationEnd()} is >= to the animation {@link Animation#duration}, then
|
||||
* <code>animationTime</code> continues to increase past {@link #getAnimationEnd()}. */
|
||||
public function getAnimationTime():Float {
|
||||
if (loop) {
|
||||
var duration:Float = animationEnd - animationStart;
|
||||
@ -147,10 +262,22 @@ class TrackEntry implements Poolable {
|
||||
timelinesRotation.resize(0);
|
||||
}
|
||||
|
||||
/** Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the
|
||||
* long way around when using {@link #getAlpha()} and starting animations on other tracks.
|
||||
* <p>
|
||||
* Mixing with {@link MixBlend#replace} involves finding a rotation between two others, which has two possible solutions:
|
||||
* the short way or the long way around. The two rotations likely change over time, so which direction is the short or long
|
||||
* way also changes. If the short way was always chosen, bones would flip to the other side when that direction became the
|
||||
* long way. TrackEntry chooses the short way the first time it is applied and remembers that direction. */
|
||||
public function resetRotationDirection():Void {
|
||||
timelinesRotation.resize(0);
|
||||
}
|
||||
|
||||
/** Sets both {@link #getMixDuration()} and {@link #getDelay()}.
|
||||
* @param mixDuration If > 0, sets {@link TrackEntry#getDelay()}. If <= 0, the delay set is the duration of the previous track
|
||||
* entry minus the specified mix duration plus the specified <code>delay</code> (ie the mix ends at
|
||||
* (<code>delay</code> = 0) or before (<code>delay</code> < 0) the previous track entry duration). If the previous
|
||||
* entry is looping, its next loop completion is used instead of its duration. */
|
||||
public function setMixDurationWithDelay(mixDuration:Float):Float {
|
||||
this.mixDuration = mixDuration;
|
||||
if (delay <= 0) {
|
||||
|
||||
@ -34,6 +34,9 @@ import spine.Skeleton;
|
||||
import spine.TransformConstraint;
|
||||
import spine.TransformConstraintData;
|
||||
|
||||
/** Changes a transform constraint's {@link TransformConstraint#mixRotate}, {@link TransformConstraint#mixX},
|
||||
* {@link TransformConstraint#mixY}, {@link TransformConstraint#mixScaleX},
|
||||
* {@link TransformConstraint#mixScaleY}, and {@link TransformConstraint#mixShearY}. */
|
||||
class TransformConstraintTimeline extends CurveTimeline {
|
||||
static public inline var ENTRIES:Int = 7;
|
||||
private static inline var ROTATE:Int = 1;
|
||||
@ -43,7 +46,8 @@ class TransformConstraintTimeline extends CurveTimeline {
|
||||
private static inline var SCALEY:Int = 5;
|
||||
private static inline var SHEARY:Int = 6;
|
||||
|
||||
/** The index of the transform constraint slot in {@link Skeleton#transformConstraints} that will be changed. */
|
||||
/** The index of the transform constraint in {@link Skeleton#transformConstraints} that will be changed when this
|
||||
* timeline is applied. */
|
||||
public var constraintIndex:Int = 0;
|
||||
|
||||
public function new(frameCount:Int, bezierCount:Int, transformConstraintIndex:Int) {
|
||||
@ -55,7 +59,9 @@ class TransformConstraintTimeline extends CurveTimeline {
|
||||
return ENTRIES;
|
||||
}
|
||||
|
||||
/** The time in seconds, rotate mix, translate mix, scale mix, and shear mix for the specified key frame. */
|
||||
/** Sets the time, rotate mix, translate mix, scale mix, and shear mix for the specified frame.
|
||||
* @param frame Between 0 and <code>frameCount</code>, inclusive.
|
||||
* @param time The frame time in seconds. */
|
||||
public function setFrame(frame:Int, time:Float, mixRotate:Float, mixX:Float, mixY:Float, mixScaleX:Float, mixScaleY:Float, mixShearY:Float):Void {
|
||||
frame *= ENTRIES;
|
||||
frames[frame] = time;
|
||||
|
||||
@ -33,6 +33,7 @@ import spine.Bone;
|
||||
import spine.Event;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Changes a bone's local {@link Bone#x} and {@link Bone#y}. */
|
||||
class TranslateTimeline extends CurveTimeline2 implements BoneTimeline {
|
||||
public var boneIndex:Int = 0;
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ import spine.Bone;
|
||||
import spine.Event;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Changes a bone's local x value. */
|
||||
class TranslateXTimeline extends CurveTimeline1 implements BoneTimeline {
|
||||
public var boneIndex:Int = 0;
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ import spine.Bone;
|
||||
import spine.Event;
|
||||
import spine.Skeleton;
|
||||
|
||||
/** Changes a bone's local {@link Bone#y}. */
|
||||
class TranslateYTimeline extends CurveTimeline1 implements BoneTimeline {
|
||||
public var boneIndex:Int = 0;
|
||||
|
||||
|
||||
@ -29,10 +29,18 @@
|
||||
|
||||
package spine.atlas;
|
||||
|
||||
/** The interface which can be implemented to customize loading images for texture atlas pages and regions. */
|
||||
interface TextureLoader {
|
||||
/** Loads a texture atlas page.
|
||||
* @param page The page to load.
|
||||
* @param path The path to the page image. */
|
||||
function loadPage(page:TextureAtlasPage, path:String):Void;
|
||||
|
||||
/** Loads a texture atlas region.
|
||||
* @param region The region to load. */
|
||||
function loadRegion(region:TextureAtlasRegion):Void;
|
||||
|
||||
/** Unloads a texture atlas page.
|
||||
* @param page The page to unload. */
|
||||
function unloadPage(page:TextureAtlasPage):Void;
|
||||
}
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
|
||||
package spine.attachments;
|
||||
|
||||
/** The base class for all attachments. */
|
||||
class Attachment {
|
||||
private var _name:String;
|
||||
|
||||
@ -39,6 +40,7 @@ class Attachment {
|
||||
_name = name;
|
||||
}
|
||||
|
||||
/** The attachment's name. */
|
||||
public var name(get, never):String;
|
||||
|
||||
private function get_name():String {
|
||||
@ -49,6 +51,7 @@ class Attachment {
|
||||
return name;
|
||||
}
|
||||
|
||||
/** Returns a copy of the attachment. */
|
||||
public function copy():Attachment {
|
||||
throw new SpineException("Not implemented");
|
||||
}
|
||||
|
||||
@ -31,22 +31,26 @@ package spine.attachments;
|
||||
|
||||
import spine.Skin;
|
||||
|
||||
/** The interface which can be implemented to customize creating and populating attachments.
|
||||
* <p>
|
||||
* See <a href='https://esotericsoftware.com/spine-loading-skeleton-data#AttachmentLoader'>Loading skeleton data</a> in the Spine
|
||||
* Runtimes Guide. */
|
||||
interface AttachmentLoader {
|
||||
/** @return May be null to not load an attachment. */
|
||||
/** @return May be null to not load the attachment. */
|
||||
function newRegionAttachment(skin:Skin, name:String, path:String, sequence:Sequence):RegionAttachment;
|
||||
|
||||
/** @return May be null to not load an attachment. */
|
||||
/** @return May be null to not load the attachment. In that case null should also be returned for child meshes. */
|
||||
function newMeshAttachment(skin:Skin, name:String, path:String, sequence:Sequence):MeshAttachment;
|
||||
|
||||
/** @return May be null to not load an attachment. */
|
||||
/** @return May be null to not load the attachment. */
|
||||
function newBoundingBoxAttachment(skin:Skin, name:String):BoundingBoxAttachment;
|
||||
|
||||
/** @return May be null to not load an attachment */
|
||||
/** @return May be null to not load the attachment. */
|
||||
function newPathAttachment(skin:Skin, name:String):PathAttachment;
|
||||
|
||||
/** @return May be null to not load an attachment */
|
||||
/** @return May be null to not load the attachment. */
|
||||
function newPointAttachment(skin:Skin, name:String):PointAttachment;
|
||||
|
||||
/** @return May be null to not load an attachment */
|
||||
/** @return May be null to not load the attachment. */
|
||||
function newClippingAttachment(skin:Skin, name:String):ClippingAttachment;
|
||||
}
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
|
||||
package spine.attachments;
|
||||
|
||||
/**
|
||||
* The type of attachment.
|
||||
*/
|
||||
class AttachmentType {
|
||||
public static var region(default, never):AttachmentType = new AttachmentType(0, "region");
|
||||
public static var boundingbox(default, never):AttachmentType = new AttachmentType(1, "boundingbox");
|
||||
|
||||
@ -31,7 +31,14 @@ package spine.attachments;
|
||||
|
||||
import spine.Color;
|
||||
|
||||
/** 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="https://esotericsoftware.com/spine-bounding-boxes">Bounding Boxes</a> in the Spine User
|
||||
* Guide. */
|
||||
class BoundingBoxAttachment extends VertexAttachment {
|
||||
/** The color of the bounding box as it was in Spine, or a default color if nonessential data was not exported. Bounding boxes
|
||||
* are not usually rendered at runtime. */
|
||||
public var color:Color = new Color(0, 0, 0, 0);
|
||||
|
||||
public function new(name:String) {
|
||||
|
||||
@ -32,8 +32,13 @@ package spine.attachments;
|
||||
import spine.Color;
|
||||
import spine.SlotData;
|
||||
|
||||
/** An attachment with vertices that make up a polygon used for clipping the rendering of other attachments. */
|
||||
class ClippingAttachment extends VertexAttachment {
|
||||
/** Clipping is performed between the clipping attachment's slot and the end slot. If null clipping is done until the end of
|
||||
* the skeleton's rendering. */
|
||||
public var endSlot:SlotData;
|
||||
/** The color of the clipping attachment as it was in Spine, or a default color if nonessential data was not exported. Clipping
|
||||
* attachments are not usually rendered at runtime. */
|
||||
public var color:Color = new Color(0.2275, 0.2275, 0.2275, 1);
|
||||
|
||||
public function new(name:String) {
|
||||
|
||||
@ -33,20 +33,36 @@ import spine.Color;
|
||||
import spine.atlas.TextureAtlasRegion;
|
||||
import spine.atlas.TextureAtlasPage;
|
||||
|
||||
/** 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="https://esotericsoftware.com/spine-meshes">Mesh attachments</a> in the Spine User Guide. */
|
||||
class MeshAttachment extends VertexAttachment implements HasTextureRegion {
|
||||
public var region:TextureRegion;
|
||||
public var path:String;
|
||||
/** The UV pair for each vertex, normalized within the texture region. */
|
||||
public var regionUVs = new Array<Float>();
|
||||
/** The UV pair for each vertex, normalized within the entire texture.
|
||||
* See {@link #updateRegion()}. */
|
||||
public var uvs = new Array<Float>();
|
||||
/** Triplets of vertex indices which describe the mesh's triangulation. */
|
||||
public var triangles = new Array<Int>();
|
||||
public var color:Color = new Color(1, 1, 1, 1);
|
||||
/** The width of the mesh's image, or zero if nonessential data was not exported. */
|
||||
public var width:Float = 0;
|
||||
/** The height of the mesh's image, or zero if nonessential data was not exported. */
|
||||
public var height:Float = 0;
|
||||
/** The number of entries at the beginning of {@link #vertices} that make up the mesh hull. */
|
||||
public var hullLength:Int = 0;
|
||||
/** Vertex index pairs describing edges for controlling triangulation, or be null if nonessential data was not exported. Mesh
|
||||
* triangles will never cross edges. Triangulation is not performed at runtime. */
|
||||
public var edges = new Array<Int>();
|
||||
public var rendererObject:Dynamic;
|
||||
public var sequence:Sequence;
|
||||
|
||||
/** 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). */
|
||||
private var _parentMesh:MeshAttachment;
|
||||
|
||||
public function new(name:String, path:String) {
|
||||
@ -54,6 +70,8 @@ class MeshAttachment extends VertexAttachment implements HasTextureRegion {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
/** Calculates {@link #uvs} using the {@link #regionUVs} and region. Must be called if the region, the region's properties, or
|
||||
* the {@link #regionUVs} are changed. */
|
||||
public function updateRegion():Void {
|
||||
if (region == null) {
|
||||
throw new SpineException("Region not set.");
|
||||
@ -174,12 +192,14 @@ class MeshAttachment extends VertexAttachment implements HasTextureRegion {
|
||||
return copy;
|
||||
}
|
||||
|
||||
/** If the attachment has a {@link #sequence}, the region may be changed. */
|
||||
public override function computeWorldVertices(slot:Slot, start:Int, count:Int, worldVertices:Array<Float>, offset:Int, stride:Int):Void {
|
||||
if (sequence != null)
|
||||
sequence.apply(slot, this);
|
||||
super.computeWorldVertices(slot, start, count, worldVertices, offset, stride);
|
||||
}
|
||||
|
||||
/** Returns a new mesh with the {@link #parentMesh} set to this mesh's parent mesh, if any, else to this mesh. */
|
||||
public function newLinkedMesh():MeshAttachment {
|
||||
var copy:MeshAttachment = new MeshAttachment(name, path);
|
||||
copy.rendererObject = rendererObject;
|
||||
|
||||
@ -31,10 +31,19 @@ package spine.attachments;
|
||||
|
||||
import spine.Color;
|
||||
|
||||
/** An attachment whose vertices make up a composite Bezier curve.
|
||||
* <p>
|
||||
* See {@link PathConstraint} and <a href="https://esotericsoftware.com/spine-paths">Paths</a> in the Spine User Guide. */
|
||||
class PathAttachment extends VertexAttachment {
|
||||
/** The lengths along the path in the setup pose from the start of the path to the end of each Bezier curve. */
|
||||
public var lengths:Array<Float>;
|
||||
/** If true, the start and end knots are connected. */
|
||||
public var closed:Bool = false;
|
||||
/** If true, additional calculations are performed to make computing positions along the path more accurate and movement along
|
||||
* the path have a constant speed. */
|
||||
public var constantSpeed:Bool = false;
|
||||
/** The color of the path as it was in Spine, or a default color if nonessential data was not exported. Paths are not usually
|
||||
* rendered at runtime. */
|
||||
public var color:Color = new Color(0, 0, 0, 0);
|
||||
|
||||
public function new(name:String) {
|
||||
|
||||
@ -33,10 +33,17 @@ import spine.Bone;
|
||||
import spine.Color;
|
||||
import spine.MathUtils;
|
||||
|
||||
/** An attachment which is a single point and a rotation. This can be used to spawn projectiles, particles, etc. A bone can be
|
||||
* used in similar ways, but a PointAttachment is slightly less expensive to compute and can be hidden, shown, and placed in a
|
||||
* skin.
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-points">Point Attachments</a> in the Spine User Guide. */
|
||||
class PointAttachment extends VertexAttachment {
|
||||
public var x:Float = 0;
|
||||
public var y:Float = 0;
|
||||
public var rotation:Float = 0;
|
||||
/** The color of the point attachment as it was in Spine, or a default color if nonessential data was not exported. Point
|
||||
* attachments are not usually rendered at runtime. */
|
||||
public var color:Color = new Color(0.38, 0.94, 0, 1);
|
||||
|
||||
public function new(name:String) {
|
||||
|
||||
@ -31,6 +31,9 @@ package spine.attachments;
|
||||
|
||||
import spine.Color;
|
||||
|
||||
/** An attachment that displays a textured quadrilateral.
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-regions">Region attachments</a> in the Spine User Guide. */
|
||||
class RegionAttachment extends Attachment implements HasTextureRegion {
|
||||
public static inline var BLX:Int = 0;
|
||||
public static inline var BLY:Int = 1;
|
||||
@ -41,12 +44,19 @@ class RegionAttachment extends Attachment implements HasTextureRegion {
|
||||
public static inline var BRX:Int = 6;
|
||||
public static inline var BRY:Int = 7;
|
||||
|
||||
/** The local x translation. */
|
||||
public var x:Float = 0;
|
||||
/** The local y translation. */
|
||||
public var y:Float = 0;
|
||||
/** The local scaleX. */
|
||||
public var scaleX:Float = 1;
|
||||
/** The local scaleY. */
|
||||
public var scaleY:Float = 1;
|
||||
/** The local rotation. */
|
||||
public var rotation:Float = 0;
|
||||
/** The width of the region attachment in Spine. */
|
||||
public var width:Float = 0;
|
||||
/** The height of the region attachment in Spine. */
|
||||
public var height:Float = 0;
|
||||
public var color:Color = new Color(1, 1, 1, 1);
|
||||
public var path:String;
|
||||
@ -54,15 +64,24 @@ class RegionAttachment extends Attachment implements HasTextureRegion {
|
||||
public var region:TextureRegion;
|
||||
public var sequence:Sequence;
|
||||
|
||||
/** For each of the 4 vertices, a pair of <code>x,y</code> values that is the local position of the vertex.
|
||||
*
|
||||
* See {@link #updateRegion()}. */
|
||||
private var offsets:Array<Float> = new Array<Float>();
|
||||
|
||||
public var uvs:Array<Float> = new Array<Float>();
|
||||
|
||||
/**
|
||||
* @param name The attachment name.
|
||||
* @param path The path used to find the region for the attachment.
|
||||
*/
|
||||
public function new(name:String, path:String) {
|
||||
super(name);
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
/** Calculates the {@link #offsets} and {@link #uvs} using the region and the attachment's transform. Must be called if the
|
||||
* region, the region's properties, or the transform are changed. */
|
||||
public function updateRegion():Void {
|
||||
if (region == null) {
|
||||
throw new SpineException("Region not set.");
|
||||
@ -126,6 +145,15 @@ class RegionAttachment extends Attachment implements HasTextureRegion {
|
||||
}
|
||||
}
|
||||
|
||||
/** Transforms the attachment's four vertices to world coordinates. If the attachment has a {@link #sequence}, the region may
|
||||
* be changed.
|
||||
*
|
||||
* See <a href="https://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
|
||||
* Runtimes Guide.
|
||||
* @param slot The slot the attachment is bound to.
|
||||
* @param worldVertices The output world vertices. Must have a length >= <code>offset</code> + 8.
|
||||
* @param offset The <code>worldVertices</code> index to begin writing values.
|
||||
* @param stride The number of <code>worldVertices</code> entries between the value pairs written. */
|
||||
public function computeWorldVertices(slot:Slot, worldVertices:Array<Float>, offset:Int, stride:Int):Void {
|
||||
if (sequence != null)
|
||||
sequence.apply(slot, this);
|
||||
|
||||
@ -33,13 +33,26 @@ import spine.Bone;
|
||||
import spine.Skeleton;
|
||||
import spine.Slot;
|
||||
|
||||
/** 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#deform}. */
|
||||
class VertexAttachment extends Attachment {
|
||||
private static var nextID:Int = 0;
|
||||
|
||||
/** The bones which affect the {@link vertices}. 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#bones}. Will be null
|
||||
* if this attachment has no weights. */
|
||||
public var bones:Array<Int>;
|
||||
/** 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 var vertices = new Array<Float>();
|
||||
/** The maximum number of world vertex values that can be output by
|
||||
* {@link computeWorldVertices} using the <code>count</code> parameter. */
|
||||
public var worldVerticesLength:Int = 0;
|
||||
/** Returns a unique ID for this attachment. */
|
||||
public var id:Int = nextID++;
|
||||
/** Timelines for the timeline attachment are also applied to this attachment.
|
||||
* May be null if no attachment-specific timelines should be applied. */
|
||||
public var timelineAttachment:VertexAttachment;
|
||||
|
||||
public function new(name:String) {
|
||||
@ -49,15 +62,15 @@ class VertexAttachment extends Attachment {
|
||||
|
||||
/** Transforms the attachment's local {@link #vertices} to world coordinates. If the slot's {@link Slot#deform} is
|
||||
* not empty, it is used to deform the vertices.
|
||||
*
|
||||
* See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine
|
||||
* <p>
|
||||
* See <a href="https://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
|
||||
* Runtimes Guide.
|
||||
* @param start The index of the first {@link #vertices} value to transform. Each vertex has 2 values, x and y.
|
||||
* @param count The number of world vertex values to output. Must be <= {@link #worldVerticesLength} - `start`.
|
||||
* @param worldVertices The output world vertices. Must have a length >= `offset` + `count` *
|
||||
* `stride` / 2.
|
||||
* @param offset The `worldVertices` index to begin writing values.
|
||||
* @param stride The number of `worldVertices` entries between the value pairs written. */
|
||||
* @param count The number of world vertex values to output. Must be <= {@link #worldVerticesLength} - <code>start</code>.
|
||||
* @param worldVertices The output world vertices. Must have a length >= <code>offset</code> + <code>count</code> *
|
||||
* <code>stride</code> / 2.
|
||||
* @param offset The <code>worldVertices</code> index to begin writing values.
|
||||
* @param stride The number of <code>worldVertices</code> entries between the value pairs written. */
|
||||
public function computeWorldVertices(slot:Slot, start:Int, count:Int, worldVertices:Array<Float>, offset:Int, stride:Int):Void {
|
||||
count = offset + (count >> 1) * stride;
|
||||
var skeleton:Skeleton = slot.skeleton;
|
||||
@ -149,6 +162,7 @@ class VertexAttachment extends Attachment {
|
||||
}
|
||||
}
|
||||
|
||||
/** Copy this attachment's data to another attachment. */
|
||||
public function copyTo(attachment:VertexAttachment):Void {
|
||||
if (bones != null) {
|
||||
attachment.bones = bones.copy();
|
||||
|
||||
@ -31,8 +31,9 @@ package spine.flixel;
|
||||
|
||||
import flixel.FlxStrip;
|
||||
|
||||
// this class is just to make the implementation coherent with the starling implementation
|
||||
/** A FlxStrip that draws a skeleton. This class is just to make the implementation coherent with the starling implementation. */
|
||||
class SkeletonMesh extends FlxStrip {
|
||||
/** Creates an uninitialized SkeletonMesh. */
|
||||
public function new(/*texture:FlxGraphicAsset*/) {
|
||||
super();
|
||||
// graphic = texture;
|
||||
|
||||
@ -33,6 +33,7 @@ import spine.attachments.RegionAttachment;
|
||||
import spine.attachments.ClippingAttachment;
|
||||
import spine.flixel.SkeletonMesh;
|
||||
|
||||
/** A FlxObject that draws a skeleton. The animation state and skeleton must be updated each frame. */
|
||||
class SkeletonSprite extends FlxObject
|
||||
{
|
||||
public var skeleton(default, null):Skeleton;
|
||||
@ -63,6 +64,7 @@ class SkeletonSprite extends FlxObject
|
||||
private var _tempPoint = new Point();
|
||||
|
||||
private static var QUAD_INDICES:Array<Int> = [0, 1, 2, 2, 3, 0];
|
||||
/** Creates an uninitialized SkeletonSprite. The renderer, skeleton, and animation state must be set before use. */
|
||||
public function new(skeletonData:SkeletonData, animationStateData:AnimationStateData = null)
|
||||
{
|
||||
super(0, 0);
|
||||
|
||||
@ -35,7 +35,9 @@ import starling.rendering.VertexData;
|
||||
import starling.styles.MeshStyle;
|
||||
import starling.textures.Texture;
|
||||
|
||||
/** A Starling Mesh that draws a skeleton. */
|
||||
class SkeletonMesh extends Mesh {
|
||||
/** Creates a SkeletonMesh with the specified texture and optional vertex, index data and style. */
|
||||
public function new(texture:Texture, vertexData:VertexData = null, indexData:IndexData = null, style:MeshStyle = null) {
|
||||
super(vertexData == null ? new VertexData() : vertexData, indexData == null ? new IndexData() : indexData, style);
|
||||
this.texture = texture;
|
||||
|
||||
@ -57,6 +57,7 @@ import starling.utils.Color;
|
||||
import starling.utils.MatrixUtil;
|
||||
import starling.utils.Max;
|
||||
|
||||
/** A starling display object that draws a skeleton. */
|
||||
class SkeletonSprite extends DisplayObject implements IAnimatable {
|
||||
static private var _tempPoint:Point = new Point();
|
||||
static private var _tempMatrix:Matrix = new Matrix();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user