[ts] Port of 4.0 changes, some kinks to be ironed out yet.

[ts] Add .json exports to WebGL assets dir for tests.

[ts] She loads, but she no play nice.
This commit is contained in:
badlogic 2020-11-10 16:35:56 +01:00
parent 549e9ae67b
commit 3863828c3e
25 changed files with 42861 additions and 13332 deletions

View File

@ -326,39 +326,48 @@ cp -f ../mix-and-match/export/mix-and-match.png "$ROOT/spine-starling/spine-star
echo "spine-ts" echo "spine-ts"
rm "$ROOT/spine-ts/webgl/example/assets/"* rm "$ROOT/spine-ts/webgl/example/assets/"*
cp -f ../coin/export/coin-pro.json "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../coin/export/coin-pro.skel "$ROOT/spine-ts/webgl/example/assets/" cp -f ../coin/export/coin-pro.skel "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../coin/export/coin-pma.atlas "$ROOT/spine-ts/webgl/example/assets/" cp -f ../coin/export/coin-pma.atlas "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../coin/export/coin-pma.png "$ROOT/spine-ts/webgl/example/assets/" cp -f ../coin/export/coin-pma.png "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../goblins/export/goblins-pro.json "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../goblins/export/goblins-pro.skel "$ROOT/spine-ts/webgl/example/assets/" cp -f ../goblins/export/goblins-pro.skel "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../goblins/export/goblins-pma.atlas "$ROOT/spine-ts/webgl/example/assets/" cp -f ../goblins/export/goblins-pma.atlas "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../goblins/export/goblins-pma.png "$ROOT/spine-ts/webgl/example/assets/" cp -f ../goblins/export/goblins-pma.png "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../raptor/export/raptor-pro.json "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../raptor/export/raptor-pro.skel "$ROOT/spine-ts/webgl/example/assets/" cp -f ../raptor/export/raptor-pro.skel "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../raptor/export/raptor-pma.atlas "$ROOT/spine-ts/webgl/example/assets/" cp -f ../raptor/export/raptor-pma.atlas "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../raptor/export/raptor-pma.png "$ROOT/spine-ts/webgl/example/assets/" cp -f ../raptor/export/raptor-pma.png "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../spineboy/export/spineboy-pro.json "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../spineboy/export/spineboy-pro.skel "$ROOT/spine-ts/webgl/example/assets/" cp -f ../spineboy/export/spineboy-pro.skel "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../spineboy/export/spineboy-pma.atlas "$ROOT/spine-ts/webgl/example/assets/" cp -f ../spineboy/export/spineboy-pma.atlas "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../spineboy/export/spineboy-pma.png "$ROOT/spine-ts/webgl/example/assets/" cp -f ../spineboy/export/spineboy-pma.png "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../spineboy/export/spineboy.png "$ROOT/spine-ts/webgl/example/assets/" cp -f ../spineboy/export/spineboy.png "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../tank/export/tank-pro.json "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../tank/export/tank-pro.skel "$ROOT/spine-ts/webgl/example/assets/" cp -f ../tank/export/tank-pro.skel "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../tank/export/tank-pma.atlas "$ROOT/spine-ts/webgl/example/assets/" cp -f ../tank/export/tank-pma.atlas "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../tank/export/tank-pma.png "$ROOT/spine-ts/webgl/example/assets/" cp -f ../tank/export/tank-pma.png "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../vine/export/vine-pro.json "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../vine/export/vine-pro.skel "$ROOT/spine-ts/webgl/example/assets/" cp -f ../vine/export/vine-pro.skel "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../vine/export/vine-pma.atlas "$ROOT/spine-ts/webgl/example/assets/" cp -f ../vine/export/vine-pma.atlas "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../vine/export/vine-pma.png "$ROOT/spine-ts/webgl/example/assets/" cp -f ../vine/export/vine-pma.png "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../owl/export/owl-pro.json "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../owl/export/owl-pro.skel "$ROOT/spine-ts/webgl/example/assets/" cp -f ../owl/export/owl-pro.skel "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../owl/export/owl-pma.atlas "$ROOT/spine-ts/webgl/example/assets/" cp -f ../owl/export/owl-pma.atlas "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../owl/export/owl-pma.png "$ROOT/spine-ts/webgl/example/assets/" cp -f ../owl/export/owl-pma.png "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../stretchyman/export/stretchyman-pro.json "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../stretchyman/export/stretchyman-pro.skel "$ROOT/spine-ts/webgl/example/assets/" cp -f ../stretchyman/export/stretchyman-pro.skel "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../stretchyman/export/stretchyman-pma.atlas "$ROOT/spine-ts/webgl/example/assets/" cp -f ../stretchyman/export/stretchyman-pma.atlas "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../stretchyman/export/stretchyman-pma.png "$ROOT/spine-ts/webgl/example/assets/" cp -f ../stretchyman/export/stretchyman-pma.png "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../mix-and-match/export/mix-and-match-pro.json "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../mix-and-match/export/mix-and-match-pro.skel "$ROOT/spine-ts/webgl/example/assets/" cp -f ../mix-and-match/export/mix-and-match-pro.skel "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../mix-and-match/export/mix-and-match-pma.atlas "$ROOT/spine-ts/webgl/example/assets/" cp -f ../mix-and-match/export/mix-and-match-pma.atlas "$ROOT/spine-ts/webgl/example/assets/"
cp -f ../mix-and-match/export/mix-and-match-pma.png "$ROOT/spine-ts/webgl/example/assets/" cp -f ../mix-and-match/export/mix-and-match-pma.png "$ROOT/spine-ts/webgl/example/assets/"

View File

@ -2,17 +2,13 @@ declare module spine {
class Animation { class Animation {
name: string; name: string;
timelines: Array<Timeline>; timelines: Array<Timeline>;
timelineIds: Array<boolean>; timelineIds: StringSet;
duration: number; duration: number;
constructor(name: string, timelines: Array<Timeline>, duration: number); constructor(name: string, timelines: Array<Timeline>, duration: number);
hasTimeline(id: number): boolean; hasTimeline(ids: string[]): boolean;
apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
static binarySearch(values: ArrayLike<number>, target: number, step?: number): number; static search(frames: ArrayLike<number>, time: number): number;
static linearSearch(values: ArrayLike<number>, target: number, step: number): number; static search2(values: ArrayLike<number>, target: number, step: number): number;
}
interface Timeline {
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
getPropertyId(): number;
} }
enum MixBlend { enum MixBlend {
setup = 0, setup = 0,
@ -24,103 +20,105 @@ declare module spine {
mixIn = 0, mixIn = 0,
mixOut = 1 mixOut = 1
} }
enum TimelineType { enum Property {
rotate = 0, rotate = 0,
translate = 1, translateX = 1,
scale = 2, translateY = 2,
shear = 3, scaleX = 3,
attachment = 4, scaleY = 4,
color = 5, shearX = 5,
deform = 6, shearY = 6,
event = 7, rgba = 7,
drawOrder = 8, rgb2 = 8,
ikConstraint = 9, attachment = 9,
transformConstraint = 10, deform = 10,
pathConstraintPosition = 11, event = 11,
pathConstraintSpacing = 12, drawOrder = 12,
pathConstraintMix = 13, ikConstraint = 13,
twoColor = 14 transformConstraint = 14,
pathConstraintPosition = 15,
pathConstraintSpacing = 16,
pathConstraintMix = 17
} }
abstract class CurveTimeline implements Timeline { abstract class Timeline {
propertyIds: string[];
frames: ArrayLike<number>;
constructor(frameCount: number, propertyIds: string[]);
abstract getFrameEntries(): number;
getFrameCount(): number;
getDuration(): number;
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
getPropertyIds(): string[];
}
interface BoneTimeline {
boneIndex: number;
}
interface SlotTimeline {
slotIndex: number;
}
abstract class CurveTimeline extends Timeline {
static LINEAR: number; static LINEAR: number;
static STEPPED: number; static STEPPED: number;
static BEZIER: number; static BEZIER: number;
static BEZIER_SIZE: number; static BEZIER_SIZE: number;
private curves; protected curves: ArrayLike<number>;
abstract getPropertyId(): number; constructor(frameCount: number, bezierCount: number, propertyIds: string[]);
constructor(frameCount: number); setLinear(frame: number): void;
getFrameCount(): number; setStepped(frame: number): void;
setLinear(frameIndex: number): void; shrink(bezierCount: number): void;
setStepped(frameIndex: number): void; setBezier(bezier: number, frame: number, value: number, time1: number, value1: number, cx1: number, cy1: number, cx2: number, cy2: number, time2: number, value2: number): void;
getCurveType(frameIndex: number): number; getBezierValue(time: number, frameIndex: number, valueOffset: number, i: number): number;
setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
getCurvePercent(frameIndex: number, percent: number): number;
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class RotateTimeline extends CurveTimeline { abstract class CurveTimeline1 extends CurveTimeline {
static ENTRIES: number; static ENTRIES: number;
static PREV_TIME: number; static VALUE: number;
static PREV_ROTATION: number; constructor(frameCount: number, bezierCount: number, propertyIds: string[]);
static ROTATION: number; getFrameEntries(): number;
setFrame(frame: number, time: number, value: number): void;
getCurveValue(time: number): number;
}
abstract class CurveTimeline2 extends CurveTimeline {
static ENTRIES: number;
static VALUE1: number;
static VALUE2: number;
constructor(frameCount: number, bezierCount: number, propertyIds: string[]);
getFrameEntries(): number;
setFrame(frame: number, time: number, value1: number, value2: number): void;
}
class RotateTimeline extends CurveTimeline1 implements BoneTimeline {
boneIndex: number; boneIndex: number;
frames: ArrayLike<number>; constructor(frameCount: number, bezierCount: number, boneIndex: number);
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, degrees: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class TranslateTimeline extends CurveTimeline { class TranslateTimeline extends CurveTimeline2 implements BoneTimeline {
static ENTRIES: number;
static PREV_TIME: number;
static PREV_X: number;
static PREV_Y: number;
static X: number;
static Y: number;
boneIndex: number; boneIndex: number;
frames: ArrayLike<number>; constructor(frameCount: number, bezierCount: number, boneIndex: number);
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, x: number, y: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class ScaleTimeline extends TranslateTimeline { class ScaleTimeline extends CurveTimeline2 implements BoneTimeline {
constructor(frameCount: number); boneIndex: number;
getPropertyId(): number; constructor(frameCount: number, bezierCount: number, boneIndex: number);
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class ShearTimeline extends TranslateTimeline { class ShearTimeline extends CurveTimeline2 implements BoneTimeline {
constructor(frameCount: number); boneIndex: number;
getPropertyId(): number; constructor(frameCount: number, bezierCount: number, boneIndex: number);
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class ColorTimeline extends CurveTimeline { class ColorTimeline extends CurveTimeline implements SlotTimeline {
static ENTRIES: number; static ENTRIES: number;
static PREV_TIME: number;
static PREV_R: number;
static PREV_G: number;
static PREV_B: number;
static PREV_A: number;
static R: number; static R: number;
static G: number; static G: number;
static B: number; static B: number;
static A: number; static A: number;
slotIndex: number; slotIndex: number;
frames: ArrayLike<number>; constructor(frameCount: number, bezierCount: number, slotIndex: number);
constructor(frameCount: number); getFrameEntries(): number;
getPropertyId(): number;
setFrame(frameIndex: number, time: number, r: number, g: number, b: number, a: number): void; setFrame(frameIndex: number, time: number, r: number, g: number, b: number, a: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class TwoColorTimeline extends CurveTimeline { class TwoColorTimeline extends CurveTimeline implements SlotTimeline {
static ENTRIES: number; static ENTRIES: number;
static PREV_TIME: number;
static PREV_R: number;
static PREV_G: number;
static PREV_B: number;
static PREV_A: number;
static PREV_R2: number;
static PREV_G2: number;
static PREV_B2: number;
static R: number; static R: number;
static G: number; static G: number;
static B: number; static B: number;
@ -129,124 +127,94 @@ declare module spine {
static G2: number; static G2: number;
static B2: number; static B2: number;
slotIndex: number; slotIndex: number;
frames: ArrayLike<number>; constructor(frameCount: number, bezierCount: number, slotIndex: number);
constructor(frameCount: number); getFrameEntries(): number;
getPropertyId(): number;
setFrame(frameIndex: number, time: number, r: number, g: number, b: number, a: number, r2: number, g2: number, b2: number): void; setFrame(frameIndex: number, time: number, r: number, g: number, b: number, a: number, r2: number, g2: number, b2: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class AttachmentTimeline implements Timeline { class AttachmentTimeline extends Timeline implements SlotTimeline {
slotIndex: number; slotIndex: number;
frames: ArrayLike<number>;
attachmentNames: Array<string>; attachmentNames: Array<string>;
constructor(frameCount: number); constructor(frameCount: number, slotIndex: number);
getPropertyId(): number; getFrameEntries(): number;
getFrameCount(): number; getFrameCount(): number;
setFrame(frameIndex: number, time: number, attachmentName: string): void; setFrame(frameIndex: number, time: number, attachmentName: string): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
setAttachment(skeleton: Skeleton, slot: Slot, attachmentName: string): void; setAttachment(skeleton: Skeleton, slot: Slot, attachmentName: string): void;
} }
class DeformTimeline extends CurveTimeline { class DeformTimeline extends CurveTimeline implements SlotTimeline {
slotIndex: number; slotIndex: number;
attachment: VertexAttachment; attachment: VertexAttachment;
frames: ArrayLike<number>; vertices: Array<ArrayLike<number>>;
frameVertices: Array<ArrayLike<number>>; constructor(frameCount: number, bezierCount: number, slotIndex: number, attachment: VertexAttachment);
constructor(frameCount: number); getFrameEntries(): number;
getPropertyId(): number;
setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void; setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
setBezier(bezier: number, frame: number, value: number, time1: number, value1: number, cx1: number, cy1: number, cx2: number, cy2: number, time2: number, value2: number): void;
getCurvePercent(time: number, frame: number): number;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class EventTimeline implements Timeline { class EventTimeline extends Timeline {
frames: ArrayLike<number>; static propertyIds: string[];
events: Array<Event>; events: Array<Event>;
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getFrameEntries(): number;
getFrameCount(): number;
setFrame(frameIndex: number, event: Event): void; setFrame(frameIndex: number, event: Event): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class DrawOrderTimeline implements Timeline { class DrawOrderTimeline extends Timeline {
frames: ArrayLike<number>; static propertyIds: string[];
drawOrders: Array<Array<number>>; drawOrders: Array<Array<number>>;
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getFrameEntries(): number;
getFrameCount(): number;
setFrame(frameIndex: number, time: number, drawOrder: Array<number>): void; setFrame(frameIndex: number, time: number, drawOrder: Array<number>): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class IkConstraintTimeline extends CurveTimeline { class IkConstraintTimeline extends CurveTimeline {
static ENTRIES: number; static ENTRIES: number;
static PREV_TIME: number;
static PREV_MIX: number;
static PREV_SOFTNESS: number;
static PREV_BEND_DIRECTION: number;
static PREV_COMPRESS: number;
static PREV_STRETCH: number;
static MIX: number; static MIX: number;
static SOFTNESS: number; static SOFTNESS: number;
static BEND_DIRECTION: number; static BEND_DIRECTION: number;
static COMPRESS: number; static COMPRESS: number;
static STRETCH: number; static STRETCH: number;
ikConstraintIndex: number; ikConstraintIndex: number;
frames: ArrayLike<number>; constructor(frameCount: number, bezierCount: number, ikConstraintIndex: number);
constructor(frameCount: number); getFrameEntries(): number;
getPropertyId(): number; setFrame(frame: number, time: number, mix: number, softness: number, bendDirection: number, compress: boolean, stretch: boolean): void;
setFrame(frameIndex: number, time: number, mix: number, softness: number, bendDirection: number, compress: boolean, stretch: boolean): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class TransformConstraintTimeline extends CurveTimeline { class TransformConstraintTimeline extends CurveTimeline {
static ENTRIES: number; static ENTRIES: number;
static PREV_TIME: number;
static PREV_ROTATE: number;
static PREV_TRANSLATE: number;
static PREV_SCALE: number;
static PREV_SHEAR: number;
static ROTATE: number; static ROTATE: number;
static TRANSLATE: number; static TRANSLATE: number;
static SCALE: number; static SCALE: number;
static SHEAR: number; static SHEAR: number;
transformConstraintIndex: number; transformConstraintIndex: number;
frames: ArrayLike<number>; constructor(frameCount: number, bezierCount: number, transformConstraintIndex: number);
constructor(frameCount: number); getFrameEntries(): number;
getPropertyId(): number; setFrame(frame: number, time: number, rotateMix: number, translateMix: number, scaleMix: number, shearMix: number): void;
setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number, scaleMix: number, shearMix: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class PathConstraintPositionTimeline extends CurveTimeline { class PathConstraintPositionTimeline extends CurveTimeline1 {
static ENTRIES: number;
static PREV_TIME: number;
static PREV_VALUE: number;
static VALUE: number;
pathConstraintIndex: number; pathConstraintIndex: number;
frames: ArrayLike<number>; constructor(frameCount: number, bezierCount: number, pathConstraintIndex: number);
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, value: number): void; setFrame(frameIndex: number, time: number, value: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline { class PathConstraintSpacingTimeline extends CurveTimeline1 {
constructor(frameCount: number); pathConstraintIndex: number;
getPropertyId(): number; constructor(frameCount: number, bezierCount: number, pathConstraintIndex: number);
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class PathConstraintMixTimeline extends CurveTimeline { class PathConstraintMixTimeline extends CurveTimeline2 {
static ENTRIES: number;
static PREV_TIME: number;
static PREV_ROTATE: number;
static PREV_TRANSLATE: number;
static ROTATE: number;
static TRANSLATE: number;
pathConstraintIndex: number; pathConstraintIndex: number;
frames: ArrayLike<number>; constructor(frameCount: number, bezierCount: number, pathConstraintIndex: number);
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
} }
declare module spine { declare module spine {
class AnimationState { class AnimationState {
static emptyAnimation: Animation; private static _emptyAnimation;
private static emptyAnimation;
static SUBSEQUENT: number; static SUBSEQUENT: number;
static FIRST: number; static FIRST: number;
static HOLD_SUBSEQUENT: number; static HOLD_SUBSEQUENT: number;
@ -261,7 +229,7 @@ declare module spine {
events: Event[]; events: Event[];
listeners: AnimationStateListener[]; listeners: AnimationStateListener[];
queue: EventQueue; queue: EventQueue;
propertyIDs: IntSet; propertyIDs: StringSet;
animationsChanged: boolean; animationsChanged: boolean;
trackEntryPool: Pool<TrackEntry>; trackEntryPool: Pool<TrackEntry>;
constructor(data: AnimationStateData); constructor(data: AnimationStateData);
@ -275,6 +243,7 @@ declare module spine {
queueEvents(entry: TrackEntry, animationTime: number): void; queueEvents(entry: TrackEntry, animationTime: number): void;
clearTracks(): void; clearTracks(): void;
clearTrack(trackIndex: number): void; clearTrack(trackIndex: number): void;
clearNext(entry: TrackEntry): void;
setCurrent(index: number, current: TrackEntry, interrupt: boolean): void; setCurrent(index: number, current: TrackEntry, interrupt: boolean): void;
setAnimation(trackIndex: number, animationName: string, loop: boolean): TrackEntry; setAnimation(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
setAnimationWith(trackIndex: number, animation: Animation, loop: boolean): TrackEntry; setAnimationWith(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
@ -296,6 +265,7 @@ declare module spine {
} }
class TrackEntry { class TrackEntry {
animation: Animation; animation: Animation;
previous: TrackEntry;
next: TrackEntry; next: TrackEntry;
mixingFrom: TrackEntry; mixingFrom: TrackEntry;
mixingTo: TrackEntry; mixingTo: TrackEntry;
@ -303,6 +273,7 @@ declare module spine {
trackIndex: number; trackIndex: number;
loop: boolean; loop: boolean;
holdPrevious: boolean; holdPrevious: boolean;
reverse: boolean;
eventThreshold: number; eventThreshold: number;
attachmentThreshold: number; attachmentThreshold: number;
drawOrderThreshold: number; drawOrderThreshold: number;
@ -330,6 +301,7 @@ declare module spine {
setAnimationLast(animationLast: number): void; setAnimationLast(animationLast: number): void;
isComplete(): boolean; isComplete(): boolean;
resetRotationDirections(): void; resetRotationDirections(): void;
getTrackComplete(): number;
} }
class EventQueue { class EventQueue {
objects: Array<any>; objects: Array<any>;
@ -588,7 +560,6 @@ declare module spine {
active: boolean; active: boolean;
constructor(data: PathConstraintData, skeleton: Skeleton); constructor(data: PathConstraintData, skeleton: Skeleton);
isActive(): boolean; isActive(): boolean;
apply(): void;
update(): void; update(): void;
computeWorldPositions(path: PathAttachment, spacesCount: number, tangents: boolean, percentPosition: boolean, percentSpacing: boolean): number[]; computeWorldPositions(path: PathAttachment, spacesCount: number, tangents: boolean, percentPosition: boolean, percentSpacing: boolean): number[];
addBeforePosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number): void; addBeforePosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number): void;
@ -655,7 +626,6 @@ declare module spine {
transformConstraints: Array<TransformConstraint>; transformConstraints: Array<TransformConstraint>;
pathConstraints: Array<PathConstraint>; pathConstraints: Array<PathConstraint>;
_updateCache: Updatable[]; _updateCache: Updatable[];
updateCacheReset: Updatable[];
skin: Skin; skin: Skin;
color: Color; color: Color;
time: number; time: number;
@ -673,6 +643,7 @@ declare module spine {
sortBone(bone: Bone): void; sortBone(bone: Bone): void;
sortReset(bones: Array<Bone>): void; sortReset(bones: Array<Bone>): void;
updateWorldTransform(): void; updateWorldTransform(): void;
updateWorldTransformWith(parent: Bone): void;
setToSetupPose(): void; setToSetupPose(): void;
setBonesToSetupPose(): void; setBonesToSetupPose(): void;
setSlotsToSetupPose(): void; setSlotsToSetupPose(): void;
@ -694,7 +665,7 @@ declare module spine {
} }
} }
declare module spine { declare module spine {
class SkeletonBinary { export class SkeletonBinary {
static AttachmentTypeValues: number[]; static AttachmentTypeValues: number[];
static TransformModeValues: TransformMode[]; static TransformModeValues: TransformMode[];
static PositionModeValues: PositionMode[]; static PositionModeValues: PositionMode[];
@ -725,9 +696,26 @@ declare module spine {
private readFloatArray; private readFloatArray;
private readShortArray; private readShortArray;
private readAnimation; private readAnimation;
private readCurve; static readTimeline(input: BinaryInput, timeline: CurveTimeline1, scale: number): Timeline;
setCurve(timeline: CurveTimeline, frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void; static readTimeline2(input: BinaryInput, timeline: CurveTimeline2, scale: number): Timeline;
static setBezier(input: BinaryInput, timeline: CurveTimeline, bezier: number, frame: number, value: number, time1: number, time2: number, value1: number, value2: number, scale: number): void;
} }
class BinaryInput {
strings: string[];
private index;
private buffer;
constructor(data: Uint8Array, strings?: string[], index?: number, buffer?: DataView);
readByte(): number;
readUnsignedByte(): number;
readShort(): number;
readInt32(): number;
readInt(optimizePositive: boolean): number;
readStringRef(): string;
readString(): string;
readFloat(): number;
readBoolean(): boolean;
}
export {};
} }
declare module spine { declare module spine {
class SkeletonBounds { class SkeletonBounds {
@ -815,7 +803,10 @@ declare module spine {
readAttachment(map: any, skin: Skin, slotIndex: number, name: string, skeletonData: SkeletonData): Attachment; readAttachment(map: any, skin: Skin, slotIndex: number, name: string, skeletonData: SkeletonData): Attachment;
readVertices(map: any, attachment: VertexAttachment, verticesLength: number): void; readVertices(map: any, attachment: VertexAttachment, verticesLength: number): void;
readAnimation(map: any, name: string, skeletonData: SkeletonData): void; readAnimation(map: any, name: string, skeletonData: SkeletonData): void;
readCurve(map: any, timeline: CurveTimeline, frameIndex: number): void; private readTimeline;
private readTimeline2;
private readCurve;
setBezier(timeline: CurveTimeline, frame: number, value: number, bezier: number, time1: number, value1: number, cx1: number, cy1: number, cx2: number, cy2: number, time2: number, value2: number): void;
getValue(map: any, prop: string, defaultValue: any): any; getValue(map: any, prop: string, defaultValue: any): any;
static blendModeFromString(str: string): BlendMode; static blendModeFromString(str: string): BlendMode;
static positionModeFromString(str: string): PositionMode; static positionModeFromString(str: string): PositionMode;
@ -967,7 +958,6 @@ declare module spine {
active: boolean; active: boolean;
constructor(data: TransformConstraintData, skeleton: Skeleton); constructor(data: TransformConstraintData, skeleton: Skeleton);
isActive(): boolean; isActive(): boolean;
apply(): void;
update(): void; update(): void;
applyAbsoluteWorld(): void; applyAbsoluteWorld(): void;
applyRelativeWorld(): void; applyRelativeWorld(): void;
@ -1027,6 +1017,14 @@ declare module spine {
remove(value: number): void; remove(value: number): void;
clear(): void; clear(): void;
} }
class StringSet {
entries: Map<boolean>;
size: number;
add(value: string): boolean;
addAll(values: string[]): boolean;
contains(value: string): boolean;
clear(): void;
}
interface Disposable { interface Disposable {
dispose(): void; dispose(): void;
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,12 @@ module spine {
* *
* See [Applying Animations](http://esotericsoftware.com/spine-applying-animations/) in the Spine Runtimes Guide. */ * See [Applying Animations](http://esotericsoftware.com/spine-applying-animations/) in the Spine Runtimes Guide. */
export class AnimationState { export class AnimationState {
static emptyAnimation = new Animation("<empty>", [], 0); private static _emptyAnimation: Animation = null;
private static emptyAnimation(): Animation {
if (AnimationState._emptyAnimation == null) AnimationState._emptyAnimation = new Animation("<empty>", [], 0);
return AnimationState._emptyAnimation;
}
/** 1. A previously applied timeline has set this property. /** 1. A previously applied timeline has set this property.
* *
@ -90,7 +95,7 @@ module spine {
events = new Array<Event>(); events = new Array<Event>();
listeners = new Array<AnimationStateListener>(); listeners = new Array<AnimationStateListener>();
queue = new EventQueue(this); queue = new EventQueue(this);
propertyIDs = new IntSet(); propertyIDs = new StringSet();
animationsChanged = false; animationsChanged = false;
trackEntryPool = new Pool<TrackEntry>(() => new TrackEntry()); trackEntryPool = new Pool<TrackEntry>(() => new TrackEntry());
@ -209,7 +214,12 @@ module spine {
mix = 0; mix = 0;
// Apply current entry. // Apply current entry.
let animationLast = current.animationLast, animationTime = current.getAnimationTime(); let animationLast = current.animationLast, animationTime = current.getAnimationTime(), applyTime = animationTime;
let applyEvents = events;
if (current.reverse) {
applyTime = current.animation.duration - applyTime;
applyEvents = null;
}
let timelineCount = current.animation.timelines.length; let timelineCount = current.animation.timelines.length;
let timelines = current.animation.timelines; let timelines = current.animation.timelines;
if ((i == 0 && mix == 1) || blend == MixBlend.add) { if ((i == 0 && mix == 1) || blend == MixBlend.add) {
@ -220,9 +230,9 @@ module spine {
Utils.webkit602BugfixHelper(mix, blend); Utils.webkit602BugfixHelper(mix, blend);
var timeline = timelines[ii]; var timeline = timelines[ii];
if (timeline instanceof AttachmentTimeline) if (timeline instanceof AttachmentTimeline)
this.applyAttachmentTimeline(timeline, skeleton, animationTime, blend, true); this.applyAttachmentTimeline(timeline, skeleton, applyTime, blend, true);
else else
timeline.apply(skeleton, animationLast, animationTime, events, mix, blend, MixDirection.mixIn); timeline.apply(skeleton, animationLast, applyTime, applyEvents, mix, blend, MixDirection.mixIn);
} }
} else { } else {
let timelineMode = current.timelineMode; let timelineMode = current.timelineMode;
@ -235,13 +245,13 @@ module spine {
let timeline = timelines[ii]; let timeline = timelines[ii];
let timelineBlend = timelineMode[ii] == AnimationState.SUBSEQUENT ? blend : MixBlend.setup; let timelineBlend = timelineMode[ii] == AnimationState.SUBSEQUENT ? blend : MixBlend.setup;
if (timeline instanceof RotateTimeline) { if (timeline instanceof RotateTimeline) {
this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame); this.applyRotateTimeline(timeline, skeleton, applyTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
} else if (timeline instanceof AttachmentTimeline) { } else if (timeline instanceof AttachmentTimeline) {
this.applyAttachmentTimeline(timeline, skeleton, animationTime, blend, true); this.applyAttachmentTimeline(timeline, skeleton, applyTime, blend, true);
} else { } else {
// This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109
Utils.webkit602BugfixHelper(mix, blend); Utils.webkit602BugfixHelper(mix, blend);
timeline.apply(skeleton, animationLast, animationTime, events, mix, timelineBlend, MixDirection.mixIn); timeline.apply(skeleton, animationLast, applyTime, applyEvents, mix, timelineBlend, MixDirection.mixIn);
} }
} }
} }
@ -283,15 +293,23 @@ module spine {
if (blend != MixBlend.first) blend = from.mixBlend; if (blend != MixBlend.first) blend = from.mixBlend;
} }
let events = mix < from.eventThreshold ? this.events : null;
let attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold; let attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold;
let animationLast = from.animationLast, animationTime = from.getAnimationTime();
let timelineCount = from.animation.timelines.length; let timelineCount = from.animation.timelines.length;
let timelines = from.animation.timelines; let timelines = from.animation.timelines;
let alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix); let alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix);
let animationLast = from.animationLast, animationTime = from.getAnimationTime(), applyTime = animationTime;
let events = null;
// let events = mix < from.eventThreshold ? this.events : null;
if (from.reverse) {
applyTime = from.animation.duration - applyTime;
} else {
if (mix < from.eventThreshold) events = this.events;
}
if (blend == MixBlend.add) { if (blend == MixBlend.add) {
for (let i = 0; i < timelineCount; i++) for (let i = 0; i < timelineCount; i++)
timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, MixDirection.mixOut); timelines[i].apply(skeleton, animationLast, applyTime, events, alphaMix, blend, MixDirection.mixOut);
} else { } else {
let timelineMode = from.timelineMode; let timelineMode = from.timelineMode;
let timelineHoldMix = from.timelineHoldMix; let timelineHoldMix = from.timelineHoldMix;
@ -333,15 +351,15 @@ module spine {
from.totalAlpha += alpha; from.totalAlpha += alpha;
if (timeline instanceof RotateTimeline) if (timeline instanceof RotateTimeline)
this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame); this.applyRotateTimeline(timeline, skeleton, applyTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame);
else if (timeline instanceof AttachmentTimeline) else if (timeline instanceof AttachmentTimeline)
this.applyAttachmentTimeline(timeline, skeleton, animationTime, timelineBlend, attachments); this.applyAttachmentTimeline(timeline, skeleton, applyTime, timelineBlend, attachments);
else { else {
// This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 // This fixes the WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109
Utils.webkit602BugfixHelper(alpha, blend); Utils.webkit602BugfixHelper(alpha, blend);
if (drawOrder && timeline instanceof DrawOrderTimeline && timelineBlend == MixBlend.setup) if (drawOrder && timeline instanceof DrawOrderTimeline && timelineBlend == MixBlend.setup)
direction = MixDirection.mixIn; direction = MixDirection.mixIn;
timeline.apply(skeleton, animationLast, animationTime, events, alpha, timelineBlend, direction); timeline.apply(skeleton, animationLast, applyTime, events, alpha, timelineBlend, direction);
} }
} }
} }
@ -364,14 +382,8 @@ module spine {
if (blend == MixBlend.setup || blend == MixBlend.first) if (blend == MixBlend.setup || blend == MixBlend.first)
this.setAttachment(skeleton, slot, slot.data.attachmentName, attachments); this.setAttachment(skeleton, slot, slot.data.attachmentName, attachments);
} }
else {
var frameIndex;
if (time >= frames[frames.length - 1]) // Time is after last frame.
frameIndex = frames.length - 1;
else else
frameIndex = Animation.binarySearch(frames, time) - 1; this.setAttachment(skeleton, slot, timeline.attachmentNames[Animation.search(frames, time)], attachments);
this.setAttachment(skeleton, slot, timeline.attachmentNames[frameIndex], attachments);
}
// If an attachment wasn't set (ie before the first frame or attachments is false), set the setup attachment later. // If an attachment wasn't set (ie before the first frame or attachments is false), set the setup attachment later.
if (slot.attachmentState <= this.unkeyedState) slot.attachmentState = this.unkeyedState + AnimationState.SETUP; if (slot.attachmentState <= this.unkeyedState) slot.attachmentState = this.unkeyedState + AnimationState.SETUP;
@ -410,21 +422,7 @@ module spine {
} }
} else { } else {
r1 = blend == MixBlend.setup ? bone.data.rotation : bone.rotation; r1 = blend == MixBlend.setup ? bone.data.rotation : bone.rotation;
if (time >= frames[frames.length - RotateTimeline.ENTRIES]) // Time is after last frame. r2 = bone.data.rotation + rotateTimeline.getCurveValue(time);
r2 = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION];
else {
// Interpolate between the previous frame and the current frame.
let frame = Animation.binarySearch(frames, time, RotateTimeline.ENTRIES);
let prevRotation = frames[frame + RotateTimeline.PREV_ROTATION];
let frameTime = frames[frame];
let percent = rotateTimeline.getCurvePercent((frame >> 1) - 1,
1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime));
r2 = frames[frame + RotateTimeline.ROTATION] - prevRotation;
r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360;
r2 = prevRotation + r2 * percent + bone.data.rotation;
r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360;
}
} }
// Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. // Mix between rotations using the direction of the shortest route on the first frame while detecting crosses.
@ -453,8 +451,7 @@ module spine {
timelinesRotation[i] = total; timelinesRotation[i] = total;
} }
timelinesRotation[i + 1] = diff; timelinesRotation[i + 1] = diff;
r1 += total * alpha; bone.rotation = r1 + total * alpha;
bone.rotation = r1 - (16384 - ((16384.499999999996 - r1 / 360) | 0)) * 360;
} }
queueEvents (entry: TrackEntry, animationTime: number) { queueEvents (entry: TrackEntry, animationTime: number) {
@ -530,9 +527,15 @@ module spine {
this.queue.drain(); this.queue.drain();
} }
/** Removes the {@link TrackEntry#getNext() next entry} and all entries after it for the specified entry. */
clearNext(entry: TrackEntry) {
this.disposeNext(entry.next);
}
setCurrent (index: number, current: TrackEntry, interrupt: boolean) { setCurrent (index: number, current: TrackEntry, interrupt: boolean) {
let from = this.expandToIndex(index); let from = this.expandToIndex(index);
this.tracks[index] = current; this.tracks[index] = current;
current.previous = null;
if (from != null) { if (from != null) {
if (interrupt) this.queue.interrupt(from); if (interrupt) this.queue.interrupt(from);
@ -620,17 +623,8 @@ module spine {
this.queue.drain(); this.queue.drain();
} else { } else {
last.next = entry; last.next = entry;
if (delay <= 0) { entry.previous = last;
let duration = last.animationEnd - last.animationStart; if (delay <= 0) delay += last.getTrackComplete() - entry.mixDuration;
if (duration != 0) {
if (last.loop)
delay += duration * (1 + ((last.trackTime / duration) | 0));
else
delay += Math.max(duration, last.trackTime);
delay -= this.data.getMix(last.animation, animation);
} else
delay = last.trackTime;
}
} }
entry.delay = delay; entry.delay = delay;
@ -652,7 +646,7 @@ module spine {
* more over the mix duration. Properties keyed in the new animation transition from the value from lower tracks or from the * more over the mix duration. Properties keyed in the new animation transition from the value from lower tracks or from the
* setup pose value if no lower tracks key the property to the value keyed in the new animation. */ * setup pose value if no lower tracks key the property to the value keyed in the new animation. */
setEmptyAnimation (trackIndex: number, mixDuration: number) { setEmptyAnimation (trackIndex: number, mixDuration: number) {
let entry = this.setAnimationWith(trackIndex, AnimationState.emptyAnimation, false); let entry = this.setAnimationWith(trackIndex, AnimationState.emptyAnimation(), false);
entry.mixDuration = mixDuration; entry.mixDuration = mixDuration;
entry.trackEnd = mixDuration; entry.trackEnd = mixDuration;
return entry; return entry;
@ -670,10 +664,10 @@ module spine {
* @return A track entry to allow further customization of animation playback. References to the track entry must not be kept * @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
* after the {@link AnimationStateListener#dispose()} event occurs. */ * after the {@link AnimationStateListener#dispose()} event occurs. */
addEmptyAnimation (trackIndex: number, mixDuration: number, delay: number) { addEmptyAnimation (trackIndex: number, mixDuration: number, delay: number) {
if (delay <= 0) delay -= mixDuration; let entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation(), false, delay <= 0 ? 1 : delay);
let entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation, false, delay);
entry.mixDuration = mixDuration; entry.mixDuration = mixDuration;
entry.trackEnd = mixDuration; entry.trackEnd = mixDuration;
if (delay <= 0 && entry.previous != null) entry.delay = entry.previous.getTrackComplete() - entry.mixDuration;
return entry; return entry;
} }
@ -767,7 +761,7 @@ module spine {
if (to != null && to.holdPrevious) { if (to != null && to.holdPrevious) {
for (let i = 0; i < timelinesCount; i++) { for (let i = 0; i < timelinesCount; i++) {
timelineMode[i] = propertyIDs.add(timelines[i].getPropertyId()) ? AnimationState.HOLD_FIRST : AnimationState.HOLD_SUBSEQUENT; timelineMode[i] = propertyIDs.addAll(timelines[i].getPropertyIds()) ? AnimationState.HOLD_FIRST : AnimationState.HOLD_SUBSEQUENT;
} }
return; return;
} }
@ -775,15 +769,15 @@ module spine {
outer: outer:
for (let i = 0; i < timelinesCount; i++) { for (let i = 0; i < timelinesCount; i++) {
let timeline = timelines[i]; let timeline = timelines[i];
let id = timeline.getPropertyId(); let ids = timeline.getPropertyIds();
if (!propertyIDs.add(id)) if (!propertyIDs.addAll(ids))
timelineMode[i] = AnimationState.SUBSEQUENT; timelineMode[i] = AnimationState.SUBSEQUENT;
else if (to == null || timeline instanceof AttachmentTimeline || timeline instanceof DrawOrderTimeline else if (to == null || timeline instanceof AttachmentTimeline || timeline instanceof DrawOrderTimeline
|| timeline instanceof EventTimeline || !to.animation.hasTimeline(id)) { || timeline instanceof EventTimeline || !to.animation.hasTimeline(ids)) {
timelineMode[i] = AnimationState.FIRST; timelineMode[i] = AnimationState.FIRST;
} else { } else {
for (let next = to.mixingTo; next != null; next = next.mixingTo) { for (let next = to.mixingTo; next != null; next = next.mixingTo) {
if (next.animation.hasTimeline(id)) continue; if (next.animation.hasTimeline(ids)) continue;
if (entry.mixDuration > 0) { if (entry.mixDuration > 0) {
timelineMode[i] = AnimationState.HOLD_MIX; timelineMode[i] = AnimationState.HOLD_MIX;
timelineDipMix[i] = next; timelineDipMix[i] = next;
@ -834,6 +828,8 @@ module spine {
/** The animation to apply for this track entry. */ /** The animation to apply for this track entry. */
animation: Animation; animation: Animation;
previous: TrackEntry;
/** The animation queued to start after this animation, or null. `next` makes up a linked list. */ /** The animation queued to start after this animation, or null. `next` makes up a linked list. */
next: TrackEntry; next: TrackEntry;
@ -873,6 +869,8 @@ module spine {
* previous animation. */ * previous animation. */
holdPrevious: boolean; holdPrevious: boolean;
reverse: boolean;
/** When the mix percentage ({@link #mixTime} / {@link #mixDuration}) is less than the /** When the mix percentage ({@link #mixTime} / {@link #mixDuration}) is less than the
* `eventThreshold`, event timelines are applied while this animation is being mixed out. Defaults to 0, so event * `eventThreshold`, 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. */ * timelines are not applied while this animation is being mixed out. */
@ -982,6 +980,7 @@ module spine {
timelinesRotation = new Array<number>(); timelinesRotation = new Array<number>();
reset () { reset () {
this.previous = null;
this.next = null; this.next = null;
this.mixingFrom = null; this.mixingFrom = null;
this.mixingTo = null; this.mixingTo = null;
@ -1026,6 +1025,15 @@ module spine {
resetRotationDirections () { resetRotationDirections () {
this.timelinesRotation.length = 0; this.timelinesRotation.length = 0;
} }
getTrackComplete() {
let duration = this.animationEnd - this.animationStart;
if (duration != 0) {
if (this.loop) return duration * (1 + Math.floor(this.trackTime / duration)); // Completion of next loop.
if (this.trackTime < duration) return duration; // Before duration.
}
return this.trackTime; // Next update.
}
} }
export class EventQueue { export class EventQueue {

View File

@ -340,10 +340,10 @@ module spine {
/** Transforms a point from world coordinates to the bone's local coordinates. */ /** Transforms a point from world coordinates to the bone's local coordinates. */
worldToLocal (world: Vector2) { worldToLocal (world: Vector2) {
let a = this.a, b = this.b, c = this.c, d = this.d; let a = this.a, b = this.b, c = this.c, d = this.d;
let invDet = 1 / (a * d - b * c); let det = a * d - b * c;
let x = world.x - this.worldX, y = world.y - this.worldY; let x = world.x - this.worldX, y = world.y - this.worldY;
world.x = (x * d * invDet - y * b * invDet); world.x = (x * d - y * b) / det;
world.y = (y * a * invDet - x * c * invDet); world.y = (y * a - x * c) / det;
return world; return world;
} }

View File

@ -86,6 +86,7 @@ module spine {
} }
update () { update () {
if (this.mix == 0) return;
let target = this.target; let target = this.target;
let bones = this.bones; let bones = this.bones;
switch (bones.length) { switch (bones.length) {
@ -152,10 +153,6 @@ module spine {
/** Applies 2 bone IK. The target is specified in the world coordinate system. /** Applies 2 bone IK. The target is specified in the world coordinate system.
* @param child A direct descendant of the parent bone. */ * @param child A direct descendant of the parent bone. */
apply2 (parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, stretch: boolean, softness: number, alpha: number) { apply2 (parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, stretch: boolean, softness: number, alpha: number) {
if (alpha == 0) {
child.updateWorldTransform();
return;
}
if (!parent.appliedValid) parent.updateAppliedTransform(); if (!parent.appliedValid) parent.updateAppliedTransform();
if (!child.appliedValid) child.updateAppliedTransform(); if (!child.appliedValid) child.updateAppliedTransform();
let px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX; let px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX;

View File

@ -82,11 +82,6 @@ module spine {
return this.active; return this.active;
} }
/** Applies the constraint to the constrained bones. */
apply () {
this.update();
}
update () { update () {
let attachment = this.target.getAttachment(); let attachment = this.target.getAttachment();
if (!(attachment instanceof PathAttachment)) return; if (!(attachment instanceof PathAttachment)) return;

View File

@ -56,7 +56,6 @@ module spine {
/** The list of bones and constraints, sorted in the order they should be updated, as computed by {@link #updateCache()}. */ /** The list of bones and constraints, sorted in the order they should be updated, as computed by {@link #updateCache()}. */
_updateCache = new Array<Updatable>(); _updateCache = new Array<Updatable>();
updateCacheReset = new Array<Updatable>();
/** The skeleton's current skin. May be null. */ /** The skeleton's current skin. May be null. */
skin: Skin; skin: Skin;
@ -138,7 +137,6 @@ module spine {
updateCache () { updateCache () {
let updateCache = this._updateCache; let updateCache = this._updateCache;
updateCache.length = 0; updateCache.length = 0;
this.updateCacheReset.length = 0;
let bones = this.bones; let bones = this.bones;
for (let i = 0, n = bones.length; i < n; i++) { for (let i = 0, n = bones.length; i < n; i++) {
@ -206,15 +204,18 @@ module spine {
let parent = constrained[0]; let parent = constrained[0];
this.sortBone(parent); this.sortBone(parent);
if (constrained.length > 1) { if (constrained.length == 1) {
this._updateCache.push(constraint);
this.sortReset(parent.children);
} else {
let child = constrained[constrained.length - 1]; let child = constrained[constrained.length - 1];
if (!(this._updateCache.indexOf(child) > -1)) this.updateCacheReset.push(child); this.sortBone(child);
}
this._updateCache.push(constraint); this._updateCache.push(constraint);
this.sortReset(parent.children); this.sortReset(parent.children);
constrained[constrained.length - 1].sorted = true; child.sorted = true;
}
} }
sortPathConstraint (constraint: PathConstraint) { sortPathConstraint (constraint: PathConstraint) {
@ -258,7 +259,7 @@ module spine {
for (let i = 0; i < boneCount; i++) { for (let i = 0; i < boneCount; i++) {
let child = constrained[i]; let child = constrained[i];
this.sortBone(child.parent); this.sortBone(child.parent);
if (!(this._updateCache.indexOf(child) > -1)) this.updateCacheReset.push(child); this.sortBone(child);
} }
} else { } else {
for (let i = 0; i < boneCount; i++) { for (let i = 0; i < boneCount; i++) {
@ -322,23 +323,36 @@ module spine {
* See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine * See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine
* Runtimes Guide. */ * Runtimes Guide. */
updateWorldTransform () { updateWorldTransform () {
let updateCacheReset = this.updateCacheReset;
for (let i = 0, n = updateCacheReset.length; i < n; i++) {
let bone = updateCacheReset[i] as Bone;
bone.ax = bone.x;
bone.ay = bone.y;
bone.arotation = bone.rotation;
bone.ascaleX = bone.scaleX;
bone.ascaleY = bone.scaleY;
bone.ashearX = bone.shearX;
bone.ashearY = bone.shearY;
bone.appliedValid = true;
}
let updateCache = this._updateCache; let updateCache = this._updateCache;
for (let i = 0, n = updateCache.length; i < n; i++) for (let i = 0, n = updateCache.length; i < n; i++)
updateCache[i].update(); updateCache[i].update();
} }
updateWorldTransformWith (parent: Bone) {
// Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection.
let rootBone = this.getRootBone();
let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d;
rootBone.worldX = pa * this.x + pb * this.y + parent.worldX;
rootBone.worldY = pc * this.x + pd * this.y + parent.worldY;
let rotationY = rootBone.rotation + 90 + rootBone.shearY;
let la = MathUtils.cosDeg(rootBone.rotation + rootBone.shearX) * rootBone.scaleX;
let lb = MathUtils.cosDeg(rotationY) * rootBone.scaleY;
let lc = MathUtils.sinDeg(rootBone.rotation + rootBone.shearX) * rootBone.scaleX;
let ld = MathUtils.sinDeg(rotationY) * rootBone.scaleY;
rootBone.a = (pa * la + pb * lc) * this.scaleX;
rootBone.b = (pa * lb + pb * ld) * this.scaleX;
rootBone.c = (pc * la + pd * lc) * this.scaleY;
rootBone.d = (pc * lb + pd * ld) * this.scaleY;
// Update everything except root bone.
let updateCache = this._updateCache;
for (let i = 0, n = updateCache.length; i < n; i++) {
let updatable = updateCache[i];
if (updatable != rootBone) updatable.update();
}
}
/** Sets the bones, constraints, and slots to their setup pose values. */ /** Sets the bones, constraints, and slots to their setup pose values. */
setToSetupPose () { setToSetupPose () {
this.setBonesToSetupPose(); this.setBonesToSetupPose();

View File

@ -79,10 +79,10 @@ module spine {
let input = new BinaryInput(binary); let input = new BinaryInput(binary);
skeletonData.hash = input.readString(); let lowHash = input.readInt(false);
let highHash = input.readInt(false);
skeletonData.hash = highHash == 0 && lowHash == 0 ? null : highHash.toString(16) + lowHash.toString(16);
skeletonData.version = input.readString(); skeletonData.version = input.readString();
if ("3.8.75" == skeletonData.version)
throw new Error("Unsupported skeleton data, please export with a newer version of Spine.");
skeletonData.x = input.readFloat(); skeletonData.x = input.readFloat();
skeletonData.y = input.readFloat(); skeletonData.y = input.readFloat();
skeletonData.width = input.readFloat(); skeletonData.width = input.readFloat();
@ -298,8 +298,7 @@ module spine {
if (name == null) name = attachmentName; if (name == null) name = attachmentName;
let typeIndex = input.readByte(); let typeIndex = input.readByte();
let type = SkeletonBinary.AttachmentTypeValues[typeIndex]; switch (SkeletonBinary.AttachmentTypeValues[typeIndex]) {
switch (type) {
case AttachmentType.Region: { case AttachmentType.Region: {
let path = input.readStringRef(); let path = input.readStringRef();
let rotation = input.readFloat(); let rotation = input.readFloat();
@ -453,9 +452,9 @@ module spine {
} }
private readVertices (input: BinaryInput, vertexCount: number): Vertices { private readVertices (input: BinaryInput, vertexCount: number): Vertices {
let scale = this.scale;
let verticesLength = vertexCount << 1; let verticesLength = vertexCount << 1;
let vertices = new Vertices(); let vertices = new Vertices();
let scale = this.scale;
if (!input.readBoolean()) { if (!input.readBoolean()) {
vertices.vertices = this.readFloatArray(input, verticesLength, scale); vertices.vertices = this.readFloatArray(input, verticesLength, scale);
return vertices; return vertices;
@ -498,9 +497,9 @@ module spine {
} }
private readAnimation (input: BinaryInput, name: string, skeletonData: SkeletonData): Animation { private readAnimation (input: BinaryInput, name: string, skeletonData: SkeletonData): Animation {
let numTimelines = input.readInt(true);
let timelines = new Array<Timeline>(); let timelines = new Array<Timeline>();
let scale = this.scale; let scale = this.scale;
let duration = 0;
let tempColor1 = new Color(); let tempColor1 = new Color();
let tempColor2 = new Color(); let tempColor2 = new Color();
@ -510,42 +509,102 @@ module spine {
for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) {
let timelineType = input.readByte(); let timelineType = input.readByte();
let frameCount = input.readInt(true); let frameCount = input.readInt(true);
let frameLast = frameCount - 1;
switch (timelineType) { switch (timelineType) {
case SkeletonBinary.SLOT_ATTACHMENT: { case SkeletonBinary.SLOT_ATTACHMENT: {
let timeline = new AttachmentTimeline(frameCount); let timeline = new AttachmentTimeline(frameCount, slotIndex);
timeline.slotIndex = slotIndex;
for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) for (let frameIndex = 0; frameIndex < frameCount; frameIndex++)
timeline.setFrame(frameIndex, input.readFloat(), input.readStringRef()); timeline.setFrame(frameIndex, input.readFloat(), input.readStringRef());
timelines.push(timeline); timelines.push(timeline);
duration = Math.max(duration, timeline.frames[frameCount - 1]);
break; break;
} }
case SkeletonBinary.SLOT_COLOR: { case SkeletonBinary.SLOT_COLOR: {
let timeline = new ColorTimeline(frameCount); let bezierCount = input.readInt(true);
timeline.slotIndex = slotIndex; let timeline = new ColorTimeline(frameCount, bezierCount, slotIndex);
for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {
let time = input.readFloat(); let time = input.readFloat();
Color.rgba8888ToColor(tempColor1, input.readInt32()); let r = input.readUnsignedByte() / 255.0;
timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a); let g = input.readUnsignedByte() / 255.0;
if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline); let b = input.readUnsignedByte() / 255.0;
let a = input.readUnsignedByte() / 255.0;
for (let frame = 0, bezier = 0;; frame++) {
timeline.setFrame(frame, time, r, g, b, a);
if (frame == frameLast) break;
let time2 = input.readFloat();
let r2 = input.readUnsignedByte() / 255.0;
let g2 = input.readUnsignedByte() / 255.0;
let b2 = input.readUnsignedByte() / 255.0;
let a2 = input.readUnsignedByte() / 255.0;
switch (input.readByte()) {
case SkeletonBinary.CURVE_STEPPED:
timeline.setStepped(frame);
break;
case SkeletonBinary.CURVE_BEZIER:
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 0, time, time2, r, r2, 1);
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 1, time, time2, g, g2, 1);
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 2, time, time2, b, b2, 1);
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 3, time, time2, a, a2, 1);
}
time = time2;
r = r2;
g = g2;
b = b2;
a = a2;
} }
timelines.push(timeline); timelines.push(timeline);
duration = Math.max(duration, timeline.frames[(frameCount - 1) * ColorTimeline.ENTRIES]);
break; break;
} }
case SkeletonBinary.SLOT_TWO_COLOR: { case SkeletonBinary.SLOT_TWO_COLOR: {
let timeline = new TwoColorTimeline(frameCount); let bezierCount = input.readInt(true);
timeline.slotIndex = slotIndex; let timeline = new TwoColorTimeline(frameCount, bezierCount, slotIndex);
for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {
let time = input.readFloat(); let time = input.readFloat();
Color.rgba8888ToColor(tempColor1, input.readInt32()); let r = input.readUnsignedByte() / 255.0;
Color.rgb888ToColor(tempColor2, input.readInt32()); let g = input.readUnsignedByte() / 255.0;
timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a, tempColor2.r, let b = input.readUnsignedByte() / 255.0;
tempColor2.g, tempColor2.b); let a = input.readUnsignedByte() / 255.0;
if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline); let r2 = input.readUnsignedByte() / 255.0;
let g2 = input.readUnsignedByte() / 255.0;
let b2 = input.readUnsignedByte() / 255.0;
for (let frame = 0, bezier = 0;; frame++) {
timeline.setFrame(frame, time, r, g, b, a, r2, g2, b2);
if (frame == frameLast) break;
let time2 = input.readFloat();
let nr = input.readUnsignedByte() / 255.0;
let ng = input.readUnsignedByte() / 255.0;
let nb = input.readUnsignedByte() / 255.0;
let na = input.readUnsignedByte() / 255.0;
let nr2 = input.readUnsignedByte() / 255.0;
let ng2 = input.readUnsignedByte() / 255.0;
let nb2 = input.readUnsignedByte() / 255.0;
switch (input.readByte()) {
case SkeletonBinary.CURVE_STEPPED:
timeline.setStepped(frame);
break;
case SkeletonBinary.CURVE_BEZIER:
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 0, time, time2, r, nr, 1);
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 1, time, time2, g, ng, 1);
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 2, time, time2, b, nb, 1);
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 3, time, time2, a, na, 1);
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 4, time, time2, r2, nr2, 1);
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 5, time, time2, g2, ng2, 1);
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 6, time, time2, b2, nb2, 1);
}
time = time2;
r = nr;
g = ng;
b = nb;
a = na;
r2 = nr2;
g2 = ng2;
b2 = nb2;
} }
timelines.push(timeline); timelines.push(timeline);
duration = Math.max(duration, timeline.frames[(frameCount - 1) * TwoColorTimeline.ENTRIES]);
break; break;
} }
} }
@ -558,40 +617,22 @@ module spine {
for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) {
let timelineType = input.readByte(); let timelineType = input.readByte();
let frameCount = input.readInt(true); let frameCount = input.readInt(true);
let bezierCount = input.readInt(true);
switch (timelineType) { switch (timelineType) {
case SkeletonBinary.BONE_ROTATE: { case SkeletonBinary.BONE_ROTATE: {
let timeline = new RotateTimeline(frameCount); timelines.push(SkeletonBinary.readTimeline(input, new RotateTimeline(frameCount, bezierCount, boneIndex), 1));
timeline.boneIndex = boneIndex; break;
for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) { }
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat()); case SkeletonBinary.BONE_TRANSLATE: {
if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline); timelines.push(SkeletonBinary.readTimeline2(input, new TranslateTimeline(frameCount, bezierCount, boneIndex), scale));
} break;
timelines.push(timeline); }
duration = Math.max(duration, timeline.frames[(frameCount - 1) * RotateTimeline.ENTRIES]); case SkeletonBinary.BONE_SCALE: {
timelines.push(SkeletonBinary.readTimeline2(input, new ScaleTimeline(frameCount, bezierCount, boneIndex), 1));
break; break;
} }
case SkeletonBinary.BONE_TRANSLATE:
case SkeletonBinary.BONE_SCALE:
case SkeletonBinary.BONE_SHEAR: { case SkeletonBinary.BONE_SHEAR: {
let timeline; timelines.push(SkeletonBinary.readTimeline2(input, new ShearTimeline(frameCount, bezierCount, boneIndex), 1));
let timelineScale = 1;
if (timelineType == SkeletonBinary.BONE_SCALE)
timeline = new ScaleTimeline(frameCount);
else if (timelineType == SkeletonBinary.BONE_SHEAR)
timeline = new ShearTimeline(frameCount);
else {
timeline = new TranslateTimeline(frameCount);
timelineScale = scale;
}
timeline.boneIndex = boneIndex;
for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat() * timelineScale,
input.readFloat() * timelineScale);
if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline);
}
timelines.push(timeline);
duration = Math.max(duration, timeline.frames[(frameCount - 1) * TranslateTimeline.ENTRIES]);
break;
} }
} }
} }
@ -601,30 +642,73 @@ module spine {
for (let i = 0, n = input.readInt(true); i < n; i++) { for (let i = 0, n = input.readInt(true); i < n; i++) {
let index = input.readInt(true); let index = input.readInt(true);
let frameCount = input.readInt(true); let frameCount = input.readInt(true);
let timeline = new IkConstraintTimeline(frameCount); let bezierCount = input.readInt(true);
timeline.ikConstraintIndex = index; let frameLast = frameCount - 1;
for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) { let timeline = new IkConstraintTimeline(frameCount, bezierCount, index);
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat() * scale, input.readByte(), input.readBoolean(),
input.readBoolean()); let time = input.readFloat();
if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline); let mix = input.readFloat();
let softness = input.readFloat() * scale;
for (let frame = 0, bezier = 0;; frame++) {
timeline.setFrame(frame, time, mix, softness, input.readByte(), input.readBoolean(), input.readBoolean());
if (frame == frameLast) break;
let time2 = input.readFloat();
let mix2 = input.readFloat();
let softness2 = input.readFloat() * scale;
switch (input.readByte()) {
case SkeletonBinary.CURVE_STEPPED:
timeline.setStepped(frame);
break;
case SkeletonBinary.CURVE_BEZIER:
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 0, time, time2, mix, mix2, 1);
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 1, time, time2, softness, softness2, scale);
}
time = time2;
mix = mix2;
softness = softness2;
} }
timelines.push(timeline); timelines.push(timeline);
duration = Math.max(duration, timeline.frames[(frameCount - 1) * IkConstraintTimeline.ENTRIES]);
} }
// Transform constraint timelines. // Transform constraint timelines.
for (let i = 0, n = input.readInt(true); i < n; i++) { for (let i = 0, n = input.readInt(true); i < n; i++) {
let index = input.readInt(true); let index = input.readInt(true);
let frameCount = input.readInt(true); let frameCount = input.readInt(true);
let timeline = new TransformConstraintTimeline(frameCount); let bezierCount = input.readInt(true);
timeline.transformConstraintIndex = index; let frameLast = frameCount - 1;
for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) { let timeline = new TransformConstraintTimeline(frameCount, bezierCount, index);
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat(),
input.readFloat()); let time = input.readFloat();
if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline); let rotateMix = input.readFloat();
let translateMix = input.readFloat();
let scaleMix = input.readFloat();
let shearMix = input.readFloat();
for (let frame = 0, bezier = 0;; frame++) {
timeline.setFrame(frame, time, rotateMix, translateMix, scaleMix, shearMix);
if (frame == frameLast) break;
let time2 = input.readFloat();
let rotateMix2 = input.readFloat();
let translateMix2 = input.readFloat();
let scaleMix2 = input.readFloat();
let shearMix2 = input.readFloat();
switch (input.readByte()) {
case SkeletonBinary.CURVE_STEPPED:
timeline.setStepped(frame);
break;
case SkeletonBinary.CURVE_BEZIER:
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 0, time, time2, rotateMix, rotateMix2, 1);
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 1, time, time2, translateMix, translateMix2, 1);
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 2, time, time2, scaleMix, scaleMix2, 1);
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 3, time, time2, shearMix, shearMix2, 1);
}
time = time2;
rotateMix = rotateMix2;
translateMix = translateMix2;
scaleMix = scaleMix2;
shearMix = shearMix2;
} }
timelines.push(timeline); timelines.push(timeline);
duration = Math.max(duration, timeline.frames[(frameCount - 1) * TransformConstraintTimeline.ENTRIES]);
} }
// Path constraint timelines. // Path constraint timelines.
@ -632,40 +716,20 @@ module spine {
let index = input.readInt(true); let index = input.readInt(true);
let data = skeletonData.pathConstraints[index]; let data = skeletonData.pathConstraints[index];
for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) {
let timelineType = input.readByte(); switch (input.readByte()) {
let frameCount = input.readInt(true);
switch (timelineType) {
case SkeletonBinary.PATH_POSITION: case SkeletonBinary.PATH_POSITION:
case SkeletonBinary.PATH_SPACING: { timelines
let timeline; .push(SkeletonBinary.readTimeline(input, new PathConstraintPositionTimeline(input.readInt(true), input.readInt(true), index),
let timelineScale = 1; data.positionMode == PositionMode.Fixed ? scale : 1));
if (timelineType == SkeletonBinary.PATH_SPACING) {
timeline = new PathConstraintSpacingTimeline(frameCount);
if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) timelineScale = scale;
} else {
timeline = new PathConstraintPositionTimeline(frameCount);
if (data.positionMode == PositionMode.Fixed) timelineScale = scale;
}
timeline.pathConstraintIndex = index;
for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat() * timelineScale);
if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline);
}
timelines.push(timeline);
duration = Math.max(duration, timeline.frames[(frameCount - 1) * PathConstraintPositionTimeline.ENTRIES]);
break; break;
} case SkeletonBinary.PATH_SPACING:
case SkeletonBinary.PATH_MIX: { timelines
let timeline = new PathConstraintMixTimeline(frameCount); .push(SkeletonBinary.readTimeline(input, new PathConstraintSpacingTimeline(input.readInt(true), input.readInt(true), index),
timeline.pathConstraintIndex = index; data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed ? scale : 1));
for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {
timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat());
if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline);
}
timelines.push(timeline);
duration = Math.max(duration, timeline.frames[(frameCount - 1) * PathConstraintMixTimeline.ENTRIES]);
break; break;
} case SkeletonBinary.PATH_MIX:
timelines
.push(SkeletonBinary.readTimeline2(input, new PathConstraintMixTimeline(input.readInt(true), input.readInt(true), index), 1));
} }
} }
} }
@ -676,18 +740,20 @@ module spine {
for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) {
let slotIndex = input.readInt(true); let slotIndex = input.readInt(true);
for (let iii = 0, nnn = input.readInt(true); iii < nnn; iii++) { for (let iii = 0, nnn = input.readInt(true); iii < nnn; iii++) {
let attachment = skin.getAttachment(slotIndex, input.readStringRef()) as VertexAttachment; let attachmentName = input.readStringRef();
let attachment = skin.getAttachment(slotIndex, attachmentName) as VertexAttachment;
if (attachment == null) throw Error("Vertex attachment not found: " + attachmentName);
let weighted = attachment.bones != null; let weighted = attachment.bones != null;
let vertices = attachment.vertices; let vertices = attachment.vertices;
let deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; let deformLength = weighted ? vertices.length / 3 * 2 : vertices.length;
let frameCount = input.readInt(true); let frameCount = input.readInt(true);
let timeline = new DeformTimeline(frameCount); let frameLast = frameCount - 1;
timeline.slotIndex = slotIndex; let bezierCount = input.readInt(true);
timeline.attachment = attachment; let timeline = new DeformTimeline(frameCount, bezierCount, slotIndex, attachment);
for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {
let time = input.readFloat(); let time = input.readFloat();
for (let frame = 0, bezier = 0;; frame++) {
let deform; let deform;
let end = input.readInt(true); let end = input.readInt(true);
if (end == 0) if (end == 0)
@ -709,11 +775,19 @@ module spine {
} }
} }
timeline.setFrame(frameIndex, time, deform); timeline.setFrame(frame, time, deform);
if (frameIndex < frameCount - 1) this.readCurve(input, frameIndex, timeline); if (frame == frameLast) break;
let time2 = input.readFloat();
switch(input.readByte()) {
case SkeletonBinary.CURVE_STEPPED:
timeline.setStepped(frame);
break;
case SkeletonBinary.CURVE_BEZIER:
SkeletonBinary.setBezier(input, timeline, bezier++, frame, 0, time, time2, 0, 1, 1);
}
time = time2;
} }
timelines.push(timeline); timelines.push(timeline);
duration = Math.max(duration, timeline.frames[frameCount - 1]);
} }
} }
} }
@ -748,7 +822,6 @@ module spine {
timeline.setFrame(i, time, drawOrder); timeline.setFrame(i, time, drawOrder);
} }
timelines.push(timeline); timelines.push(timeline);
duration = Math.max(duration, timeline.frames[drawOrderCount - 1]);
} }
// Event timeline. // Event timeline.
@ -769,25 +842,56 @@ module spine {
timeline.setFrame(i, event); timeline.setFrame(i, event);
} }
timelines.push(timeline); timelines.push(timeline);
duration = Math.max(duration, timeline.frames[eventCount - 1]);
} }
let duration = 0;
for (let i = 0, n = timelines.length; i < n; i++)
duration = Math.max(duration, (timelines[i]).getDuration());
return new Animation(name, timelines, duration); return new Animation(name, timelines, duration);
} }
private readCurve (input: BinaryInput, frameIndex: number, timeline: CurveTimeline) { static readTimeline (input: BinaryInput, timeline: CurveTimeline1, scale: number): Timeline {
let time = input.readFloat(), value = input.readFloat() * scale;
for (let frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1;; frame++) {
timeline.setFrame(frame, time, value);
if (frame == frameLast) break;
let time2 = input.readFloat(), value2 = input.readFloat() * scale;
switch (input.readByte()) { switch (input.readByte()) {
case SkeletonBinary.CURVE_STEPPED: case SkeletonBinary.CURVE_STEPPED:
timeline.setStepped(frameIndex); timeline.setStepped(frame);
break; break;
case SkeletonBinary.CURVE_BEZIER: case SkeletonBinary.CURVE_BEZIER:
this.setCurve(timeline, frameIndex, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat()); SkeletonBinary.setBezier(input, timeline, bezier++, frame, 0, time, time2, value, value2, 1);
break;
} }
time = time2;
value = value2;
}
return timeline;
} }
setCurve (timeline: CurveTimeline, frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number) { static readTimeline2 (input: BinaryInput, timeline: CurveTimeline2, scale: number): Timeline {
timeline.setCurve(frameIndex, cx1, cy1, cx2, cy2); let time = input.readFloat(), value1 = input.readFloat() * scale, value2 = input.readFloat() * scale;
for (let frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1;; frame++) {
timeline.setFrame(frame, time, value1, value2);
if (frame == frameLast) break;
let time2 = input.readFloat(), nvalue1 = input.readFloat() * scale, nvalue2 = input.readFloat() * scale;
switch (input.readByte()) {
case SkeletonBinary.CURVE_STEPPED:
timeline.setStepped(frame);
break;
case SkeletonBinary.CURVE_BEZIER:
this.setBezier(input, timeline, bezier++, frame, 0, time, time2, value1, nvalue1, scale);
this.setBezier(input, timeline, bezier++, frame, 1, time, time2, value2, nvalue2, scale);
}
time = time2;
value1 = nvalue1;
value2 = nvalue2;
}
return timeline;
}
static setBezier (input: BinaryInput, timeline: CurveTimeline, bezier: number, frame: number, value: number, time1: number, time2: number, value1: number, value2: number, scale: number) {
timeline.setBezier(bezier, frame, value, time1, value1, input.readFloat(), input.readFloat() * scale, input.readFloat(), input.readFloat() * scale, time2, value2);
} }
} }
@ -800,6 +904,10 @@ module spine {
return this.buffer.getInt8(this.index++); return this.buffer.getInt8(this.index++);
} }
readUnsignedByte(): number {
return this.buffer.getUint8(this.index++);
}
readShort(): number { readShort(): number {
let value = this.buffer.getInt16(this.index); let value = this.buffer.getInt16(this.index);
this.index += 2; this.index += 2;

View File

@ -58,8 +58,6 @@ module spine {
if (skeletonMap != null) { if (skeletonMap != null) {
skeletonData.hash = skeletonMap.hash; skeletonData.hash = skeletonMap.hash;
skeletonData.version = skeletonMap.spine; skeletonData.version = skeletonMap.spine;
if ("3.8.75" == skeletonData.version)
throw new Error("Unsupported skeleton data, please export with a newer version of Spine.");
skeletonData.x = skeletonMap.x; skeletonData.x = skeletonMap.x;
skeletonData.y = skeletonMap.y; skeletonData.y = skeletonMap.y;
skeletonData.width = skeletonMap.width; skeletonData.width = skeletonMap.width;
@ -460,7 +458,6 @@ module spine {
readAnimation (map: any, name: string, skeletonData: SkeletonData) { readAnimation (map: any, name: string, skeletonData: SkeletonData) {
let scale = this.scale; let scale = this.scale;
let timelines = new Array<Timeline>(); let timelines = new Array<Timeline>();
let duration = 0;
// Slot timelines. // Slot timelines.
if (map.slots) { if (map.slots) {
@ -470,50 +467,78 @@ module spine {
if (slotIndex == -1) throw new Error("Slot not found: " + slotName); if (slotIndex == -1) throw new Error("Slot not found: " + slotName);
for (let timelineName in slotMap) { for (let timelineName in slotMap) {
let timelineMap = slotMap[timelineName]; let timelineMap = slotMap[timelineName];
if (!timelineMap) continue;
if (timelineName == "attachment") { if (timelineName == "attachment") {
let timeline = new AttachmentTimeline(timelineMap.length); let timeline = new AttachmentTimeline(timelineMap.length, slotIndex);
timeline.slotIndex = slotIndex;
let frameIndex = 0; let frame = 0;
for (let i = 0; i < timelineMap.length; i++) { for (let i = 0; i < timelineMap.length; i++) {
let valueMap = timelineMap[i]; let keyMap = timelineMap[i];
timeline.setFrame(frameIndex++, this.getValue(valueMap, "time", 0), valueMap.name); timeline.setFrame(frame++, this.getValue(keyMap, "time", 0), keyMap.name);
} }
timelines.push(timeline); timelines.push(timeline);
duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
} else if (timelineName == "color") { } else if (timelineName == "color") {
let timeline = new ColorTimeline(timelineMap.length); let timeline = new ColorTimeline(timelineMap.length, timelineMap.length << 2, slotIndex);
timeline.slotIndex = slotIndex; let keyMap = timelineMap[0];
let time = this.getValue(keyMap, "time", 0);
let color = new Color().setFromString(keyMap.color);
let frameIndex = 0; for (let frame = 0, bezier = 0;; frame++) {
for (let i = 0; i < timelineMap.length; i++) { timeline.setFrame(frame, time, color.r, color.g, color.b, color.a);
let valueMap = timelineMap[i]; if (timelineMap.length == frame + 1) {
let color = new Color(); break;
color.setFromString(valueMap.color);
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), color.r, color.g, color.b, color.a);
this.readCurve(valueMap, timeline, frameIndex);
frameIndex++;
} }
let nextMap = timelineMap[frame + 1];
let time2 = this.getValue(nextMap, "time", 0);
let newColor = new Color().setFromString(nextMap.color);
let curve = keyMap.curve;
if (curve) {
bezier = this.readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1);
bezier = this.readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1);
bezier = this.readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1);
bezier = this.readCurve(curve, timeline, bezier, frame, 3, time, time2, color.a, newColor.a, 1);
}
time = time2;
color = newColor;
keyMap = nextMap;
}
timelines.push(timeline); timelines.push(timeline);
duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * ColorTimeline.ENTRIES]);
} else if (timelineName == "twoColor") { } else if (timelineName == "twoColor") {
let timeline = new TwoColorTimeline(timelineMap.length); let timeline = new TwoColorTimeline(timelineMap.length, timelineMap.length * 7, slotIndex);
timeline.slotIndex = slotIndex;
let frameIndex = 0; let keyMap = timelineMap[0];
for (let i = 0; i < timelineMap.length; i++) { let time = this.getValue(keyMap, "time", 0);
let valueMap = timelineMap[i]; let color = new Color().setFromString(keyMap.light);
let light = new Color(); let color2 = new Color().setFromString(keyMap.dark);
let dark = new Color();
light.setFromString(valueMap.light); for (let frame = 0, bezier = 0;; frame++) {
dark.setFromString(valueMap.dark); timeline.setFrame(frame, time, color.r, color.g, color.b, color.a, color2.r, color2.g, color2.b);
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b); if (timelineMap.length == frame + 1) {
this.readCurve(valueMap, timeline, frameIndex); break;
frameIndex++;
} }
let nextMap = timelineMap[frame + 1];
let time2 = this.getValue(nextMap, "time", 0);
let newColor = new Color().setFromString(nextMap.light);
let newColor2 = new Color().setFromString(nextMap.dark);
let curve = keyMap.curve;
if (curve) {
bezier = this.readCurve(curve, timeline, bezier, frame, 0, time, time2, color.r, newColor.r, 1);
bezier = this.readCurve(curve, timeline, bezier, frame, 1, time, time2, color.g, newColor.g, 1);
bezier = this.readCurve(curve, timeline, bezier, frame, 2, time, time2, color.b, newColor.b, 1);
bezier = this.readCurve(curve, timeline, bezier, frame, 3, time, time2, color.a, newColor.a, 1);
bezier = this.readCurve(curve, timeline, bezier, frame, 4, time, time2, color2.r, newColor2.r, 1);
bezier = this.readCurve(curve, timeline, bezier, frame, 5, time, time2, color2.g, newColor2.g, 1);
bezier = this.readCurve(curve, timeline, bezier, frame, 6, time, time2, color2.b, newColor2.b, 1);
}
time = time2;
color = newColor;
color2 = newColor2;
keyMap = nextMap;
}
timelines.push(timeline); timelines.push(timeline);
duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * TwoColorTimeline.ENTRIES]);
} else } else
throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"); throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
@ -529,68 +554,65 @@ module spine {
if (boneIndex == -1) throw new Error("Bone not found: " + boneName); if (boneIndex == -1) throw new Error("Bone not found: " + boneName);
for (let timelineName in boneMap) { for (let timelineName in boneMap) {
let timelineMap = boneMap[timelineName]; let timelineMap = boneMap[timelineName];
let keyMap = timelineMap[0];
if (!keyMap) continue;
if (timelineName === "rotate") { if (timelineName === "rotate") {
let timeline = new RotateTimeline(timelineMap.length); timelines.push(this.readTimeline(timelineMap, new RotateTimeline(timelineMap.length, timelineMap.length, boneIndex), 0, 1));
timeline.boneIndex = boneIndex; } else if (timelineName === "translate") {
let timeline = new TranslateTimeline(timelineMap.length, timelineMap.length << 1, boneIndex);
let frameIndex = 0; timelines.push(this.readTimeline2(timelineMap, timeline, "x", "y", 0, scale));
for (let i = 0; i < timelineMap.length; i++) { } else if (timelineName === "scale") {
let valueMap = timelineMap[i]; let timeline = new ScaleTimeline(timelineMap.length, timelineMap.length << 1, boneIndex);
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "angle", 0)); timelines.push(this.readTimeline2(timelineMap, timeline, "x", "y", 1, 1));
this.readCurve(valueMap, timeline, frameIndex); } else if (timelineName === "shear") {
frameIndex++; let timeline = new ShearTimeline(timelineMap.length, timelineMap.length << 1, boneIndex);
} timelines.push(this.readTimeline2(timelineMap, timeline, "x", "y", 0, 1));
timelines.push(timeline); } else {
duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * RotateTimeline.ENTRIES]);
} else if (timelineName === "translate" || timelineName === "scale" || timelineName === "shear") {
let timeline: TranslateTimeline = null;
let timelineScale = 1, defaultValue = 0;
if (timelineName === "scale") {
timeline = new ScaleTimeline(timelineMap.length);
defaultValue = 1;
} else if (timelineName === "shear")
timeline = new ShearTimeline(timelineMap.length);
else {
timeline = new TranslateTimeline(timelineMap.length);
timelineScale = scale;
}
timeline.boneIndex = boneIndex;
let frameIndex = 0;
for (let i = 0; i < timelineMap.length; i++) {
let valueMap = timelineMap[i];
let x = this.getValue(valueMap, "x", defaultValue), y = this.getValue(valueMap, "y", defaultValue);
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), x * timelineScale, y * timelineScale);
this.readCurve(valueMap, timeline, frameIndex);
frameIndex++;
}
timelines.push(timeline);
duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * TranslateTimeline.ENTRIES]);
} else
throw new Error("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"); throw new Error("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
} }
} }
} }
}
// IK constraint timelines. // IK constraint timelines.
if (map.ik) { if (map.ik) {
for (let constraintName in map.ik) { for (let constraintName in map.ik) {
let constraintMap = map.ik[constraintName]; let constraintMap = map.ik[constraintName];
let keyMap = constraintMap[0];
if (!keyMap) continue;
let constraint = skeletonData.findIkConstraint(constraintName); let constraint = skeletonData.findIkConstraint(constraintName);
let timeline = new IkConstraintTimeline(constraintMap.length); let constraintIndex = skeletonData.ikConstraints.indexOf(constraint);
timeline.ikConstraintIndex = skeletonData.ikConstraints.indexOf(constraint); let timeline = new IkConstraintTimeline(constraintMap.length, constraintMap.length << 1, constraintIndex);
let frameIndex = 0;
for (let i = 0; i < constraintMap.length; i++) { let time = this.getValue(keyMap, "time", 0);
let valueMap = constraintMap[i]; let mix = this.getValue(keyMap, "mix", 1);
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "softness", 0) * scale, let softness = this.getValue(keyMap, "softness", 0) * scale;
this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false));
this.readCurve(valueMap, timeline, frameIndex); for (let frame = 0, bezier = 0;; frame++) {
frameIndex++; timeline.setFrame(frame, time, mix, softness, this.getValue(keyMap, "bendPositive", true) ? 1 : -1, this.getValue(keyMap, "compress", false), this.getValue(keyMap, "stretch", false))
let nextMap = constraintMap[frame + 1];
if (!nextMap) {
break;
}
let time2 = this.getValue(nextMap, "time", 0);
let mix2 = this.getValue(nextMap, "mix", 1);
let softness2 = this.getValue(nextMap, "softness", 0) * scale;
let curve = keyMap.curve;
if (curve) {
bezier = this.readCurve(curve, timeline, bezier, frame, 0, time, time2, mix, mix2, 1);
bezier = this.readCurve(curve, timeline, bezier, frame, 1, time, time2, softness, softness2, scale);
}
time = time2;
mix = mix2;
softness = softness2;
keyMap = nextMap;
} }
timelines.push(timeline); timelines.push(timeline);
duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * IkConstraintTimeline.ENTRIES]);
} }
} }
@ -598,20 +620,48 @@ module spine {
if (map.transform) { if (map.transform) {
for (let constraintName in map.transform) { for (let constraintName in map.transform) {
let constraintMap = map.transform[constraintName]; let constraintMap = map.transform[constraintName];
let keyMap = constraintMap[0];
if (!keyMap) continue;
let constraint = skeletonData.findTransformConstraint(constraintName); let constraint = skeletonData.findTransformConstraint(constraintName);
let timeline = new TransformConstraintTimeline(constraintMap.length); let constraintIndex = skeletonData.transformConstraints.indexOf(constraint);
timeline.transformConstraintIndex = skeletonData.transformConstraints.indexOf(constraint); let timeline = new TransformConstraintTimeline(constraintMap.length, constraintMap.length << 2, constraintIndex);
let frameIndex = 0;
for (let i = 0; i < constraintMap.length; i++) { let time = this.getValue(keyMap, "time", 0);
let valueMap = constraintMap[i]; let rotateMix = this.getValue(keyMap, "rotateMix", 1);
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), let translateMix = this.getValue(keyMap, "translateMix", 1);
this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1)); let scaleMix = this.getValue(keyMap, "scaleMix", 1);
this.readCurve(valueMap, timeline, frameIndex); let shearMix = this.getValue(keyMap, "shearMix", 1);
frameIndex++;
for (let frame = 0, bezier = 0;; frame++) {
timeline.setFrame(frame, time, rotateMix, translateMix, scaleMix, shearMix);
let nextMap = constraintMap[frame + 1];
if (!nextMap) {
break;
}
let time2 = this.getValue(nextMap, "time", 0);
let rotateMix2 = this.getValue(nextMap, "rotateMix", 1);
let translateMix2 = this.getValue(nextMap, "translateMix", 1);
let scaleMix2 = this.getValue(nextMap, "scaleMix", 1);
let shearMix2 = this.getValue(nextMap, "shearMix", 1);
let curve = keyMap.curve;
if (curve) {
bezier = this.readCurve(curve, timeline, bezier, frame, 0, time, time2, rotateMix, rotateMix2, 1);
bezier = this.readCurve(curve, timeline, bezier, frame, 1, time, time2, translateMix, translateMix2, 1);
bezier = this.readCurve(curve, timeline, bezier, frame, 2, time, time2, scaleMix, scaleMix2, 1);
bezier = this.readCurve(curve, timeline, bezier, frame, 3, time, time2, shearMix, shearMix2, 1);
}
time = time2;
rotateMix = rotateMix2;
translateMix = translateMix2;
scaleMix = scaleMix2;
shearMix = shearMix2;
keyMap = nextMap;
} }
timelines.push(timeline); timelines.push(timeline);
duration = Math.max(duration,
timeline.frames[(timeline.getFrameCount() - 1) * TransformConstraintTimeline.ENTRIES]);
} }
} }
@ -624,41 +674,18 @@ module spine {
let data = skeletonData.pathConstraints[index]; let data = skeletonData.pathConstraints[index];
for (let timelineName in constraintMap) { for (let timelineName in constraintMap) {
let timelineMap = constraintMap[timelineName]; let timelineMap = constraintMap[timelineName];
if (timelineName === "position" || timelineName === "spacing") { let keyMap = constraintMap[0];
let timeline: PathConstraintPositionTimeline = null; if (!keyMap) continue;
let timelineScale = 1;
if (timelineName === "spacing") { if (timelineName === "position") {
timeline = new PathConstraintSpacingTimeline(timelineMap.length); let timeline = new PathConstraintPositionTimeline(timelineMap.length, timelineMap.length, index);
if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) timelineScale = scale; timelines.push(this.readTimeline(timelineMap, timeline, 0, data.positionMode == PositionMode.Fixed ? scale : 1));
} else { } else if (timelineName === "spacing") {
timeline = new PathConstraintPositionTimeline(timelineMap.length); let timeline = new PathConstraintSpacingTimeline(timelineMap.length, timelineMap.length, index);
if (data.positionMode == PositionMode.Fixed) timelineScale = scale; timelines.push(this.readTimeline(timelineMap, timeline, 0, data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed ? scale : 1));
}
timeline.pathConstraintIndex = index;
let frameIndex = 0;
for (let i = 0; i < timelineMap.length; i++) {
let valueMap = timelineMap[i];
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, timelineName, 0) * timelineScale);
this.readCurve(valueMap, timeline, frameIndex);
frameIndex++;
}
timelines.push(timeline);
duration = Math.max(duration,
timeline.frames[(timeline.getFrameCount() - 1) * PathConstraintPositionTimeline.ENTRIES]);
} else if (timelineName === "mix") { } else if (timelineName === "mix") {
let timeline = new PathConstraintMixTimeline(timelineMap.length); let timeline = new PathConstraintMixTimeline(timelineMap.size, timelineMap.size << 1, index);
timeline.pathConstraintIndex = index; timelines.push(this.readTimeline2(timelineMap, timeline, "rotateMix", "translateMix", 1, 1));
let frameIndex = 0;
for (let i = 0; i < timelineMap.length; i++) {
let valueMap = timelineMap[i];
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1),
this.getValue(valueMap, "translateMix", 1));
this.readCurve(valueMap, timeline, frameIndex);
frameIndex++;
}
timelines.push(timeline);
duration = Math.max(duration,
timeline.frames[(timeline.getFrameCount() - 1) * PathConstraintMixTimeline.ENTRIES]);
} }
} }
} }
@ -676,26 +703,25 @@ module spine {
if (slotIndex == -1) throw new Error("Slot not found: " + slotMap.name); if (slotIndex == -1) throw new Error("Slot not found: " + slotMap.name);
for (let timelineName in slotMap) { for (let timelineName in slotMap) {
let timelineMap = slotMap[timelineName]; let timelineMap = slotMap[timelineName];
let keyMap = timelineMap[0];
if (!keyMap) continue;
let attachment = <VertexAttachment>skin.getAttachment(slotIndex, timelineName); let attachment = <VertexAttachment>skin.getAttachment(slotIndex, timelineName);
if (attachment == null) throw new Error("Deform attachment not found: " + timelineMap.name); if (attachment == null) throw new Error("Deform attachment not found: " + timelineMap.name);
let weighted = attachment.bones != null; let weighted = attachment.bones != null;
let vertices = attachment.vertices; let vertices = attachment.vertices;
let deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; let deformLength = weighted ? vertices.length / 3 * 2 : vertices.length;
let timeline = new DeformTimeline(timelineMap.length); let timeline = new DeformTimeline(timelineMap.length, timelineMap.length, slotIndex, attachment);
timeline.slotIndex = slotIndex; let time = this.getValue(keyMap, "time", 0);
timeline.attachment = attachment; for (let frame = 0, bezier = 0;; frame++) {
let frameIndex = 0;
for (let j = 0; j < timelineMap.length; j++) {
let valueMap = timelineMap[j];
let deform: ArrayLike<number>; let deform: ArrayLike<number>;
let verticesValue: Array<Number> = this.getValue(valueMap, "vertices", null); let verticesValue: Array<Number> = this.getValue(keyMap, "vertices", null);
if (verticesValue == null) if (verticesValue == null)
deform = weighted ? Utils.newFloatArray(deformLength) : vertices; deform = weighted ? Utils.newFloatArray(deformLength) : vertices;
else { else {
deform = Utils.newFloatArray(deformLength); deform = Utils.newFloatArray(deformLength);
let start = <number>this.getValue(valueMap, "offset", 0); let start = <number>this.getValue(keyMap, "offset", 0);
Utils.arrayCopy(verticesValue, 0, deform, start, verticesValue.length); Utils.arrayCopy(verticesValue, 0, deform, start, verticesValue.length);
if (scale != 1) { if (scale != 1) {
for (let i = start, n = i + verticesValue.length; i < n; i++) for (let i = start, n = i + verticesValue.length; i < n; i++)
@ -707,12 +733,20 @@ module spine {
} }
} }
timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), deform); timeline.setFrame(frame, time, deform);
this.readCurve(valueMap, timeline, frameIndex); let nextMap = timelineMap[frame + 1];
frameIndex++; if (!nextMap) {
break;
}
let time2 = this.getValue(nextMap, "time", 0);
let curve = keyMap.curve;
if (curve) {
bezier = this.readCurve(curve, timeline, bezier, frame, 0, time, time2, 0, 1, 1);
}
time = time2;
keyMap = nextMap;
} }
timelines.push(timeline); timelines.push(timeline);
duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
} }
} }
} }
@ -724,8 +758,8 @@ module spine {
if (drawOrderNode != null) { if (drawOrderNode != null) {
let timeline = new DrawOrderTimeline(drawOrderNode.length); let timeline = new DrawOrderTimeline(drawOrderNode.length);
let slotCount = skeletonData.slots.length; let slotCount = skeletonData.slots.length;
let frameIndex = 0; let frame = 0;
for (let j = 0; j < drawOrderNode.length; j++) { for (let j = 0; j < drawOrderNode.length; j++, frame++) {
let drawOrderMap = drawOrderNode[j]; let drawOrderMap = drawOrderNode[j];
let drawOrder: Array<number> = null; let drawOrder: Array<number> = null;
let offsets = this.getValue(drawOrderMap, "offsets", null); let offsets = this.getValue(drawOrderMap, "offsets", null);
@ -750,17 +784,16 @@ module spine {
for (let i = slotCount - 1; i >= 0; i--) for (let i = slotCount - 1; i >= 0; i--)
if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex]; if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex];
} }
timeline.setFrame(frameIndex++, this.getValue(drawOrderMap, "time", 0), drawOrder); timeline.setFrame(frame, this.getValue(drawOrderMap, "time", 0), drawOrder);
} }
timelines.push(timeline); timelines.push(timeline);
duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
} }
// Event timeline. // Event timeline.
if (map.events) { if (map.events) {
let timeline = new EventTimeline(map.events.length); let timeline = new EventTimeline(map.events.length);
let frameIndex = 0; let frame = 0;
for (let i = 0; i < map.events.length; i++) { for (let i = 0; i < map.events.length; i++, frame++) {
let eventMap = map.events[i]; let eventMap = map.events[i];
let eventData = skeletonData.findEvent(eventMap.name); let eventData = skeletonData.findEvent(eventMap.name);
if (eventData == null) throw new Error("Event not found: " + eventMap.name); if (eventData == null) throw new Error("Event not found: " + eventMap.name);
@ -772,10 +805,14 @@ module spine {
event.volume = this.getValue(eventMap, "volume", 1); event.volume = this.getValue(eventMap, "volume", 1);
event.balance = this.getValue(eventMap, "balance", 0); event.balance = this.getValue(eventMap, "balance", 0);
} }
timeline.setFrame(frameIndex++, event); timeline.setFrame(frame, event);
} }
timelines.push(timeline); timelines.push(timeline);
duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); }
let duration = 0;
for (let i = 0, n = timelines.length; i < n; i++) {
duration = Math.max(duration, timelines[i].getDuration());
} }
if (isNaN(duration)) { if (isNaN(duration)) {
@ -785,14 +822,71 @@ module spine {
skeletonData.animations.push(new Animation(name, timelines, duration)); skeletonData.animations.push(new Animation(name, timelines, duration));
} }
readCurve (map: any, timeline: CurveTimeline, frameIndex: number) { private readTimeline (keys: any[], timeline: CurveTimeline1, defaultValue: number, scale: number) {
if (!map.hasOwnProperty("curve")) return; let keyMap = keys[0];
if (map.curve == "stepped") let time = this.getValue(keyMap, "time", 0);
timeline.setStepped(frameIndex); let value = this.getValue(keyMap, "value", defaultValue) * scale;
else { let bezier = 0;
let curve: number = map.curve; for (let frame = 0;; frame++) {
timeline.setCurve(frameIndex, curve, this.getValue(map, "c2", 0), this.getValue(map, "c3", 1), this.getValue(map, "c4", 1)); timeline.setFrame(frame, time, value);
let nextMap = keys[frame + 1];
if (!nextMap) break;
let time2 = this.getValue(nextMap, "time", 0);
let value2 = this.getValue(nextMap, "value", defaultValue) * scale;
let curve = keyMap.curve;
if (curve) bezier = this.readCurve(curve, timeline, bezier, frame, 0, time, time2, value, value2, scale);
time = time2;
value = value2;
keyMap = nextMap;
} }
return timeline;
}
private readTimeline2 (keys: any[], timeline: CurveTimeline2, name1: string, name2: string, defaultValue: number, scale: number) {
let keyMap = keys[0];
let time = this.getValue(keyMap, "time", 0);
let value1 = this.getValue(keyMap, name1, defaultValue) * scale;
let value2 = this.getValue(keyMap, name2, defaultValue) * scale;
let bezier = 0;
for (let frame = 0;; frame++) {
timeline.setFrame(frame, time, value1, value2);
let nextMap = keys[frame + 1];
if (!nextMap) break;
let time2 = this.getValue(nextMap, "time", 0);
let nvalue1 = this.getValue(nextMap, name1, defaultValue) * scale;
let nvalue2 = this.getValue(nextMap, name2, defaultValue) * scale;
let curve = keyMap.curve;
if (curve != null) {
bezier = this.readCurve(curve, timeline, bezier, frame, 0, time, time2, value1, nvalue1, scale);
bezier = this.readCurve(curve, timeline, bezier, frame, 1, time, time2, value2, nvalue2, scale);
}
time = time2;
value1 = nvalue1;
value2 = nvalue2;
keyMap = nextMap;
}
timeline.shrink(bezier);
return timeline;
}
private readCurve (curve: any, timeline: CurveTimeline, bezier: number, frame: number, value: number, time1: number, time2: number,
value1: number, value2: number, scale: number) {
if (curve == "stepped") {
if (value != 0) timeline.setStepped(frame);
} else {
let i = value << 2;
let cx1 = curve[i++];
let cy1 = curve[i++] * scale;
let cx2 = curve[i++];
let cy2 = curve[i++] * scale;
this.setBezier(timeline, frame, value, bezier++, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
}
return bezier;
}
setBezier (timeline: CurveTimeline, frame: number, value: number, bezier: number, time1: number, value1: number, cx1: number, cy1: number,
cx2: number, cy2: number, time2: number, value2: number) {
timeline.setBezier(bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
} }
getValue (map: any, prop: string, defaultValue: any) { getValue (map: any, prop: string, defaultValue: any) {

View File

@ -77,12 +77,9 @@ module spine {
return this.active; return this.active;
} }
/** Applies the constraint to the constrained bones. */
apply () {
this.update();
}
update () { update () {
if (this.rotateMix == 0 && this.translateMix == 0 && this.scaleMix == 0 && this.shearMix == 0) return;
if (this.data.local) { if (this.data.local) {
if (this.data.relative) if (this.data.relative)
this.applyRelativeLocal(); this.applyRelativeLocal();
@ -107,7 +104,6 @@ module spine {
let bones = this.bones; let bones = this.bones;
for (let i = 0, n = bones.length; i < n; i++) { for (let i = 0, n = bones.length; i < n; i++) {
let bone = bones[i]; let bone = bones[i];
let modified = false;
if (rotateMix != 0) { if (rotateMix != 0) {
let a = bone.a, b = bone.b, c = bone.c, d = bone.d; let a = bone.a, b = bone.b, c = bone.c, d = bone.d;
@ -122,7 +118,6 @@ module spine {
bone.b = cos * b - sin * d; bone.b = cos * b - sin * d;
bone.c = sin * a + cos * c; bone.c = sin * a + cos * c;
bone.d = sin * b + cos * d; bone.d = sin * b + cos * d;
modified = true;
} }
if (translateMix != 0) { if (translateMix != 0) {
@ -130,7 +125,6 @@ module spine {
target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY));
bone.worldX += (temp.x - bone.worldX) * translateMix; bone.worldX += (temp.x - bone.worldX) * translateMix;
bone.worldY += (temp.y - bone.worldY) * translateMix; bone.worldY += (temp.y - bone.worldY) * translateMix;
modified = true;
} }
if (scaleMix > 0) { if (scaleMix > 0) {
@ -144,7 +138,6 @@ module spine {
if (s > 0.00001) s = (s + (ts - s + this.data.offsetScaleY) * scaleMix) / s; if (s > 0.00001) s = (s + (ts - s + this.data.offsetScaleY) * scaleMix) / s;
bone.b *= s; bone.b *= s;
bone.d *= s; bone.d *= s;
modified = true;
} }
if (shearMix > 0) { if (shearMix > 0) {
@ -159,10 +152,9 @@ module spine {
let s = Math.sqrt(b * b + d * d); let s = Math.sqrt(b * b + d * d);
bone.b = Math.cos(r) * s; bone.b = Math.cos(r) * s;
bone.d = Math.sin(r) * s; bone.d = Math.sin(r) * s;
modified = true;
} }
if (modified) bone.appliedValid = false; bone.appliedValid = false;
} }
} }
@ -175,7 +167,6 @@ module spine {
let bones = this.bones; let bones = this.bones;
for (let i = 0, n = bones.length; i < n; i++) { for (let i = 0, n = bones.length; i < n; i++) {
let bone = bones[i]; let bone = bones[i];
let modified = false;
if (rotateMix != 0) { if (rotateMix != 0) {
let a = bone.a, b = bone.b, c = bone.c, d = bone.d; let a = bone.a, b = bone.b, c = bone.c, d = bone.d;
@ -189,7 +180,6 @@ module spine {
bone.b = cos * b - sin * d; bone.b = cos * b - sin * d;
bone.c = sin * a + cos * c; bone.c = sin * a + cos * c;
bone.d = sin * b + cos * d; bone.d = sin * b + cos * d;
modified = true;
} }
if (translateMix != 0) { if (translateMix != 0) {
@ -197,7 +187,6 @@ module spine {
target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY));
bone.worldX += temp.x * translateMix; bone.worldX += temp.x * translateMix;
bone.worldY += temp.y * translateMix; bone.worldY += temp.y * translateMix;
modified = true;
} }
if (scaleMix > 0) { if (scaleMix > 0) {
@ -207,7 +196,6 @@ module spine {
s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * scaleMix + 1; s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * scaleMix + 1;
bone.b *= s; bone.b *= s;
bone.d *= s; bone.d *= s;
modified = true;
} }
if (shearMix > 0) { if (shearMix > 0) {
@ -220,10 +208,9 @@ module spine {
let s = Math.sqrt(b * b + d * d); let s = Math.sqrt(b * b + d * d);
bone.b = Math.cos(r) * s; bone.b = Math.cos(r) * s;
bone.d = Math.sin(r) * s; bone.d = Math.sin(r) * s;
modified = true;
} }
if (modified) bone.appliedValid = false; bone.appliedValid = false;
} }
} }

View File

@ -54,6 +54,36 @@ module spine {
} }
} }
export class StringSet {
entries: Map<boolean> = {};
size = 0;
add (value: string): boolean {
let contains = this.entries[value];
this.entries[value] = true;
if (!contains) this.size++;
return contains != true;
}
addAll (values: string[]): boolean {
let oldSize = this.size;
for (var i = 0, n = values.length; i < n; i++) {
this.add(values[i]);
}
return oldSize != this.size;
}
contains (value: string) {
let contains = this.entries[value];
return contains == true;
}
clear () {
this.entries = {};
this.size = 0;
}
}
export interface Disposable { export interface Disposable {
dispose (): void; dispose (): void;
} }

View File

@ -46,7 +46,7 @@ module spine {
private static nextID = 0; private static nextID = 0;
/** The unique ID for this attachment. */ /** The unique ID for this attachment. */
id = (VertexAttachment.nextID++ & 65535) << 11; id = VertexAttachment.nextID++;
/** The bones which affect the {@link #getVertices()}. The array entries are, for each vertex, the number of bones affecting /** The bones which affect the {@link #getVertices()}. The array entries are, for each vertex, the number of bones affecting
* the vertex followed by that many bone indices, which is the index of the bone in {@link Skeleton#bones}. Will be null * the vertex followed by that many bone indices, which is the index of the bone in {@link Skeleton#bones}. Will be null

View File

@ -0,0 +1,259 @@
{
"skeleton": {
"hash": "upF+oMt2JRY",
"spine": "4.0.05-beta",
"x": -152.5,
"y": -151,
"width": 305,
"height": 302,
"images": "./images/",
"audio": ""
},
"bones": [
{ "name": "root" },
{ "name": "coin-front", "parent": "root" },
{ "name": "clipping", "parent": "coin-front" },
{ "name": "coin-sides", "parent": "root" },
{ "name": "coin-side-round", "parent": "coin-sides" },
{ "name": "coin-side-straight", "parent": "coin-sides" },
{ "name": "shine", "parent": "root", "x": 243.14 }
],
"slots": [
{ "name": "coin-side", "bone": "coin-side-straight", "color": "ffdb2fff", "attachment": "coin-side-straight" },
{ "name": "coin-side-round", "bone": "coin-side-round", "color": "ffdb2fff", "attachment": "coin-side-round" },
{ "name": "coin-front-texture", "bone": "coin-front", "color": "868686ff", "attachment": "coin-front-logo" },
{ "name": "coin-front-shine", "bone": "coin-front", "color": "888888ff", "dark": "000000", "attachment": "coin-front-shine-logo", "blend": "additive" },
{ "name": "clipping", "bone": "clipping", "attachment": "clipping" },
{ "name": "shine", "bone": "shine", "color": "ffffff60", "attachment": "shine", "blend": "additive" }
],
"skins": [
{
"name": "default",
"attachments": {
"clipping": {
"clipping": {
"type": "clipping",
"end": "clipping",
"vertexCount": 39,
"vertices": [ 0.1, 140.26, -26.4, 138.14, -50.51, 131.25, -75.42, 119.06, -98.21, 101.04, -115.44, 82.22, -127.63, 62.08, -136.11, 39.03, -140.08, 19.68, -141.41, -0.19, -140.08, -22.98, -134.78, -45.5, -125.24, -66.44, -113.32, -84.19, -98.21, -101.95, -80.46, -116.52, -61.38, -127.39, -38.92, -134.81, -18.22, -139.27, -0.14, -140.58, 24.23, -138.48, 45.45, -132.46, 67.98, -122.5, 86.58, -110.19, 102.56, -95.25, 115.4, -78.75, 125.36, -61.72, 134, -42.33, 138.46, -22.15, 139.24, -0.15, 138.46, 20.29, 133.48, 39.94, 127.19, 58.54, 117.5, 76.1, 104.4, 92.86, 88.42, 108.32, 69.03, 121.42, 50.43, 130.85, 26.32, 137.4 ],
"color": "ce3a3aff"
}
},
"coin-front-shine": {
"coin-front-shine-logo": { "width": 282, "height": 282 },
"coin-front-shine-spineboy": { "width": 282, "height": 282 }
},
"coin-front-texture": {
"coin-front-logo": { "width": 305, "height": 302 },
"coin-front-spineboy": { "width": 305, "height": 302 }
},
"coin-side": {
"coin-side-straight": { "x": 0.5, "width": 17, "height": 282 }
},
"coin-side-round": {
"coin-side-round": { "x": -69.43, "width": 144, "height": 282 }
},
"shine": {
"shine": { "y": 0.5, "scaleX": 1.6004, "scaleY": 1.6004, "width": 72, "height": 245 }
}
}
}
],
"animations": {
"animation": {
"slots": {
"coin-front-shine": {
"twoColor": [
{ "light": "7d7d7dff", "dark": "000000" },
{ "time": 0.2667, "light": "000000ff", "dark": "7e7e7e" },
{ "time": 0.664, "light": "000000ff", "dark": "000000" },
{ "time": 1.0333, "light": "7f7f7fff", "dark": "000000" },
{ "time": 1.3333, "light": "404040ff", "dark": "000000" },
{ "time": 1.6, "light": "000000ff", "dark": "7e7e7e" },
{ "time": 2.0022, "light": "000000ff", "dark": "000000" },
{ "time": 2.4, "light": "7f7f7fff", "dark": "000000" },
{ "time": 2.6667, "light": "7d7d7dff", "dark": "000000" }
],
"attachment": [
{ "time": 0.6667, "name": "coin-front-shine-spineboy" },
{ "time": 2, "name": "coin-front-shine-logo" }
]
},
"coin-front-texture": {
"color": [
{ "color": "858585ff" },
{ "time": 0.4, "color": "ffffffff" },
{
"time": 0.6696,
"color": "858585ff",
"curve": [ 0.725, 0.59, 0.892, 1, 0.725, 0.59, 0.892, 1, 0.725, 0.59, 0.892, 1, 0.725, 1, 0.892, 1 ]
},
{ "time": 0.9667, "color": "ffffffff" },
{ "time": 1.3318, "color": "858585ff", "curve": "stepped" },
{ "time": 1.3333, "color": "858585ff" },
{ "time": 1.7333, "color": "ffffffff" },
{ "time": 1.9982, "color": "858585ff", "curve": "stepped" },
{ "time": 2.0022, "color": "858585ff" },
{ "time": 2.3, "color": "ffffffff" },
{ "time": 2.6667, "color": "858585ff" }
],
"attachment": [
{ "time": 0.6667, "name": "coin-front-spineboy" },
{ "time": 2, "name": "coin-front-logo" }
]
}
},
"bones": {
"coin-front": {
"translate": [
{},
{ "time": 0.664, "x": 8.3, "curve": "stepped" },
{
"time": 0.6696,
"x": -8.3,
"curve": [ 0.794, -7.08, 1.167, 0, 0.794, 0, 1.167, 0 ]
},
{ "time": 1.3333 },
{ "time": 1.9982, "x": 8.3, "curve": "stepped" },
{ "time": 2.0022, "x": -8.3 },
{ "time": 2.6667 }
],
"scale": [
{
"curve": [ 0.164, 1, 0.484, 0.09, 0.164, 1, 0.484, 1 ]
},
{ "time": 0.664, "x": 0, "curve": "stepped" },
{
"time": 0.6696,
"x": 0.003,
"curve": [ 0.786, 0.15, 1.167, 1, 0.786, 1, 1.167, 1 ]
},
{
"time": 1.3333,
"curve": [ 1.442, 0.99, 1.858, 0.1, 1.442, 1, 1.858, 1 ]
},
{ "time": 1.9982, "x": 0.003, "curve": "stepped" },
{
"time": 2.0022,
"x": 0.003,
"curve": [ 2.123, 0.15, 2.501, 1, 2.123, 1, 2.501, 1 ]
},
{ "time": 2.6667 }
]
},
"coin-side-round": {
"translate": [
{},
{ "time": 0.664, "x": -6.75, "curve": "stepped" },
{
"time": 0.6696,
"x": 7.03,
"curve": [ 0.794, 5.99, 1.167, 0, 0.794, 0, 1.167, 0 ]
},
{ "time": 1.3333 },
{ "time": 1.9982, "x": -6.75, "curve": "stepped" },
{ "time": 2.0022, "x": 7.03 },
{ "time": 2.6667 }
],
"scale": [
{
"curve": [ 0.085, 1, 0.207, 0.79, 0.085, 1, 0.207, 1 ]
},
{
"time": 0.3333,
"x": 0.555,
"curve": [ 0.449, 0.35, 0.567, 0.12, 0.449, 1, 0.567, 1 ]
},
{ "time": 0.664, "x": 0.014, "curve": "stepped" },
{
"time": 0.6696,
"x": -0.028,
"curve": [ 0.723, -0.13, 0.865, -0.37, 0.723, 1, 0.865, 1 ]
},
{
"time": 1,
"x": -0.609,
"curve": [ 1.053, -0.78, 1.29, -1, 1.053, 1, 1.29, 1 ]
},
{ "time": 1.3318, "x": -1, "curve": "stepped" },
{
"time": 1.3333,
"curve": [ 1.384, 1, 1.439, 0.94, 1.384, 1, 1.439, 1 ]
},
{
"time": 1.5,
"x": 0.852,
"curve": [ 1.564, 0.75, 1.703, 0.51, 1.564, 1, 1.703, 1 ]
},
{
"time": 1.8,
"x": 0.315,
"curve": [ 1.873, 0.13, 1.987, 0.01, 1.873, 1, 1.987, 1 ]
},
{ "time": 1.9982, "x": 0.014, "curve": "stepped" },
{
"time": 2.0022,
"x": -0.028,
"curve": [ 2.039, -0.07, 2.123, -0.24, 2.039, 1, 2.123, 1 ]
},
{
"time": 2.2018,
"x": -0.365,
"curve": [ 2.269, -0.51, 2.337, -0.63, 2.269, 1, 2.337, 1 ]
},
{
"time": 2.4,
"x": -0.731,
"curve": [ 2.503, -0.87, 2.596, -0.96, 2.503, 1, 2.596, 1 ]
},
{
"time": 2.6592,
"x": -1,
"curve": [ 2.661, -1, 2.665, 1, 2.661, 1, 2.665, 1 ]
},
{ "time": 2.6667 }
]
},
"shine": {
"translate": [
{
"curve": [ 0.167, 0, 0.5, -473.39, 0.167, 0, 0.5, 0 ]
},
{
"time": 0.6667,
"x": -473.39,
"curve": [ 0.833, -473.39, 1.167, -33.16, 0.833, 0, 1.167, 0 ]
},
{
"time": 1.3333,
"x": -33.16,
"curve": [ 1.5, -33.16, 1.833, -473.39, 1.5, 0, 1.833, 0 ]
},
{
"time": 2,
"x": -473.39,
"curve": [ 2.167, -473.39, 2.5, 0, 2.167, 0, 2.5, 0 ]
},
{ "time": 2.6667 }
]
}
},
"drawOrder": [
{
"time": 0.6667,
"offsets": [
{ "slot": "coin-side", "offset": 2 }
]
},
{ "time": 0.6696 },
{
"time": 1.9982,
"offsets": [
{ "slot": "coin-side", "offset": 2 }
]
},
{ "time": 2.0022 }
]
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -35,7 +35,7 @@ function init() {
assetManager.loadTextureAtlas(FILE.replace("-pro", "").replace("-ess", "") + "-pma.atlas"); assetManager.loadTextureAtlas(FILE.replace("-pro", "").replace("-ess", "") + "-pma.atlas");
assetManager.loadBinary(FILE + ".skel"); assetManager.loadBinary(FILE + ".skel");
assetManager.loadText(FILE + ".json"); // assetManager.loadText(FILE + ".json");
timeKeeper = new spine.TimeKeeper(); timeKeeper = new spine.TimeKeeper();
requestAnimationFrame(load); requestAnimationFrame(load);