Bläddra i källkod

[ts] Port of new AnimationState, needs testing

badlogic 9 år sedan
förälder
incheckning
787af5c8f8

+ 144 - 47
spine-ts/build/spine-all.d.ts

@@ -92,13 +92,29 @@ declare module spine {
 		timelines: Array<Timeline>;
 		timelines: Array<Timeline>;
 		duration: number;
 		duration: number;
 		constructor(name: string, timelines: Array<Timeline>, duration: number);
 		constructor(name: string, timelines: Array<Timeline>, duration: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>): void;
-		mix(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 		static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
 		static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
 		static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
 		static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
 	}
 	}
 	interface Timeline {
 	interface Timeline {
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+		getPropertyId(): number;
+	}
+	enum TimelineType {
+		rotate = 0,
+		translate = 1,
+		scale = 2,
+		shear = 3,
+		attachment = 4,
+		color = 5,
+		deform = 6,
+		event = 7,
+		drawOrder = 8,
+		ikConstraint = 9,
+		transformConstraint = 10,
+		pathConstraintPosition = 11,
+		pathConstraintSpacing = 12,
+		pathConstraintMix = 13,
 	}
 	}
 	abstract class CurveTimeline implements Timeline {
 	abstract class CurveTimeline implements Timeline {
 		static LINEAR: number;
 		static LINEAR: number;
@@ -106,6 +122,7 @@ declare module spine {
 		static BEZIER: number;
 		static BEZIER: number;
 		static BEZIER_SIZE: number;
 		static BEZIER_SIZE: number;
 		private curves;
 		private curves;
+		abstract getPropertyId(): number;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
 		getFrameCount(): number;
 		getFrameCount(): number;
 		setLinear(frameIndex: number): void;
 		setLinear(frameIndex: number): void;
@@ -113,7 +130,7 @@ declare module spine {
 		getCurveType(frameIndex: number): number;
 		getCurveType(frameIndex: number): number;
 		setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
 		setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
 		getCurvePercent(frameIndex: number, percent: number): number;
 		getCurvePercent(frameIndex: number, percent: number): number;
-		abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class RotateTimeline extends CurveTimeline {
 	class RotateTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -123,8 +140,9 @@ declare module spine {
 		boneIndex: number;
 		boneIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, degrees: number): void;
 		setFrame(frameIndex: number, time: number, degrees: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class TranslateTimeline extends CurveTimeline {
 	class TranslateTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -136,16 +154,19 @@ declare module spine {
 		boneIndex: number;
 		boneIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, x: number, y: number): void;
 		setFrame(frameIndex: number, time: number, x: number, y: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ScaleTimeline extends TranslateTimeline {
 	class ScaleTimeline extends TranslateTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ShearTimeline extends TranslateTimeline {
 	class ShearTimeline extends TranslateTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ColorTimeline extends CurveTimeline {
 	class ColorTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -161,42 +182,47 @@ declare module spine {
 		slotIndex: number;
 		slotIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class AttachmentTimeline implements Timeline {
 	class AttachmentTimeline implements Timeline {
 		slotIndex: number;
 		slotIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		attachmentNames: Array<string>;
 		attachmentNames: Array<string>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class EventTimeline implements Timeline {
 	class EventTimeline implements Timeline {
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		events: Array<Event>;
 		events: Array<Event>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		getFrameCount(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class DrawOrderTimeline implements Timeline {
 	class DrawOrderTimeline implements Timeline {
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		drawOrders: Array<Array<number>>;
 		drawOrders: Array<Array<number>>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		getFrameCount(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class DeformTimeline extends CurveTimeline {
 	class DeformTimeline extends CurveTimeline {
-		frames: ArrayLike<number>;
-		frameVertices: Array<ArrayLike<number>>;
 		slotIndex: number;
 		slotIndex: number;
 		attachment: VertexAttachment;
 		attachment: VertexAttachment;
+		frames: ArrayLike<number>;
+		frameVertices: Array<ArrayLike<number>>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
 		setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class IkConstraintTimeline extends CurveTimeline {
 	class IkConstraintTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -208,8 +234,9 @@ declare module spine {
 		ikConstraintIndex: number;
 		ikConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void;
 		setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class TransformConstraintTimeline extends CurveTimeline {
 	class TransformConstraintTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -225,8 +252,9 @@ declare module spine {
 		transformConstraintIndex: number;
 		transformConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintPositionTimeline extends CurveTimeline {
 	class PathConstraintPositionTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -236,12 +264,14 @@ declare module spine {
 		pathConstraintIndex: number;
 		pathConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
 	class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintMixTimeline extends CurveTimeline {
 	class PathConstraintMixTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -253,62 +283,121 @@ declare module spine {
 		pathConstraintIndex: number;
 		pathConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
 		setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 }
 }
 declare module spine {
 declare module spine {
 	class AnimationState {
 	class AnimationState {
+		static emptyAnimation: Animation;
 		data: AnimationStateData;
 		data: AnimationStateData;
 		tracks: TrackEntry[];
 		tracks: TrackEntry[];
 		events: Event[];
 		events: Event[];
-		listeners: AnimationStateListener[];
+		listeners: AnimationStateListener2[];
+		queue: EventQueue;
+		propertyIDs: IntSet;
+		animationsChanged: boolean;
 		timeScale: number;
 		timeScale: number;
-		constructor(data?: AnimationStateData);
+		trackEntryPool: Pool<TrackEntry>;
+		constructor(data: AnimationStateData);
 		update(delta: number): void;
 		update(delta: number): void;
+		updateMixingFrom(entry: TrackEntry, delta: number, canEnd: boolean): void;
 		apply(skeleton: Skeleton): void;
 		apply(skeleton: Skeleton): void;
+		applyMixingFrom(entry: TrackEntry, skeleton: Skeleton, alpha: number): number;
+		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
+		queueEvents(entry: TrackEntry, animationTime: number): void;
 		clearTracks(): void;
 		clearTracks(): void;
 		clearTrack(trackIndex: number): void;
 		clearTrack(trackIndex: number): void;
-		freeAll(entry: TrackEntry): void;
+		setCurrent(index: number, current: TrackEntry): void;
+		setAnimationByName(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
+		setAnimation(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
+		addAnimationByName(trackIndex: number, animationName: string, loop: boolean, delay: number): TrackEntry;
+		addAnimation(trackIndex: number, animation: Animation, loop: boolean, delay: number): TrackEntry;
+		setEmptyAnimation(trackIndex: number, mixDuration: number): TrackEntry;
+		addEmptyAnimation(trackIndex: number, mixDuration: number, delay: number): TrackEntry;
+		setEmptyAnimations(mixDuration: number): void;
 		expandToIndex(index: number): TrackEntry;
 		expandToIndex(index: number): TrackEntry;
-		setCurrent(index: number, entry: TrackEntry): void;
-		setAnimation(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
-		setAnimationWith(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
-		addAnimation(trackIndex: number, animationName: string, loop: boolean, delay: number): TrackEntry;
-		addAnimationWith(trackIndex: number, animation: Animation, loop: boolean, delay: number): TrackEntry;
+		trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry): TrackEntry;
+		disposeNext(entry: TrackEntry): void;
+		_animationsChanged(): void;
+		setTimelinesFirst(entry: TrackEntry): void;
+		checkTimelinesFirst(entry: TrackEntry): void;
+		checkTimelinesUsage(entry: TrackEntry, usageArray: Array<boolean>): void;
 		getCurrent(trackIndex: number): TrackEntry;
 		getCurrent(trackIndex: number): TrackEntry;
-		addListener(listener: AnimationStateListener): void;
-		removeListener(listener: AnimationStateListener): void;
+		addListener(listener: AnimationStateListener2): void;
+		removeListener(listener: AnimationStateListener2): void;
 		clearListeners(): void;
 		clearListeners(): void;
+		clearListenerNotifications(): void;
 	}
 	}
 	class TrackEntry {
 	class TrackEntry {
-		next: TrackEntry;
-		previous: TrackEntry;
 		animation: Animation;
 		animation: Animation;
+		next: TrackEntry;
+		mixingFrom: TrackEntry;
+		listener: AnimationStateListener2;
+		trackIndex: number;
 		loop: boolean;
 		loop: boolean;
+		eventThreshold: number;
+		attachmentThreshold: number;
+		drawOrderThreshold: number;
+		animationStart: number;
+		animationEnd: number;
+		animationLast: number;
+		nextAnimationLast: number;
 		delay: number;
 		delay: number;
-		time: number;
-		lastTime: number;
-		endTime: number;
+		trackTime: number;
+		trackLast: number;
+		nextTrackLast: number;
+		trackEnd: number;
 		timeScale: number;
 		timeScale: number;
+		alpha: number;
 		mixTime: number;
 		mixTime: number;
 		mixDuration: number;
 		mixDuration: number;
-		listener: AnimationStateListener;
-		mix: number;
+		mixAlpha: number;
+		timelinesFirst: boolean[];
+		timelinesRotation: number[];
 		reset(): void;
 		reset(): void;
+		getAnimationTime(): number;
+		setAnimationLast(animationLast: number): void;
 		isComplete(): boolean;
 		isComplete(): boolean;
 	}
 	}
-	abstract class AnimationStateAdapter implements AnimationStateListener {
-		event(trackIndex: number, event: Event): void;
-		complete(trackIndex: number, loopCount: number): void;
-		start(trackIndex: number): void;
-		end(trackIndex: number): void;
+	class EventQueue {
+		objects: Array<any>;
+		drainDisabled: boolean;
+		animState: AnimationState;
+		constructor(animState: AnimationState);
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
+		drain(): void;
+		clear(): void;
 	}
 	}
-	interface AnimationStateListener {
-		event(trackIndex: number, event: Event): void;
-		complete(trackIndex: number, loopCount: number): void;
-		start(trackIndex: number): void;
-		end(trackIndex: number): void;
+	enum EventType {
+		start = 0,
+		interrupt = 1,
+		end = 2,
+		dispose = 3,
+		complete = 4,
+		event = 5,
+	}
+	interface AnimationStateListener2 {
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
+	}
+	abstract class AnimationStateAdapter2 implements AnimationStateListener2 {
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
 	}
 	}
 }
 }
 declare module spine {
 declare module spine {
@@ -898,6 +987,13 @@ declare module spine {
 	interface Map<T> {
 	interface Map<T> {
 		[key: string]: T;
 		[key: string]: T;
 	}
 	}
+	class IntSet {
+		array: number[];
+		add(value: number): boolean;
+		contains(value: number): boolean;
+		remove(value: number): void;
+		clear(): void;
+	}
 	interface Disposable {
 	interface Disposable {
 		dispose(): void;
 		dispose(): void;
 	}
 	}
@@ -936,6 +1032,7 @@ declare module spine {
 		static SUPPORTS_TYPED_ARRAYS: boolean;
 		static SUPPORTS_TYPED_ARRAYS: boolean;
 		static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
 		static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
 		static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
 		static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
+		static ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
 		static newArray<T>(size: number, defaultValue: T): Array<T>;
 		static newArray<T>(size: number, defaultValue: T): Array<T>;
 		static newFloatArray(size: number): ArrayLike<number>;
 		static newFloatArray(size: number): ArrayLike<number>;
 		static toFloatArray(array: Array<number>): number[] | Float32Array;
 		static toFloatArray(array: Array<number>): number[] | Float32Array;

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 545 - 195
spine-ts/build/spine-all.js


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 0
spine-ts/build/spine-all.js.map


+ 144 - 47
spine-ts/build/spine-canvas.d.ts

@@ -92,13 +92,29 @@ declare module spine {
 		timelines: Array<Timeline>;
 		timelines: Array<Timeline>;
 		duration: number;
 		duration: number;
 		constructor(name: string, timelines: Array<Timeline>, duration: number);
 		constructor(name: string, timelines: Array<Timeline>, duration: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>): void;
-		mix(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 		static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
 		static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
 		static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
 		static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
 	}
 	}
 	interface Timeline {
 	interface Timeline {
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+		getPropertyId(): number;
+	}
+	enum TimelineType {
+		rotate = 0,
+		translate = 1,
+		scale = 2,
+		shear = 3,
+		attachment = 4,
+		color = 5,
+		deform = 6,
+		event = 7,
+		drawOrder = 8,
+		ikConstraint = 9,
+		transformConstraint = 10,
+		pathConstraintPosition = 11,
+		pathConstraintSpacing = 12,
+		pathConstraintMix = 13,
 	}
 	}
 	abstract class CurveTimeline implements Timeline {
 	abstract class CurveTimeline implements Timeline {
 		static LINEAR: number;
 		static LINEAR: number;
@@ -106,6 +122,7 @@ declare module spine {
 		static BEZIER: number;
 		static BEZIER: number;
 		static BEZIER_SIZE: number;
 		static BEZIER_SIZE: number;
 		private curves;
 		private curves;
+		abstract getPropertyId(): number;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
 		getFrameCount(): number;
 		getFrameCount(): number;
 		setLinear(frameIndex: number): void;
 		setLinear(frameIndex: number): void;
@@ -113,7 +130,7 @@ declare module spine {
 		getCurveType(frameIndex: number): number;
 		getCurveType(frameIndex: number): number;
 		setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
 		setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
 		getCurvePercent(frameIndex: number, percent: number): number;
 		getCurvePercent(frameIndex: number, percent: number): number;
-		abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class RotateTimeline extends CurveTimeline {
 	class RotateTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -123,8 +140,9 @@ declare module spine {
 		boneIndex: number;
 		boneIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, degrees: number): void;
 		setFrame(frameIndex: number, time: number, degrees: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class TranslateTimeline extends CurveTimeline {
 	class TranslateTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -136,16 +154,19 @@ declare module spine {
 		boneIndex: number;
 		boneIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, x: number, y: number): void;
 		setFrame(frameIndex: number, time: number, x: number, y: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ScaleTimeline extends TranslateTimeline {
 	class ScaleTimeline extends TranslateTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ShearTimeline extends TranslateTimeline {
 	class ShearTimeline extends TranslateTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ColorTimeline extends CurveTimeline {
 	class ColorTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -161,42 +182,47 @@ declare module spine {
 		slotIndex: number;
 		slotIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class AttachmentTimeline implements Timeline {
 	class AttachmentTimeline implements Timeline {
 		slotIndex: number;
 		slotIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		attachmentNames: Array<string>;
 		attachmentNames: Array<string>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class EventTimeline implements Timeline {
 	class EventTimeline implements Timeline {
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		events: Array<Event>;
 		events: Array<Event>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		getFrameCount(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class DrawOrderTimeline implements Timeline {
 	class DrawOrderTimeline implements Timeline {
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		drawOrders: Array<Array<number>>;
 		drawOrders: Array<Array<number>>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		getFrameCount(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class DeformTimeline extends CurveTimeline {
 	class DeformTimeline extends CurveTimeline {
-		frames: ArrayLike<number>;
-		frameVertices: Array<ArrayLike<number>>;
 		slotIndex: number;
 		slotIndex: number;
 		attachment: VertexAttachment;
 		attachment: VertexAttachment;
+		frames: ArrayLike<number>;
+		frameVertices: Array<ArrayLike<number>>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
 		setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class IkConstraintTimeline extends CurveTimeline {
 	class IkConstraintTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -208,8 +234,9 @@ declare module spine {
 		ikConstraintIndex: number;
 		ikConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void;
 		setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class TransformConstraintTimeline extends CurveTimeline {
 	class TransformConstraintTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -225,8 +252,9 @@ declare module spine {
 		transformConstraintIndex: number;
 		transformConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintPositionTimeline extends CurveTimeline {
 	class PathConstraintPositionTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -236,12 +264,14 @@ declare module spine {
 		pathConstraintIndex: number;
 		pathConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
 	class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintMixTimeline extends CurveTimeline {
 	class PathConstraintMixTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -253,62 +283,121 @@ declare module spine {
 		pathConstraintIndex: number;
 		pathConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
 		setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 }
 }
 declare module spine {
 declare module spine {
 	class AnimationState {
 	class AnimationState {
+		static emptyAnimation: Animation;
 		data: AnimationStateData;
 		data: AnimationStateData;
 		tracks: TrackEntry[];
 		tracks: TrackEntry[];
 		events: Event[];
 		events: Event[];
-		listeners: AnimationStateListener[];
+		listeners: AnimationStateListener2[];
+		queue: EventQueue;
+		propertyIDs: IntSet;
+		animationsChanged: boolean;
 		timeScale: number;
 		timeScale: number;
-		constructor(data?: AnimationStateData);
+		trackEntryPool: Pool<TrackEntry>;
+		constructor(data: AnimationStateData);
 		update(delta: number): void;
 		update(delta: number): void;
+		updateMixingFrom(entry: TrackEntry, delta: number, canEnd: boolean): void;
 		apply(skeleton: Skeleton): void;
 		apply(skeleton: Skeleton): void;
+		applyMixingFrom(entry: TrackEntry, skeleton: Skeleton, alpha: number): number;
+		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
+		queueEvents(entry: TrackEntry, animationTime: number): void;
 		clearTracks(): void;
 		clearTracks(): void;
 		clearTrack(trackIndex: number): void;
 		clearTrack(trackIndex: number): void;
-		freeAll(entry: TrackEntry): void;
+		setCurrent(index: number, current: TrackEntry): void;
+		setAnimationByName(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
+		setAnimation(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
+		addAnimationByName(trackIndex: number, animationName: string, loop: boolean, delay: number): TrackEntry;
+		addAnimation(trackIndex: number, animation: Animation, loop: boolean, delay: number): TrackEntry;
+		setEmptyAnimation(trackIndex: number, mixDuration: number): TrackEntry;
+		addEmptyAnimation(trackIndex: number, mixDuration: number, delay: number): TrackEntry;
+		setEmptyAnimations(mixDuration: number): void;
 		expandToIndex(index: number): TrackEntry;
 		expandToIndex(index: number): TrackEntry;
-		setCurrent(index: number, entry: TrackEntry): void;
-		setAnimation(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
-		setAnimationWith(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
-		addAnimation(trackIndex: number, animationName: string, loop: boolean, delay: number): TrackEntry;
-		addAnimationWith(trackIndex: number, animation: Animation, loop: boolean, delay: number): TrackEntry;
+		trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry): TrackEntry;
+		disposeNext(entry: TrackEntry): void;
+		_animationsChanged(): void;
+		setTimelinesFirst(entry: TrackEntry): void;
+		checkTimelinesFirst(entry: TrackEntry): void;
+		checkTimelinesUsage(entry: TrackEntry, usageArray: Array<boolean>): void;
 		getCurrent(trackIndex: number): TrackEntry;
 		getCurrent(trackIndex: number): TrackEntry;
-		addListener(listener: AnimationStateListener): void;
-		removeListener(listener: AnimationStateListener): void;
+		addListener(listener: AnimationStateListener2): void;
+		removeListener(listener: AnimationStateListener2): void;
 		clearListeners(): void;
 		clearListeners(): void;
+		clearListenerNotifications(): void;
 	}
 	}
 	class TrackEntry {
 	class TrackEntry {
-		next: TrackEntry;
-		previous: TrackEntry;
 		animation: Animation;
 		animation: Animation;
+		next: TrackEntry;
+		mixingFrom: TrackEntry;
+		listener: AnimationStateListener2;
+		trackIndex: number;
 		loop: boolean;
 		loop: boolean;
+		eventThreshold: number;
+		attachmentThreshold: number;
+		drawOrderThreshold: number;
+		animationStart: number;
+		animationEnd: number;
+		animationLast: number;
+		nextAnimationLast: number;
 		delay: number;
 		delay: number;
-		time: number;
-		lastTime: number;
-		endTime: number;
+		trackTime: number;
+		trackLast: number;
+		nextTrackLast: number;
+		trackEnd: number;
 		timeScale: number;
 		timeScale: number;
+		alpha: number;
 		mixTime: number;
 		mixTime: number;
 		mixDuration: number;
 		mixDuration: number;
-		listener: AnimationStateListener;
-		mix: number;
+		mixAlpha: number;
+		timelinesFirst: boolean[];
+		timelinesRotation: number[];
 		reset(): void;
 		reset(): void;
+		getAnimationTime(): number;
+		setAnimationLast(animationLast: number): void;
 		isComplete(): boolean;
 		isComplete(): boolean;
 	}
 	}
-	abstract class AnimationStateAdapter implements AnimationStateListener {
-		event(trackIndex: number, event: Event): void;
-		complete(trackIndex: number, loopCount: number): void;
-		start(trackIndex: number): void;
-		end(trackIndex: number): void;
+	class EventQueue {
+		objects: Array<any>;
+		drainDisabled: boolean;
+		animState: AnimationState;
+		constructor(animState: AnimationState);
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
+		drain(): void;
+		clear(): void;
 	}
 	}
-	interface AnimationStateListener {
-		event(trackIndex: number, event: Event): void;
-		complete(trackIndex: number, loopCount: number): void;
-		start(trackIndex: number): void;
-		end(trackIndex: number): void;
+	enum EventType {
+		start = 0,
+		interrupt = 1,
+		end = 2,
+		dispose = 3,
+		complete = 4,
+		event = 5,
+	}
+	interface AnimationStateListener2 {
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
+	}
+	abstract class AnimationStateAdapter2 implements AnimationStateListener2 {
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
 	}
 	}
 }
 }
 declare module spine {
 declare module spine {
@@ -898,6 +987,13 @@ declare module spine {
 	interface Map<T> {
 	interface Map<T> {
 		[key: string]: T;
 		[key: string]: T;
 	}
 	}
+	class IntSet {
+		array: number[];
+		add(value: number): boolean;
+		contains(value: number): boolean;
+		remove(value: number): void;
+		clear(): void;
+	}
 	interface Disposable {
 	interface Disposable {
 		dispose(): void;
 		dispose(): void;
 	}
 	}
@@ -936,6 +1032,7 @@ declare module spine {
 		static SUPPORTS_TYPED_ARRAYS: boolean;
 		static SUPPORTS_TYPED_ARRAYS: boolean;
 		static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
 		static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
 		static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
 		static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
+		static ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
 		static newArray<T>(size: number, defaultValue: T): Array<T>;
 		static newArray<T>(size: number, defaultValue: T): Array<T>;
 		static newFloatArray(size: number): ArrayLike<number>;
 		static newFloatArray(size: number): ArrayLike<number>;
 		static toFloatArray(array: Array<number>): number[] | Float32Array;
 		static toFloatArray(array: Array<number>): number[] | Float32Array;

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 545 - 195
spine-ts/build/spine-canvas.js


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 0
spine-ts/build/spine-canvas.js.map


+ 144 - 47
spine-ts/build/spine-core.d.ts

@@ -4,13 +4,29 @@ declare module spine {
 		timelines: Array<Timeline>;
 		timelines: Array<Timeline>;
 		duration: number;
 		duration: number;
 		constructor(name: string, timelines: Array<Timeline>, duration: number);
 		constructor(name: string, timelines: Array<Timeline>, duration: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>): void;
-		mix(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 		static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
 		static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
 		static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
 		static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
 	}
 	}
 	interface Timeline {
 	interface Timeline {
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+		getPropertyId(): number;
+	}
+	enum TimelineType {
+		rotate = 0,
+		translate = 1,
+		scale = 2,
+		shear = 3,
+		attachment = 4,
+		color = 5,
+		deform = 6,
+		event = 7,
+		drawOrder = 8,
+		ikConstraint = 9,
+		transformConstraint = 10,
+		pathConstraintPosition = 11,
+		pathConstraintSpacing = 12,
+		pathConstraintMix = 13,
 	}
 	}
 	abstract class CurveTimeline implements Timeline {
 	abstract class CurveTimeline implements Timeline {
 		static LINEAR: number;
 		static LINEAR: number;
@@ -18,6 +34,7 @@ declare module spine {
 		static BEZIER: number;
 		static BEZIER: number;
 		static BEZIER_SIZE: number;
 		static BEZIER_SIZE: number;
 		private curves;
 		private curves;
+		abstract getPropertyId(): number;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
 		getFrameCount(): number;
 		getFrameCount(): number;
 		setLinear(frameIndex: number): void;
 		setLinear(frameIndex: number): void;
@@ -25,7 +42,7 @@ declare module spine {
 		getCurveType(frameIndex: number): number;
 		getCurveType(frameIndex: number): number;
 		setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
 		setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
 		getCurvePercent(frameIndex: number, percent: number): number;
 		getCurvePercent(frameIndex: number, percent: number): number;
-		abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class RotateTimeline extends CurveTimeline {
 	class RotateTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -35,8 +52,9 @@ declare module spine {
 		boneIndex: number;
 		boneIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, degrees: number): void;
 		setFrame(frameIndex: number, time: number, degrees: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class TranslateTimeline extends CurveTimeline {
 	class TranslateTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -48,16 +66,19 @@ declare module spine {
 		boneIndex: number;
 		boneIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, x: number, y: number): void;
 		setFrame(frameIndex: number, time: number, x: number, y: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ScaleTimeline extends TranslateTimeline {
 	class ScaleTimeline extends TranslateTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ShearTimeline extends TranslateTimeline {
 	class ShearTimeline extends TranslateTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ColorTimeline extends CurveTimeline {
 	class ColorTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -73,42 +94,47 @@ declare module spine {
 		slotIndex: number;
 		slotIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class AttachmentTimeline implements Timeline {
 	class AttachmentTimeline implements Timeline {
 		slotIndex: number;
 		slotIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		attachmentNames: Array<string>;
 		attachmentNames: Array<string>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class EventTimeline implements Timeline {
 	class EventTimeline implements Timeline {
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		events: Array<Event>;
 		events: Array<Event>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		getFrameCount(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class DrawOrderTimeline implements Timeline {
 	class DrawOrderTimeline implements Timeline {
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		drawOrders: Array<Array<number>>;
 		drawOrders: Array<Array<number>>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		getFrameCount(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class DeformTimeline extends CurveTimeline {
 	class DeformTimeline extends CurveTimeline {
-		frames: ArrayLike<number>;
-		frameVertices: Array<ArrayLike<number>>;
 		slotIndex: number;
 		slotIndex: number;
 		attachment: VertexAttachment;
 		attachment: VertexAttachment;
+		frames: ArrayLike<number>;
+		frameVertices: Array<ArrayLike<number>>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
 		setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class IkConstraintTimeline extends CurveTimeline {
 	class IkConstraintTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -120,8 +146,9 @@ declare module spine {
 		ikConstraintIndex: number;
 		ikConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void;
 		setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class TransformConstraintTimeline extends CurveTimeline {
 	class TransformConstraintTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -137,8 +164,9 @@ declare module spine {
 		transformConstraintIndex: number;
 		transformConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintPositionTimeline extends CurveTimeline {
 	class PathConstraintPositionTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -148,12 +176,14 @@ declare module spine {
 		pathConstraintIndex: number;
 		pathConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
 	class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintMixTimeline extends CurveTimeline {
 	class PathConstraintMixTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -165,62 +195,121 @@ declare module spine {
 		pathConstraintIndex: number;
 		pathConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
 		setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 }
 }
 declare module spine {
 declare module spine {
 	class AnimationState {
 	class AnimationState {
+		static emptyAnimation: Animation;
 		data: AnimationStateData;
 		data: AnimationStateData;
 		tracks: TrackEntry[];
 		tracks: TrackEntry[];
 		events: Event[];
 		events: Event[];
-		listeners: AnimationStateListener[];
+		listeners: AnimationStateListener2[];
+		queue: EventQueue;
+		propertyIDs: IntSet;
+		animationsChanged: boolean;
 		timeScale: number;
 		timeScale: number;
-		constructor(data?: AnimationStateData);
+		trackEntryPool: Pool<TrackEntry>;
+		constructor(data: AnimationStateData);
 		update(delta: number): void;
 		update(delta: number): void;
+		updateMixingFrom(entry: TrackEntry, delta: number, canEnd: boolean): void;
 		apply(skeleton: Skeleton): void;
 		apply(skeleton: Skeleton): void;
+		applyMixingFrom(entry: TrackEntry, skeleton: Skeleton, alpha: number): number;
+		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
+		queueEvents(entry: TrackEntry, animationTime: number): void;
 		clearTracks(): void;
 		clearTracks(): void;
 		clearTrack(trackIndex: number): void;
 		clearTrack(trackIndex: number): void;
-		freeAll(entry: TrackEntry): void;
+		setCurrent(index: number, current: TrackEntry): void;
+		setAnimationByName(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
+		setAnimation(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
+		addAnimationByName(trackIndex: number, animationName: string, loop: boolean, delay: number): TrackEntry;
+		addAnimation(trackIndex: number, animation: Animation, loop: boolean, delay: number): TrackEntry;
+		setEmptyAnimation(trackIndex: number, mixDuration: number): TrackEntry;
+		addEmptyAnimation(trackIndex: number, mixDuration: number, delay: number): TrackEntry;
+		setEmptyAnimations(mixDuration: number): void;
 		expandToIndex(index: number): TrackEntry;
 		expandToIndex(index: number): TrackEntry;
-		setCurrent(index: number, entry: TrackEntry): void;
-		setAnimation(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
-		setAnimationWith(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
-		addAnimation(trackIndex: number, animationName: string, loop: boolean, delay: number): TrackEntry;
-		addAnimationWith(trackIndex: number, animation: Animation, loop: boolean, delay: number): TrackEntry;
+		trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry): TrackEntry;
+		disposeNext(entry: TrackEntry): void;
+		_animationsChanged(): void;
+		setTimelinesFirst(entry: TrackEntry): void;
+		checkTimelinesFirst(entry: TrackEntry): void;
+		checkTimelinesUsage(entry: TrackEntry, usageArray: Array<boolean>): void;
 		getCurrent(trackIndex: number): TrackEntry;
 		getCurrent(trackIndex: number): TrackEntry;
-		addListener(listener: AnimationStateListener): void;
-		removeListener(listener: AnimationStateListener): void;
+		addListener(listener: AnimationStateListener2): void;
+		removeListener(listener: AnimationStateListener2): void;
 		clearListeners(): void;
 		clearListeners(): void;
+		clearListenerNotifications(): void;
 	}
 	}
 	class TrackEntry {
 	class TrackEntry {
-		next: TrackEntry;
-		previous: TrackEntry;
 		animation: Animation;
 		animation: Animation;
+		next: TrackEntry;
+		mixingFrom: TrackEntry;
+		listener: AnimationStateListener2;
+		trackIndex: number;
 		loop: boolean;
 		loop: boolean;
+		eventThreshold: number;
+		attachmentThreshold: number;
+		drawOrderThreshold: number;
+		animationStart: number;
+		animationEnd: number;
+		animationLast: number;
+		nextAnimationLast: number;
 		delay: number;
 		delay: number;
-		time: number;
-		lastTime: number;
-		endTime: number;
+		trackTime: number;
+		trackLast: number;
+		nextTrackLast: number;
+		trackEnd: number;
 		timeScale: number;
 		timeScale: number;
+		alpha: number;
 		mixTime: number;
 		mixTime: number;
 		mixDuration: number;
 		mixDuration: number;
-		listener: AnimationStateListener;
-		mix: number;
+		mixAlpha: number;
+		timelinesFirst: boolean[];
+		timelinesRotation: number[];
 		reset(): void;
 		reset(): void;
+		getAnimationTime(): number;
+		setAnimationLast(animationLast: number): void;
 		isComplete(): boolean;
 		isComplete(): boolean;
 	}
 	}
-	abstract class AnimationStateAdapter implements AnimationStateListener {
-		event(trackIndex: number, event: Event): void;
-		complete(trackIndex: number, loopCount: number): void;
-		start(trackIndex: number): void;
-		end(trackIndex: number): void;
+	class EventQueue {
+		objects: Array<any>;
+		drainDisabled: boolean;
+		animState: AnimationState;
+		constructor(animState: AnimationState);
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
+		drain(): void;
+		clear(): void;
 	}
 	}
-	interface AnimationStateListener {
-		event(trackIndex: number, event: Event): void;
-		complete(trackIndex: number, loopCount: number): void;
-		start(trackIndex: number): void;
-		end(trackIndex: number): void;
+	enum EventType {
+		start = 0,
+		interrupt = 1,
+		end = 2,
+		dispose = 3,
+		complete = 4,
+		event = 5,
+	}
+	interface AnimationStateListener2 {
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
+	}
+	abstract class AnimationStateAdapter2 implements AnimationStateListener2 {
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
 	}
 	}
 }
 }
 declare module spine {
 declare module spine {
@@ -872,6 +961,13 @@ declare module spine {
 	interface Map<T> {
 	interface Map<T> {
 		[key: string]: T;
 		[key: string]: T;
 	}
 	}
+	class IntSet {
+		array: number[];
+		add(value: number): boolean;
+		contains(value: number): boolean;
+		remove(value: number): void;
+		clear(): void;
+	}
 	interface Disposable {
 	interface Disposable {
 		dispose(): void;
 		dispose(): void;
 	}
 	}
@@ -910,6 +1006,7 @@ declare module spine {
 		static SUPPORTS_TYPED_ARRAYS: boolean;
 		static SUPPORTS_TYPED_ARRAYS: boolean;
 		static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
 		static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
 		static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
 		static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
+		static ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
 		static newArray<T>(size: number, defaultValue: T): Array<T>;
 		static newArray<T>(size: number, defaultValue: T): Array<T>;
 		static newFloatArray(size: number): ArrayLike<number>;
 		static newFloatArray(size: number): ArrayLike<number>;
 		static toFloatArray(array: Array<number>): number[] | Float32Array;
 		static toFloatArray(array: Array<number>): number[] | Float32Array;

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 545 - 195
spine-ts/build/spine-core.js


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 0
spine-ts/build/spine-core.js.map


+ 144 - 47
spine-ts/build/spine-threejs.d.ts

@@ -4,13 +4,29 @@ declare module spine {
 		timelines: Array<Timeline>;
 		timelines: Array<Timeline>;
 		duration: number;
 		duration: number;
 		constructor(name: string, timelines: Array<Timeline>, duration: number);
 		constructor(name: string, timelines: Array<Timeline>, duration: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>): void;
-		mix(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 		static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
 		static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
 		static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
 		static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
 	}
 	}
 	interface Timeline {
 	interface Timeline {
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+		getPropertyId(): number;
+	}
+	enum TimelineType {
+		rotate = 0,
+		translate = 1,
+		scale = 2,
+		shear = 3,
+		attachment = 4,
+		color = 5,
+		deform = 6,
+		event = 7,
+		drawOrder = 8,
+		ikConstraint = 9,
+		transformConstraint = 10,
+		pathConstraintPosition = 11,
+		pathConstraintSpacing = 12,
+		pathConstraintMix = 13,
 	}
 	}
 	abstract class CurveTimeline implements Timeline {
 	abstract class CurveTimeline implements Timeline {
 		static LINEAR: number;
 		static LINEAR: number;
@@ -18,6 +34,7 @@ declare module spine {
 		static BEZIER: number;
 		static BEZIER: number;
 		static BEZIER_SIZE: number;
 		static BEZIER_SIZE: number;
 		private curves;
 		private curves;
+		abstract getPropertyId(): number;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
 		getFrameCount(): number;
 		getFrameCount(): number;
 		setLinear(frameIndex: number): void;
 		setLinear(frameIndex: number): void;
@@ -25,7 +42,7 @@ declare module spine {
 		getCurveType(frameIndex: number): number;
 		getCurveType(frameIndex: number): number;
 		setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
 		setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
 		getCurvePercent(frameIndex: number, percent: number): number;
 		getCurvePercent(frameIndex: number, percent: number): number;
-		abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class RotateTimeline extends CurveTimeline {
 	class RotateTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -35,8 +52,9 @@ declare module spine {
 		boneIndex: number;
 		boneIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, degrees: number): void;
 		setFrame(frameIndex: number, time: number, degrees: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class TranslateTimeline extends CurveTimeline {
 	class TranslateTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -48,16 +66,19 @@ declare module spine {
 		boneIndex: number;
 		boneIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, x: number, y: number): void;
 		setFrame(frameIndex: number, time: number, x: number, y: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ScaleTimeline extends TranslateTimeline {
 	class ScaleTimeline extends TranslateTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ShearTimeline extends TranslateTimeline {
 	class ShearTimeline extends TranslateTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ColorTimeline extends CurveTimeline {
 	class ColorTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -73,42 +94,47 @@ declare module spine {
 		slotIndex: number;
 		slotIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class AttachmentTimeline implements Timeline {
 	class AttachmentTimeline implements Timeline {
 		slotIndex: number;
 		slotIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		attachmentNames: Array<string>;
 		attachmentNames: Array<string>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class EventTimeline implements Timeline {
 	class EventTimeline implements Timeline {
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		events: Array<Event>;
 		events: Array<Event>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		getFrameCount(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class DrawOrderTimeline implements Timeline {
 	class DrawOrderTimeline implements Timeline {
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		drawOrders: Array<Array<number>>;
 		drawOrders: Array<Array<number>>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		getFrameCount(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class DeformTimeline extends CurveTimeline {
 	class DeformTimeline extends CurveTimeline {
-		frames: ArrayLike<number>;
-		frameVertices: Array<ArrayLike<number>>;
 		slotIndex: number;
 		slotIndex: number;
 		attachment: VertexAttachment;
 		attachment: VertexAttachment;
+		frames: ArrayLike<number>;
+		frameVertices: Array<ArrayLike<number>>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
 		setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class IkConstraintTimeline extends CurveTimeline {
 	class IkConstraintTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -120,8 +146,9 @@ declare module spine {
 		ikConstraintIndex: number;
 		ikConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void;
 		setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class TransformConstraintTimeline extends CurveTimeline {
 	class TransformConstraintTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -137,8 +164,9 @@ declare module spine {
 		transformConstraintIndex: number;
 		transformConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintPositionTimeline extends CurveTimeline {
 	class PathConstraintPositionTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -148,12 +176,14 @@ declare module spine {
 		pathConstraintIndex: number;
 		pathConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
 	class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintMixTimeline extends CurveTimeline {
 	class PathConstraintMixTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -165,62 +195,121 @@ declare module spine {
 		pathConstraintIndex: number;
 		pathConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
 		setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 }
 }
 declare module spine {
 declare module spine {
 	class AnimationState {
 	class AnimationState {
+		static emptyAnimation: Animation;
 		data: AnimationStateData;
 		data: AnimationStateData;
 		tracks: TrackEntry[];
 		tracks: TrackEntry[];
 		events: Event[];
 		events: Event[];
-		listeners: AnimationStateListener[];
+		listeners: AnimationStateListener2[];
+		queue: EventQueue;
+		propertyIDs: IntSet;
+		animationsChanged: boolean;
 		timeScale: number;
 		timeScale: number;
-		constructor(data?: AnimationStateData);
+		trackEntryPool: Pool<TrackEntry>;
+		constructor(data: AnimationStateData);
 		update(delta: number): void;
 		update(delta: number): void;
+		updateMixingFrom(entry: TrackEntry, delta: number, canEnd: boolean): void;
 		apply(skeleton: Skeleton): void;
 		apply(skeleton: Skeleton): void;
+		applyMixingFrom(entry: TrackEntry, skeleton: Skeleton, alpha: number): number;
+		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
+		queueEvents(entry: TrackEntry, animationTime: number): void;
 		clearTracks(): void;
 		clearTracks(): void;
 		clearTrack(trackIndex: number): void;
 		clearTrack(trackIndex: number): void;
-		freeAll(entry: TrackEntry): void;
+		setCurrent(index: number, current: TrackEntry): void;
+		setAnimationByName(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
+		setAnimation(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
+		addAnimationByName(trackIndex: number, animationName: string, loop: boolean, delay: number): TrackEntry;
+		addAnimation(trackIndex: number, animation: Animation, loop: boolean, delay: number): TrackEntry;
+		setEmptyAnimation(trackIndex: number, mixDuration: number): TrackEntry;
+		addEmptyAnimation(trackIndex: number, mixDuration: number, delay: number): TrackEntry;
+		setEmptyAnimations(mixDuration: number): void;
 		expandToIndex(index: number): TrackEntry;
 		expandToIndex(index: number): TrackEntry;
-		setCurrent(index: number, entry: TrackEntry): void;
-		setAnimation(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
-		setAnimationWith(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
-		addAnimation(trackIndex: number, animationName: string, loop: boolean, delay: number): TrackEntry;
-		addAnimationWith(trackIndex: number, animation: Animation, loop: boolean, delay: number): TrackEntry;
+		trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry): TrackEntry;
+		disposeNext(entry: TrackEntry): void;
+		_animationsChanged(): void;
+		setTimelinesFirst(entry: TrackEntry): void;
+		checkTimelinesFirst(entry: TrackEntry): void;
+		checkTimelinesUsage(entry: TrackEntry, usageArray: Array<boolean>): void;
 		getCurrent(trackIndex: number): TrackEntry;
 		getCurrent(trackIndex: number): TrackEntry;
-		addListener(listener: AnimationStateListener): void;
-		removeListener(listener: AnimationStateListener): void;
+		addListener(listener: AnimationStateListener2): void;
+		removeListener(listener: AnimationStateListener2): void;
 		clearListeners(): void;
 		clearListeners(): void;
+		clearListenerNotifications(): void;
 	}
 	}
 	class TrackEntry {
 	class TrackEntry {
-		next: TrackEntry;
-		previous: TrackEntry;
 		animation: Animation;
 		animation: Animation;
+		next: TrackEntry;
+		mixingFrom: TrackEntry;
+		listener: AnimationStateListener2;
+		trackIndex: number;
 		loop: boolean;
 		loop: boolean;
+		eventThreshold: number;
+		attachmentThreshold: number;
+		drawOrderThreshold: number;
+		animationStart: number;
+		animationEnd: number;
+		animationLast: number;
+		nextAnimationLast: number;
 		delay: number;
 		delay: number;
-		time: number;
-		lastTime: number;
-		endTime: number;
+		trackTime: number;
+		trackLast: number;
+		nextTrackLast: number;
+		trackEnd: number;
 		timeScale: number;
 		timeScale: number;
+		alpha: number;
 		mixTime: number;
 		mixTime: number;
 		mixDuration: number;
 		mixDuration: number;
-		listener: AnimationStateListener;
-		mix: number;
+		mixAlpha: number;
+		timelinesFirst: boolean[];
+		timelinesRotation: number[];
 		reset(): void;
 		reset(): void;
+		getAnimationTime(): number;
+		setAnimationLast(animationLast: number): void;
 		isComplete(): boolean;
 		isComplete(): boolean;
 	}
 	}
-	abstract class AnimationStateAdapter implements AnimationStateListener {
-		event(trackIndex: number, event: Event): void;
-		complete(trackIndex: number, loopCount: number): void;
-		start(trackIndex: number): void;
-		end(trackIndex: number): void;
+	class EventQueue {
+		objects: Array<any>;
+		drainDisabled: boolean;
+		animState: AnimationState;
+		constructor(animState: AnimationState);
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
+		drain(): void;
+		clear(): void;
 	}
 	}
-	interface AnimationStateListener {
-		event(trackIndex: number, event: Event): void;
-		complete(trackIndex: number, loopCount: number): void;
-		start(trackIndex: number): void;
-		end(trackIndex: number): void;
+	enum EventType {
+		start = 0,
+		interrupt = 1,
+		end = 2,
+		dispose = 3,
+		complete = 4,
+		event = 5,
+	}
+	interface AnimationStateListener2 {
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
+	}
+	abstract class AnimationStateAdapter2 implements AnimationStateListener2 {
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
 	}
 	}
 }
 }
 declare module spine {
 declare module spine {
@@ -872,6 +961,13 @@ declare module spine {
 	interface Map<T> {
 	interface Map<T> {
 		[key: string]: T;
 		[key: string]: T;
 	}
 	}
+	class IntSet {
+		array: number[];
+		add(value: number): boolean;
+		contains(value: number): boolean;
+		remove(value: number): void;
+		clear(): void;
+	}
 	interface Disposable {
 	interface Disposable {
 		dispose(): void;
 		dispose(): void;
 	}
 	}
@@ -910,6 +1006,7 @@ declare module spine {
 		static SUPPORTS_TYPED_ARRAYS: boolean;
 		static SUPPORTS_TYPED_ARRAYS: boolean;
 		static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
 		static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
 		static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
 		static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
+		static ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
 		static newArray<T>(size: number, defaultValue: T): Array<T>;
 		static newArray<T>(size: number, defaultValue: T): Array<T>;
 		static newFloatArray(size: number): ArrayLike<number>;
 		static newFloatArray(size: number): ArrayLike<number>;
 		static toFloatArray(array: Array<number>): number[] | Float32Array;
 		static toFloatArray(array: Array<number>): number[] | Float32Array;

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 545 - 195
spine-ts/build/spine-threejs.js


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 0
spine-ts/build/spine-threejs.js.map


+ 144 - 47
spine-ts/build/spine-webgl.d.ts

@@ -4,13 +4,29 @@ declare module spine {
 		timelines: Array<Timeline>;
 		timelines: Array<Timeline>;
 		duration: number;
 		duration: number;
 		constructor(name: string, timelines: Array<Timeline>, duration: number);
 		constructor(name: string, timelines: Array<Timeline>, duration: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>): void;
-		mix(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 		static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
 		static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
 		static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
 		static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
 	}
 	}
 	interface Timeline {
 	interface Timeline {
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+		getPropertyId(): number;
+	}
+	enum TimelineType {
+		rotate = 0,
+		translate = 1,
+		scale = 2,
+		shear = 3,
+		attachment = 4,
+		color = 5,
+		deform = 6,
+		event = 7,
+		drawOrder = 8,
+		ikConstraint = 9,
+		transformConstraint = 10,
+		pathConstraintPosition = 11,
+		pathConstraintSpacing = 12,
+		pathConstraintMix = 13,
 	}
 	}
 	abstract class CurveTimeline implements Timeline {
 	abstract class CurveTimeline implements Timeline {
 		static LINEAR: number;
 		static LINEAR: number;
@@ -18,6 +34,7 @@ declare module spine {
 		static BEZIER: number;
 		static BEZIER: number;
 		static BEZIER_SIZE: number;
 		static BEZIER_SIZE: number;
 		private curves;
 		private curves;
+		abstract getPropertyId(): number;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
 		getFrameCount(): number;
 		getFrameCount(): number;
 		setLinear(frameIndex: number): void;
 		setLinear(frameIndex: number): void;
@@ -25,7 +42,7 @@ declare module spine {
 		getCurveType(frameIndex: number): number;
 		getCurveType(frameIndex: number): number;
 		setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
 		setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
 		getCurvePercent(frameIndex: number, percent: number): number;
 		getCurvePercent(frameIndex: number, percent: number): number;
-		abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class RotateTimeline extends CurveTimeline {
 	class RotateTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -35,8 +52,9 @@ declare module spine {
 		boneIndex: number;
 		boneIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, degrees: number): void;
 		setFrame(frameIndex: number, time: number, degrees: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class TranslateTimeline extends CurveTimeline {
 	class TranslateTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -48,16 +66,19 @@ declare module spine {
 		boneIndex: number;
 		boneIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, x: number, y: number): void;
 		setFrame(frameIndex: number, time: number, x: number, y: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ScaleTimeline extends TranslateTimeline {
 	class ScaleTimeline extends TranslateTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ShearTimeline extends TranslateTimeline {
 	class ShearTimeline extends TranslateTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ColorTimeline extends CurveTimeline {
 	class ColorTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -73,42 +94,47 @@ declare module spine {
 		slotIndex: number;
 		slotIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class AttachmentTimeline implements Timeline {
 	class AttachmentTimeline implements Timeline {
 		slotIndex: number;
 		slotIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		attachmentNames: Array<string>;
 		attachmentNames: Array<string>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class EventTimeline implements Timeline {
 	class EventTimeline implements Timeline {
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		events: Array<Event>;
 		events: Array<Event>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		getFrameCount(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class DrawOrderTimeline implements Timeline {
 	class DrawOrderTimeline implements Timeline {
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		drawOrders: Array<Array<number>>;
 		drawOrders: Array<Array<number>>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		getFrameCount(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class DeformTimeline extends CurveTimeline {
 	class DeformTimeline extends CurveTimeline {
-		frames: ArrayLike<number>;
-		frameVertices: Array<ArrayLike<number>>;
 		slotIndex: number;
 		slotIndex: number;
 		attachment: VertexAttachment;
 		attachment: VertexAttachment;
+		frames: ArrayLike<number>;
+		frameVertices: Array<ArrayLike<number>>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
 		setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class IkConstraintTimeline extends CurveTimeline {
 	class IkConstraintTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -120,8 +146,9 @@ declare module spine {
 		ikConstraintIndex: number;
 		ikConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void;
 		setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class TransformConstraintTimeline extends CurveTimeline {
 	class TransformConstraintTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -137,8 +164,9 @@ declare module spine {
 		transformConstraintIndex: number;
 		transformConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintPositionTimeline extends CurveTimeline {
 	class PathConstraintPositionTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -148,12 +176,14 @@ declare module spine {
 		pathConstraintIndex: number;
 		pathConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
 	class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintMixTimeline extends CurveTimeline {
 	class PathConstraintMixTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -165,62 +195,121 @@ declare module spine {
 		pathConstraintIndex: number;
 		pathConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
 		setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 }
 }
 declare module spine {
 declare module spine {
 	class AnimationState {
 	class AnimationState {
+		static emptyAnimation: Animation;
 		data: AnimationStateData;
 		data: AnimationStateData;
 		tracks: TrackEntry[];
 		tracks: TrackEntry[];
 		events: Event[];
 		events: Event[];
-		listeners: AnimationStateListener[];
+		listeners: AnimationStateListener2[];
+		queue: EventQueue;
+		propertyIDs: IntSet;
+		animationsChanged: boolean;
 		timeScale: number;
 		timeScale: number;
-		constructor(data?: AnimationStateData);
+		trackEntryPool: Pool<TrackEntry>;
+		constructor(data: AnimationStateData);
 		update(delta: number): void;
 		update(delta: number): void;
+		updateMixingFrom(entry: TrackEntry, delta: number, canEnd: boolean): void;
 		apply(skeleton: Skeleton): void;
 		apply(skeleton: Skeleton): void;
+		applyMixingFrom(entry: TrackEntry, skeleton: Skeleton, alpha: number): number;
+		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
+		queueEvents(entry: TrackEntry, animationTime: number): void;
 		clearTracks(): void;
 		clearTracks(): void;
 		clearTrack(trackIndex: number): void;
 		clearTrack(trackIndex: number): void;
-		freeAll(entry: TrackEntry): void;
+		setCurrent(index: number, current: TrackEntry): void;
+		setAnimationByName(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
+		setAnimation(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
+		addAnimationByName(trackIndex: number, animationName: string, loop: boolean, delay: number): TrackEntry;
+		addAnimation(trackIndex: number, animation: Animation, loop: boolean, delay: number): TrackEntry;
+		setEmptyAnimation(trackIndex: number, mixDuration: number): TrackEntry;
+		addEmptyAnimation(trackIndex: number, mixDuration: number, delay: number): TrackEntry;
+		setEmptyAnimations(mixDuration: number): void;
 		expandToIndex(index: number): TrackEntry;
 		expandToIndex(index: number): TrackEntry;
-		setCurrent(index: number, entry: TrackEntry): void;
-		setAnimation(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
-		setAnimationWith(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
-		addAnimation(trackIndex: number, animationName: string, loop: boolean, delay: number): TrackEntry;
-		addAnimationWith(trackIndex: number, animation: Animation, loop: boolean, delay: number): TrackEntry;
+		trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry): TrackEntry;
+		disposeNext(entry: TrackEntry): void;
+		_animationsChanged(): void;
+		setTimelinesFirst(entry: TrackEntry): void;
+		checkTimelinesFirst(entry: TrackEntry): void;
+		checkTimelinesUsage(entry: TrackEntry, usageArray: Array<boolean>): void;
 		getCurrent(trackIndex: number): TrackEntry;
 		getCurrent(trackIndex: number): TrackEntry;
-		addListener(listener: AnimationStateListener): void;
-		removeListener(listener: AnimationStateListener): void;
+		addListener(listener: AnimationStateListener2): void;
+		removeListener(listener: AnimationStateListener2): void;
 		clearListeners(): void;
 		clearListeners(): void;
+		clearListenerNotifications(): void;
 	}
 	}
 	class TrackEntry {
 	class TrackEntry {
-		next: TrackEntry;
-		previous: TrackEntry;
 		animation: Animation;
 		animation: Animation;
+		next: TrackEntry;
+		mixingFrom: TrackEntry;
+		listener: AnimationStateListener2;
+		trackIndex: number;
 		loop: boolean;
 		loop: boolean;
+		eventThreshold: number;
+		attachmentThreshold: number;
+		drawOrderThreshold: number;
+		animationStart: number;
+		animationEnd: number;
+		animationLast: number;
+		nextAnimationLast: number;
 		delay: number;
 		delay: number;
-		time: number;
-		lastTime: number;
-		endTime: number;
+		trackTime: number;
+		trackLast: number;
+		nextTrackLast: number;
+		trackEnd: number;
 		timeScale: number;
 		timeScale: number;
+		alpha: number;
 		mixTime: number;
 		mixTime: number;
 		mixDuration: number;
 		mixDuration: number;
-		listener: AnimationStateListener;
-		mix: number;
+		mixAlpha: number;
+		timelinesFirst: boolean[];
+		timelinesRotation: number[];
 		reset(): void;
 		reset(): void;
+		getAnimationTime(): number;
+		setAnimationLast(animationLast: number): void;
 		isComplete(): boolean;
 		isComplete(): boolean;
 	}
 	}
-	abstract class AnimationStateAdapter implements AnimationStateListener {
-		event(trackIndex: number, event: Event): void;
-		complete(trackIndex: number, loopCount: number): void;
-		start(trackIndex: number): void;
-		end(trackIndex: number): void;
+	class EventQueue {
+		objects: Array<any>;
+		drainDisabled: boolean;
+		animState: AnimationState;
+		constructor(animState: AnimationState);
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
+		drain(): void;
+		clear(): void;
 	}
 	}
-	interface AnimationStateListener {
-		event(trackIndex: number, event: Event): void;
-		complete(trackIndex: number, loopCount: number): void;
-		start(trackIndex: number): void;
-		end(trackIndex: number): void;
+	enum EventType {
+		start = 0,
+		interrupt = 1,
+		end = 2,
+		dispose = 3,
+		complete = 4,
+		event = 5,
+	}
+	interface AnimationStateListener2 {
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
+	}
+	abstract class AnimationStateAdapter2 implements AnimationStateListener2 {
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
 	}
 	}
 }
 }
 declare module spine {
 declare module spine {
@@ -872,6 +961,13 @@ declare module spine {
 	interface Map<T> {
 	interface Map<T> {
 		[key: string]: T;
 		[key: string]: T;
 	}
 	}
+	class IntSet {
+		array: number[];
+		add(value: number): boolean;
+		contains(value: number): boolean;
+		remove(value: number): void;
+		clear(): void;
+	}
 	interface Disposable {
 	interface Disposable {
 		dispose(): void;
 		dispose(): void;
 	}
 	}
@@ -910,6 +1006,7 @@ declare module spine {
 		static SUPPORTS_TYPED_ARRAYS: boolean;
 		static SUPPORTS_TYPED_ARRAYS: boolean;
 		static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
 		static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
 		static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
 		static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
+		static ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
 		static newArray<T>(size: number, defaultValue: T): Array<T>;
 		static newArray<T>(size: number, defaultValue: T): Array<T>;
 		static newFloatArray(size: number): ArrayLike<number>;
 		static newFloatArray(size: number): ArrayLike<number>;
 		static toFloatArray(array: Array<number>): number[] | Float32Array;
 		static toFloatArray(array: Array<number>): number[] | Float32Array;

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 545 - 195
spine-ts/build/spine-webgl.js


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 0
spine-ts/build/spine-webgl.js.map


+ 144 - 47
spine-ts/build/spine-widget.d.ts

@@ -4,13 +4,29 @@ declare module spine {
 		timelines: Array<Timeline>;
 		timelines: Array<Timeline>;
 		duration: number;
 		duration: number;
 		constructor(name: string, timelines: Array<Timeline>, duration: number);
 		constructor(name: string, timelines: Array<Timeline>, duration: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>): void;
-		mix(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 		static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
 		static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
 		static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
 		static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
 	}
 	}
 	interface Timeline {
 	interface Timeline {
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+		getPropertyId(): number;
+	}
+	enum TimelineType {
+		rotate = 0,
+		translate = 1,
+		scale = 2,
+		shear = 3,
+		attachment = 4,
+		color = 5,
+		deform = 6,
+		event = 7,
+		drawOrder = 8,
+		ikConstraint = 9,
+		transformConstraint = 10,
+		pathConstraintPosition = 11,
+		pathConstraintSpacing = 12,
+		pathConstraintMix = 13,
 	}
 	}
 	abstract class CurveTimeline implements Timeline {
 	abstract class CurveTimeline implements Timeline {
 		static LINEAR: number;
 		static LINEAR: number;
@@ -18,6 +34,7 @@ declare module spine {
 		static BEZIER: number;
 		static BEZIER: number;
 		static BEZIER_SIZE: number;
 		static BEZIER_SIZE: number;
 		private curves;
 		private curves;
+		abstract getPropertyId(): number;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
 		getFrameCount(): number;
 		getFrameCount(): number;
 		setLinear(frameIndex: number): void;
 		setLinear(frameIndex: number): void;
@@ -25,7 +42,7 @@ declare module spine {
 		getCurveType(frameIndex: number): number;
 		getCurveType(frameIndex: number): number;
 		setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
 		setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
 		getCurvePercent(frameIndex: number, percent: number): number;
 		getCurvePercent(frameIndex: number, percent: number): number;
-		abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class RotateTimeline extends CurveTimeline {
 	class RotateTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -35,8 +52,9 @@ declare module spine {
 		boneIndex: number;
 		boneIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, degrees: number): void;
 		setFrame(frameIndex: number, time: number, degrees: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class TranslateTimeline extends CurveTimeline {
 	class TranslateTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -48,16 +66,19 @@ declare module spine {
 		boneIndex: number;
 		boneIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, x: number, y: number): void;
 		setFrame(frameIndex: number, time: number, x: number, y: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ScaleTimeline extends TranslateTimeline {
 	class ScaleTimeline extends TranslateTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ShearTimeline extends TranslateTimeline {
 	class ShearTimeline extends TranslateTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class ColorTimeline extends CurveTimeline {
 	class ColorTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -73,42 +94,47 @@ declare module spine {
 		slotIndex: number;
 		slotIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class AttachmentTimeline implements Timeline {
 	class AttachmentTimeline implements Timeline {
 		slotIndex: number;
 		slotIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		attachmentNames: Array<string>;
 		attachmentNames: Array<string>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class EventTimeline implements Timeline {
 	class EventTimeline implements Timeline {
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		events: Array<Event>;
 		events: Array<Event>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		getFrameCount(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class DrawOrderTimeline implements Timeline {
 	class DrawOrderTimeline implements Timeline {
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		drawOrders: Array<Array<number>>;
 		drawOrders: Array<Array<number>>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		getFrameCount(): 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class DeformTimeline extends CurveTimeline {
 	class DeformTimeline extends CurveTimeline {
-		frames: ArrayLike<number>;
-		frameVertices: Array<ArrayLike<number>>;
 		slotIndex: number;
 		slotIndex: number;
 		attachment: VertexAttachment;
 		attachment: VertexAttachment;
+		frames: ArrayLike<number>;
+		frameVertices: Array<ArrayLike<number>>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
 		setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class IkConstraintTimeline extends CurveTimeline {
 	class IkConstraintTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -120,8 +146,9 @@ declare module spine {
 		ikConstraintIndex: number;
 		ikConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void;
 		setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class TransformConstraintTimeline extends CurveTimeline {
 	class TransformConstraintTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -137,8 +164,9 @@ declare module spine {
 		transformConstraintIndex: number;
 		transformConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintPositionTimeline extends CurveTimeline {
 	class PathConstraintPositionTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -148,12 +176,14 @@ declare module spine {
 		pathConstraintIndex: number;
 		pathConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: 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): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
 	class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
 		constructor(frameCount: number);
 		constructor(frameCount: number);
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 	class PathConstraintMixTimeline extends CurveTimeline {
 	class PathConstraintMixTimeline extends CurveTimeline {
 		static ENTRIES: number;
 		static ENTRIES: number;
@@ -165,62 +195,121 @@ declare module spine {
 		pathConstraintIndex: number;
 		pathConstraintIndex: number;
 		frames: ArrayLike<number>;
 		frames: ArrayLike<number>;
 		constructor(frameCount: number);
 		constructor(frameCount: number);
+		getPropertyId(): number;
 		setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
 		setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
-		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 }
 }
 declare module spine {
 declare module spine {
 	class AnimationState {
 	class AnimationState {
+		static emptyAnimation: Animation;
 		data: AnimationStateData;
 		data: AnimationStateData;
 		tracks: TrackEntry[];
 		tracks: TrackEntry[];
 		events: Event[];
 		events: Event[];
-		listeners: AnimationStateListener[];
+		listeners: AnimationStateListener2[];
+		queue: EventQueue;
+		propertyIDs: IntSet;
+		animationsChanged: boolean;
 		timeScale: number;
 		timeScale: number;
-		constructor(data?: AnimationStateData);
+		trackEntryPool: Pool<TrackEntry>;
+		constructor(data: AnimationStateData);
 		update(delta: number): void;
 		update(delta: number): void;
+		updateMixingFrom(entry: TrackEntry, delta: number, canEnd: boolean): void;
 		apply(skeleton: Skeleton): void;
 		apply(skeleton: Skeleton): void;
+		applyMixingFrom(entry: TrackEntry, skeleton: Skeleton, alpha: number): number;
+		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
+		queueEvents(entry: TrackEntry, animationTime: number): void;
 		clearTracks(): void;
 		clearTracks(): void;
 		clearTrack(trackIndex: number): void;
 		clearTrack(trackIndex: number): void;
-		freeAll(entry: TrackEntry): void;
+		setCurrent(index: number, current: TrackEntry): void;
+		setAnimationByName(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
+		setAnimation(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
+		addAnimationByName(trackIndex: number, animationName: string, loop: boolean, delay: number): TrackEntry;
+		addAnimation(trackIndex: number, animation: Animation, loop: boolean, delay: number): TrackEntry;
+		setEmptyAnimation(trackIndex: number, mixDuration: number): TrackEntry;
+		addEmptyAnimation(trackIndex: number, mixDuration: number, delay: number): TrackEntry;
+		setEmptyAnimations(mixDuration: number): void;
 		expandToIndex(index: number): TrackEntry;
 		expandToIndex(index: number): TrackEntry;
-		setCurrent(index: number, entry: TrackEntry): void;
-		setAnimation(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
-		setAnimationWith(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
-		addAnimation(trackIndex: number, animationName: string, loop: boolean, delay: number): TrackEntry;
-		addAnimationWith(trackIndex: number, animation: Animation, loop: boolean, delay: number): TrackEntry;
+		trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry): TrackEntry;
+		disposeNext(entry: TrackEntry): void;
+		_animationsChanged(): void;
+		setTimelinesFirst(entry: TrackEntry): void;
+		checkTimelinesFirst(entry: TrackEntry): void;
+		checkTimelinesUsage(entry: TrackEntry, usageArray: Array<boolean>): void;
 		getCurrent(trackIndex: number): TrackEntry;
 		getCurrent(trackIndex: number): TrackEntry;
-		addListener(listener: AnimationStateListener): void;
-		removeListener(listener: AnimationStateListener): void;
+		addListener(listener: AnimationStateListener2): void;
+		removeListener(listener: AnimationStateListener2): void;
 		clearListeners(): void;
 		clearListeners(): void;
+		clearListenerNotifications(): void;
 	}
 	}
 	class TrackEntry {
 	class TrackEntry {
-		next: TrackEntry;
-		previous: TrackEntry;
 		animation: Animation;
 		animation: Animation;
+		next: TrackEntry;
+		mixingFrom: TrackEntry;
+		listener: AnimationStateListener2;
+		trackIndex: number;
 		loop: boolean;
 		loop: boolean;
+		eventThreshold: number;
+		attachmentThreshold: number;
+		drawOrderThreshold: number;
+		animationStart: number;
+		animationEnd: number;
+		animationLast: number;
+		nextAnimationLast: number;
 		delay: number;
 		delay: number;
-		time: number;
-		lastTime: number;
-		endTime: number;
+		trackTime: number;
+		trackLast: number;
+		nextTrackLast: number;
+		trackEnd: number;
 		timeScale: number;
 		timeScale: number;
+		alpha: number;
 		mixTime: number;
 		mixTime: number;
 		mixDuration: number;
 		mixDuration: number;
-		listener: AnimationStateListener;
-		mix: number;
+		mixAlpha: number;
+		timelinesFirst: boolean[];
+		timelinesRotation: number[];
 		reset(): void;
 		reset(): void;
+		getAnimationTime(): number;
+		setAnimationLast(animationLast: number): void;
 		isComplete(): boolean;
 		isComplete(): boolean;
 	}
 	}
-	abstract class AnimationStateAdapter implements AnimationStateListener {
-		event(trackIndex: number, event: Event): void;
-		complete(trackIndex: number, loopCount: number): void;
-		start(trackIndex: number): void;
-		end(trackIndex: number): void;
+	class EventQueue {
+		objects: Array<any>;
+		drainDisabled: boolean;
+		animState: AnimationState;
+		constructor(animState: AnimationState);
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
+		drain(): void;
+		clear(): void;
 	}
 	}
-	interface AnimationStateListener {
-		event(trackIndex: number, event: Event): void;
-		complete(trackIndex: number, loopCount: number): void;
-		start(trackIndex: number): void;
-		end(trackIndex: number): void;
+	enum EventType {
+		start = 0,
+		interrupt = 1,
+		end = 2,
+		dispose = 3,
+		complete = 4,
+		event = 5,
+	}
+	interface AnimationStateListener2 {
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
+	}
+	abstract class AnimationStateAdapter2 implements AnimationStateListener2 {
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
 	}
 	}
 }
 }
 declare module spine {
 declare module spine {
@@ -872,6 +961,13 @@ declare module spine {
 	interface Map<T> {
 	interface Map<T> {
 		[key: string]: T;
 		[key: string]: T;
 	}
 	}
+	class IntSet {
+		array: number[];
+		add(value: number): boolean;
+		contains(value: number): boolean;
+		remove(value: number): void;
+		clear(): void;
+	}
 	interface Disposable {
 	interface Disposable {
 		dispose(): void;
 		dispose(): void;
 	}
 	}
@@ -910,6 +1006,7 @@ declare module spine {
 		static SUPPORTS_TYPED_ARRAYS: boolean;
 		static SUPPORTS_TYPED_ARRAYS: boolean;
 		static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
 		static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
 		static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
 		static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
+		static ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
 		static newArray<T>(size: number, defaultValue: T): Array<T>;
 		static newArray<T>(size: number, defaultValue: T): Array<T>;
 		static newFloatArray(size: number): ArrayLike<number>;
 		static newFloatArray(size: number): ArrayLike<number>;
 		static toFloatArray(array: Array<number>): number[] | Float32Array;
 		static toFloatArray(array: Array<number>): number[] | Float32Array;

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 545 - 195
spine-ts/build/spine-widget.js


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 0
spine-ts/build/spine-widget.js.map


+ 343 - 168
spine-ts/core/src/Animation.ts

@@ -42,7 +42,7 @@ module spine {
 			this.duration = duration;
 			this.duration = duration;
 		}
 		}
 
 
-		apply (skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>) {
+		apply (skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean) {
 			if (skeleton == null) throw new Error("skeleton cannot be null.");
 			if (skeleton == null) throw new Error("skeleton cannot be null.");
 
 
 			if (loop && this.duration != 0) {
 			if (loop && this.duration != 0) {
@@ -52,20 +52,7 @@ module spine {
 
 
 			let timelines = this.timelines;
 			let timelines = this.timelines;
 			for (let i = 0, n = timelines.length; i < n; i++)
 			for (let i = 0, n = timelines.length; i < n; i++)
-				timelines[i].apply(skeleton, lastTime, time, events, 1);
-		}
-
-		mix (skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number) {
-			if (skeleton == null) throw new Error("skeleton cannot be null.");
-
-			if (loop && this.duration != 0) {
-				time %= this.duration;
-				if (lastTime > 0) lastTime %= this.duration;
-			}
-
-			let timelines = this.timelines;
-			for (let i = 0, n = timelines.length; i < n; i++)
-				timelines[i].apply(skeleton, lastTime, time, events, alpha);
+				timelines[i].apply(skeleton, lastTime, time, events, alpha, setupPose, mixingOut);
 		}
 		}
 
 
 		static binarySearch (values: ArrayLike<number>, target: number, step: number = 1) {
 		static binarySearch (values: ArrayLike<number>, target: number, step: number = 1) {
@@ -91,7 +78,16 @@ module spine {
 	}
 	}
 
 
 	export interface Timeline {
 	export interface Timeline {
-		apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+		getPropertyId (): number;
+	}
+
+	export enum TimelineType {
+		rotate, translate, scale, shear,
+		attachment, color, deform,
+		event, drawOrder,
+		ikConstraint, transformConstraint,
+		pathConstraintPosition, pathConstraintSpacing, pathConstraintMix
 	}
 	}
 
 
 	export abstract class CurveTimeline implements Timeline {
 	export abstract class CurveTimeline implements Timeline {
@@ -100,6 +96,8 @@ module spine {
 
 
 		private curves: ArrayLike<number>; // type, x, y, ...
 		private curves: ArrayLike<number>; // type, x, y, ...
 
 
+		abstract getPropertyId(): number;
+
 		constructor (frameCount: number) {
 		constructor (frameCount: number) {
 			if (frameCount <= 0) throw new Error("frameCount must be > 0: " + frameCount);
 			if (frameCount <= 0) throw new Error("frameCount must be > 0: " + frameCount);
 			this.curves = Utils.newFloatArray((frameCount - 1) * CurveTimeline.BEZIER_SIZE);
 			this.curves = Utils.newFloatArray((frameCount - 1) * CurveTimeline.BEZIER_SIZE);
@@ -179,7 +177,7 @@ module spine {
 			return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1.
 			return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1.
 		}
 		}
 
 
-		abstract apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
+		abstract apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
 	}
 	}
 
 
 	export class RotateTimeline extends CurveTimeline {
 	export class RotateTimeline extends CurveTimeline {
@@ -195,6 +193,10 @@ module spine {
 			this.frames = Utils.newFloatArray(frameCount << 1);
 			this.frames = Utils.newFloatArray(frameCount << 1);
 		}
 		}
 
 
+		getPropertyId () {
+			return (TimelineType.rotate << 24) + this.boneIndex;
+		}
+
 		/** Sets the time and angle of the specified keyframe. */
 		/** Sets the time and angle of the specified keyframe. */
 		setFrame (frameIndex: number, time: number, degrees: number) {
 		setFrame (frameIndex: number, time: number, degrees: number) {
 			frameIndex <<= 1;
 			frameIndex <<= 1;
@@ -202,19 +204,20 @@ module spine {
 			this.frames[frameIndex + RotateTimeline.ROTATION] = degrees;
 			this.frames[frameIndex + RotateTimeline.ROTATION] = degrees;
 		}
 		}
 
 
-		apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number) {
+		apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean) {
 			let frames = this.frames;
 			let frames = this.frames;
 			if (time < frames[0]) return; // Time is before first frame.
 			if (time < frames[0]) return; // Time is before first frame.
 
 
 			let bone = skeleton.bones[this.boneIndex];
 			let bone = skeleton.bones[this.boneIndex];
 
 
 			if (time >= frames[frames.length - RotateTimeline.ENTRIES]) { // Time is after last frame.
 			if (time >= frames[frames.length - RotateTimeline.ENTRIES]) { // Time is after last frame.
-				let amount = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION] - bone.rotation;
-				while (amount > 180)
-					amount -= 360;
-				while (amount < -180)
-					amount += 360;
-				bone.rotation += amount * alpha;
+				if (setupPose)
+					bone.rotation = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION] * alpha;
+				else {
+					let r = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION] - bone.rotation;
+					r -= (16384 - Math.floor(16384.499999999996 - r / 360)) * 360; // Wrap within -180 and 180.
+					bone.rotation += r * alpha;
+				}
 				return;
 				return;
 			}
 			}
 
 
@@ -225,17 +228,17 @@ module spine {
 			let percent = this.getCurvePercent((frame >> 1) - 1,
 			let percent = this.getCurvePercent((frame >> 1) - 1,
 				1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime));
 				1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime));
 
 
-			let amount = frames[frame + RotateTimeline.ROTATION] - prevRotation;
-			while (amount > 180)
-				amount -= 360;
-			while (amount < -180)
-				amount += 360;
-			amount = bone.data.rotation + (prevRotation + amount * percent) - bone.rotation;
-			while (amount > 180)
-				amount -= 360;
-			while (amount < -180)
-				amount += 360;
-			bone.rotation += amount * alpha;
+			let r = frames[frame + RotateTimeline.ROTATION] - prevRotation;
+			r -= (16384 - Math.floor(16384.499999999996 - r / 360)) * 360;
+			r = prevRotation + r * percent;
+			if (setupPose) {
+				r -= (16384 - Math.floor(16384.499999999996 - r / 360)) * 360;
+				bone.rotation = bone.data.rotation + r * alpha;
+			} else {
+				r = bone.data.rotation + r - bone.rotation;
+				r -= (16384 - Math.floor(16384.499999999996 - r / 360)) * 360;
+				bone.rotation += r * alpha;
+			}
 		}
 		}
 	}
 	}
 
 
@@ -252,6 +255,10 @@ module spine {
 			this.frames = Utils.newFloatArray(frameCount * TranslateTimeline.ENTRIES);
 			this.frames = Utils.newFloatArray(frameCount * TranslateTimeline.ENTRIES);
 		}
 		}
 
 
+		getPropertyId () {
+			return (TimelineType.translate << 24) + this.boneIndex;
+		}
+
 		/** Sets the time and value of the specified keyframe. */
 		/** Sets the time and value of the specified keyframe. */
 		setFrame (frameIndex: number, time: number, x: number, y: number) {
 		setFrame (frameIndex: number, time: number, x: number, y: number) {
 			frameIndex *= TranslateTimeline.ENTRIES;
 			frameIndex *= TranslateTimeline.ENTRIES;
@@ -260,28 +267,35 @@ module spine {
 			this.frames[frameIndex + TranslateTimeline.Y] = y;
 			this.frames[frameIndex + TranslateTimeline.Y] = y;
 		}
 		}
 
 
-		apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number) {
+		apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean) {
 			let frames = this.frames;
 			let frames = this.frames;
 			if (time < frames[0]) return; // Time is before first frame.
 			if (time < frames[0]) return; // Time is before first frame.
 
 
 			let bone = skeleton.bones[this.boneIndex];
 			let bone = skeleton.bones[this.boneIndex];
 
 
+			let x = 0, y = 0;
 			if (time >= frames[frames.length - TranslateTimeline.ENTRIES]) { // Time is after last frame.
 			if (time >= frames[frames.length - TranslateTimeline.ENTRIES]) { // Time is after last frame.
-				bone.x += (bone.data.x + frames[frames.length + TranslateTimeline.PREV_X] - bone.x) * alpha;
-				bone.y += (bone.data.y + frames[frames.length + TranslateTimeline.PREV_Y] - bone.y) * alpha;
-				return;
-			}
-
-			// Interpolate between the previous frame and the current frame.
-			let frame = Animation.binarySearch(frames, time, TranslateTimeline.ENTRIES);
-			let prevX = frames[frame + TranslateTimeline.PREV_X];
-			let prevY = frames[frame + TranslateTimeline.PREV_Y];
-			let frameTime = frames[frame];
-			let percent = this.getCurvePercent(frame / TranslateTimeline.ENTRIES - 1,
-				1 - (time - frameTime) / (frames[frame + TranslateTimeline.PREV_TIME] - frameTime));
+				x = frames[frames.length + TranslateTimeline.PREV_X];
+				y = frames[frames.length + TranslateTimeline.PREV_Y];
+			} else {
+				// Interpolate between the previous frame and the current frame.
+				let frame = Animation.binarySearch(frames, time, TranslateTimeline.ENTRIES);
+				x = frames[frame + TranslateTimeline.PREV_X];
+				y = frames[frame + TranslateTimeline.PREV_Y];
+				let frameTime = frames[frame];
+				let percent = this.getCurvePercent(frame / TranslateTimeline.ENTRIES - 1,
+					1 - (time - frameTime) / (frames[frame + TranslateTimeline.PREV_TIME] - frameTime));
 
 
-			bone.x += (bone.data.x + prevX + (frames[frame + TranslateTimeline.X] - prevX) * percent - bone.x) * alpha;
-			bone.y += (bone.data.y + prevY + (frames[frame + TranslateTimeline.Y] - prevY) * percent - bone.y) * alpha;
+				x += (frames[frame + TranslateTimeline.X] - x) * percent;
+				y += (frames[frame + TranslateTimeline.Y] - y) * percent;
+			}
+			if (setupPose) {
+				bone.x = bone.data.x + x * alpha;
+				bone.y = bone.data.y + y * alpha;
+			} else {
+				bone.x += (bone.data.x + x - bone.x) * alpha;
+				bone.y += (bone.data.y + y - bone.y) * alpha;
+			}
 		}
 		}
 	}
 	}
 
 
@@ -290,27 +304,54 @@ module spine {
 			super(frameCount);
 			super(frameCount);
 		}
 		}
 
 
-		apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number) {
+		getPropertyId () {
+			return (TimelineType.scale << 24) + this.boneIndex;
+		}
+
+		apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean) {
 			let frames = this.frames;
 			let frames = this.frames;
 			if (time < frames[0]) return; // Time is before first frame.
 			if (time < frames[0]) return; // Time is before first frame.
 
 
 			let bone = skeleton.bones[this.boneIndex];
 			let bone = skeleton.bones[this.boneIndex];
+			let x = 0, y = 0;
 			if (time >= frames[frames.length - ScaleTimeline.ENTRIES]) { // Time is after last frame.
 			if (time >= frames[frames.length - ScaleTimeline.ENTRIES]) { // Time is after last frame.
-				bone.scaleX += (bone.data.scaleX * frames[frames.length + ScaleTimeline.PREV_X] - bone.scaleX) * alpha;
-				bone.scaleY += (bone.data.scaleY * frames[frames.length + ScaleTimeline.PREV_Y] - bone.scaleY) * alpha;
-				return;
-			}
-
-			// Interpolate between the previous frame and the current frame.
-			let frame = Animation.binarySearch(frames, time, ScaleTimeline.ENTRIES);
-			let prevX = frames[frame + ScaleTimeline.PREV_X];
-			let prevY = frames[frame + ScaleTimeline.PREV_Y];
-			let frameTime = frames[frame];
-			let percent = this.getCurvePercent(frame / ScaleTimeline.ENTRIES - 1,
-				1 - (time - frameTime) / (frames[frame + ScaleTimeline.PREV_TIME] - frameTime));
+				x = frames[frames.length + ScaleTimeline.PREV_X] * bone.data.scaleX;
+				y = frames[frames.length + ScaleTimeline.PREV_Y] * bone.data.scaleY;
+			} else {
+				// Interpolate between the previous frame and the current frame.
+				let frame = Animation.binarySearch(frames, time, ScaleTimeline.ENTRIES);
+				x = frames[frame + ScaleTimeline.PREV_X];
+				y = frames[frame + ScaleTimeline.PREV_Y];
+				let frameTime = frames[frame];
+				let percent = this.getCurvePercent(frame / ScaleTimeline.ENTRIES - 1,
+					1 - (time - frameTime) / (frames[frame + ScaleTimeline.PREV_TIME] - frameTime));
 
 
-			bone.scaleX += (bone.data.scaleX * (prevX + (frames[frame + ScaleTimeline.X] - prevX) * percent) - bone.scaleX) * alpha;
-			bone.scaleY += (bone.data.scaleY * (prevY + (frames[frame + ScaleTimeline.Y] - prevY) * percent) - bone.scaleY) * alpha;
+				x = (x + (frames[frame + ScaleTimeline.X] - x) * percent) * bone.data.scaleX;
+				y = (y + (frames[frame + ScaleTimeline.Y] - y) * percent) * bone.data.scaleY;
+			}
+			if (alpha == 1) {
+				bone.scaleX = x;
+				bone.scaleY = y;
+			} else {
+				let bx = 0, by = 0;
+				if (setupPose) {
+					bx = bone.data.scaleX;
+					by = bone.data.scaleY;
+				} else {
+					bx = bone.scaleX;
+					by = bone.scaleY;
+				}
+				// Mixing out uses sign of setup or current pose, else use sign of key.
+				if (mixingOut) {
+					x = Math.abs(x) * MathUtils.signum(bx);
+					y = Math.abs(y) * MathUtils.signum(by);
+				} else {
+					bx = Math.abs(bx) * MathUtils.signum(x);
+					by = Math.abs(by) * MathUtils.signum(y);
+				}
+				bone.scaleX = bx + (x - bx) * alpha;
+				bone.scaleY = by + (y - by) * alpha;
+			}
 		}
 		}
 	}
 	}
 
 
@@ -319,27 +360,39 @@ module spine {
 			super(frameCount);
 			super(frameCount);
 		}
 		}
 
 
-		apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number) {
+		getPropertyId () {
+			return (TimelineType.shear << 24) + this.boneIndex;
+		}
+
+		apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean) {
 			let frames = this.frames;
 			let frames = this.frames;
 			if (time < frames[0]) return; // Time is before first frame.
 			if (time < frames[0]) return; // Time is before first frame.
 
 
 			let bone = skeleton.bones[this.boneIndex];
 			let bone = skeleton.bones[this.boneIndex];
-			if (time >= frames[frames.length - ShearTimeline.ENTRIES]) { // Time is after last frame.
-				bone.shearX += (bone.data.shearX + frames[frames.length + ShearTimeline.PREV_X] - bone.shearX) * alpha;
-				bone.shearY += (bone.data.shearY + frames[frames.length + ShearTimeline.PREV_Y] - bone.shearY) * alpha;
-				return;
-			}
 
 
-			// Interpolate between the previous frame and the current frame.
-			let frame = Animation.binarySearch(frames, time, ShearTimeline.ENTRIES);
-			let prevX = frames[frame + ShearTimeline.PREV_X];
-			let prevY = frames[frame + ShearTimeline.PREV_Y];
-			let frameTime = frames[frame];
-			let percent = this.getCurvePercent(frame / ShearTimeline.ENTRIES - 1,
-				1 - (time - frameTime) / (frames[frame + ShearTimeline.PREV_TIME] - frameTime));
+			let x = 0, y = 0;
+			if (time >= frames[frames.length - ShearTimeline.ENTRIES]) { // Time is after last frame.
+				x = frames[frames.length + ShearTimeline.PREV_X];
+				y = frames[frames.length + ShearTimeline.PREV_Y];
+			} else {
+				// Interpolate between the previous frame and the current frame.
+				let frame = Animation.binarySearch(frames, time, ShearTimeline.ENTRIES);
+				x = frames[frame + ShearTimeline.PREV_X];
+				y = frames[frame + ShearTimeline.PREV_Y];
+				let frameTime = frames[frame];
+				let percent = this.getCurvePercent(frame / ShearTimeline.ENTRIES - 1,
+					1 - (time - frameTime) / (frames[frame + ShearTimeline.PREV_TIME] - frameTime));
 
 
-			bone.shearX += (bone.data.shearX + (prevX + (frames[frame + ShearTimeline.X] - prevX) * percent) - bone.shearX) * alpha;
-			bone.shearY += (bone.data.shearY + (prevY + (frames[frame + ShearTimeline.Y] - prevY) * percent) - bone.shearY) * alpha;
+				x = x + (frames[frame + ShearTimeline.X] - x) * percent;
+				y = y + (frames[frame + ShearTimeline.Y] - y) * percent;
+			}
+			if (setupPose) {
+				bone.shearX = bone.data.shearX + x * alpha;
+				bone.shearY = bone.data.shearY + y * alpha;
+			} else {
+				bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha;
+				bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha;
+			}
 		}
 		}
 	}
 	}
 
 
@@ -356,6 +409,10 @@ module spine {
 			this.frames = Utils.newFloatArray(frameCount * ColorTimeline.ENTRIES);
 			this.frames = Utils.newFloatArray(frameCount * ColorTimeline.ENTRIES);
 		}
 		}
 
 
+		getPropertyId () {
+			return (TimelineType.color << 24) + this.slotIndex;
+		}
+
 		/** Sets the time and value of the specified keyframe. */
 		/** Sets the time and value of the specified keyframe. */
 		setFrame (frameIndex: number, time: number, r: number, g: number, b: number, a: number) {
 		setFrame (frameIndex: number, time: number, r: number, g: number, b: number, a: number) {
 			frameIndex *= ColorTimeline.ENTRIES;
 			frameIndex *= ColorTimeline.ENTRIES;
@@ -366,7 +423,7 @@ module spine {
 			this.frames[frameIndex + ColorTimeline.A] = a;
 			this.frames[frameIndex + ColorTimeline.A] = a;
 		}
 		}
 
 
-		apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number) {
+		apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean) {
 			let frames = this.frames;
 			let frames = this.frames;
 			if (time < frames[0]) return; // Time is before first frame.
 			if (time < frames[0]) return; // Time is before first frame.
 
 
@@ -393,11 +450,14 @@ module spine {
 				b += (frames[frame + ColorTimeline.B] - b) * percent;
 				b += (frames[frame + ColorTimeline.B] - b) * percent;
 				a += (frames[frame + ColorTimeline.A] - a) * percent;
 				a += (frames[frame + ColorTimeline.A] - a) * percent;
 			}
 			}
-			let color: Color = skeleton.slots[this.slotIndex].color;
-			if (alpha < 1)
+			let slot = skeleton.slots[this.slotIndex];
+			if (alpha == 1)
+				slot.color.set(r, g, b, a);
+			else {
+				let color = slot.color;
+				if (setupPose) color.setFromColor(slot.data.color);
 				color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha);
 				color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha);
-			else
-				color.set(r, g, b, a);
+			}
 		}
 		}
 	}
 	}
 
 
@@ -411,6 +471,10 @@ module spine {
 			this.attachmentNames = new Array<string>(frameCount);
 			this.attachmentNames = new Array<string>(frameCount);
 		}
 		}
 
 
+		getPropertyId () {
+			return (TimelineType.attachment << 24) + this.slotIndex;
+		}
+
 		getFrameCount () {
 		getFrameCount () {
 			return this.frames.length;
 			return this.frames.length;
 		}
 		}
@@ -421,7 +485,14 @@ module spine {
 			this.attachmentNames[frameIndex] = attachmentName;
 			this.attachmentNames[frameIndex] = attachmentName;
 		}
 		}
 
 
-		apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number) {
+		apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean) {
+			if (mixingOut && setupPose) {
+				let slot = skeleton.slots[this.slotIndex];
+				let attachmentName = slot.data.attachmentName;
+				slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName));
+				return;
+			}
+
 			let frames = this.frames;
 			let frames = this.frames;
 			if (time < frames[0]) return; // Time is before first frame.
 			if (time < frames[0]) return; // Time is before first frame.
 
 
@@ -446,6 +517,10 @@ module spine {
 			this.events = new Array<Event>(frameCount);
 			this.events = new Array<Event>(frameCount);
 		}
 		}
 
 
+		getPropertyId () {
+			return TimelineType.event << 24;
+		}
+
 		getFrameCount () {
 		getFrameCount () {
 			return this.frames.length;
 			return this.frames.length;
 		}
 		}
@@ -457,13 +532,13 @@ module spine {
 		}
 		}
 
 
 		/** Fires events for frames > lastTime and <= time. */
 		/** Fires events for frames > lastTime and <= time. */
-		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number) {
+		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean) {
 			if (firedEvents == null) return;
 			if (firedEvents == null) return;
 			let frames = this.frames;
 			let frames = this.frames;
 			let frameCount = this.frames.length;
 			let frameCount = this.frames.length;
 
 
 			if (lastTime > time) { // Fire events after last time for looped animations.
 			if (lastTime > time) { // Fire events after last time for looped animations.
-				this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha);
+				this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, setupPose, mixingOut);
 				lastTime = -1;
 				lastTime = -1;
 			} else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame.
 			} else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame.
 				return;
 				return;
@@ -494,6 +569,10 @@ module spine {
 			this.drawOrders = new Array<Array<number>>(frameCount);
 			this.drawOrders = new Array<Array<number>>(frameCount);
 		}
 		}
 
 
+		getPropertyId () {
+			return TimelineType.drawOrder << 24;
+		}
+
 		getFrameCount () {
 		getFrameCount () {
 			return this.frames.length;
 			return this.frames.length;
 		}
 		}
@@ -505,7 +584,12 @@ module spine {
 			this.drawOrders[frameIndex] = drawOrder;
 			this.drawOrders[frameIndex] = drawOrder;
 		}
 		}
 
 
-		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number) {
+		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean) {
+			if (mixingOut && setupPose) {
+				Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);
+				return;
+			}
+
 			let frames = this.frames;
 			let frames = this.frames;
 			if (time < frames[0]) return; // Time is before first frame.
 			if (time < frames[0]) return; // Time is before first frame.
 
 
@@ -528,10 +612,10 @@ module spine {
 	}
 	}
 
 
 	export class DeformTimeline extends CurveTimeline {
 	export class DeformTimeline extends CurveTimeline {
-		frames: ArrayLike<number>; // time, ...
-		frameVertices: Array<ArrayLike<number>>;
 		slotIndex: number;
 		slotIndex: number;
 		attachment: VertexAttachment;
 		attachment: VertexAttachment;
+		frames: ArrayLike<number>; // time, ...
+		frameVertices: Array<ArrayLike<number>>;
 
 
 		constructor (frameCount: number) {
 		constructor (frameCount: number) {
 			super(frameCount);
 			super(frameCount);
@@ -539,13 +623,17 @@ module spine {
 			this.frameVertices = new Array<ArrayLike<number>>(frameCount);
 			this.frameVertices = new Array<ArrayLike<number>>(frameCount);
 		}
 		}
 
 
+		getPropertyId () {
+			return (TimelineType.deform << 24) + this.slotIndex;
+		}
+
 		/** Sets the time of the specified keyframe. */
 		/** Sets the time of the specified keyframe. */
 		setFrame (frameIndex: number, time: number, vertices: ArrayLike<number>) {
 		setFrame (frameIndex: number, time: number, vertices: ArrayLike<number>) {
 			this.frames[frameIndex] = time;
 			this.frames[frameIndex] = time;
 			this.frameVertices[frameIndex] = vertices;
 			this.frameVertices[frameIndex] = vertices;
 		}
 		}
 
 
-		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number) {
+		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean) {
 			let slot: Slot = skeleton.slots[this.slotIndex];
 			let slot: Slot = skeleton.slots[this.slotIndex];
 			let slotAttachment: Attachment = slot.getAttachment();
 			let slotAttachment: Attachment = slot.getAttachment();
 			if (!(slotAttachment instanceof VertexAttachment) || !(<VertexAttachment>slotAttachment).applyDeform(this.attachment)) return;
 			if (!(slotAttachment instanceof VertexAttachment) || !(<VertexAttachment>slotAttachment).applyDeform(this.attachment)) return;
@@ -562,11 +650,26 @@ module spine {
 
 
 			if (time >= frames[frames.length - 1]) { // Time is after last frame.
 			if (time >= frames[frames.length - 1]) { // Time is after last frame.
 				let lastVertices = frameVertices[frames.length - 1];
 				let lastVertices = frameVertices[frames.length - 1];
-				if (alpha < 1) {
+				if (alpha == 1) {
+					Utils.arrayCopy(lastVertices, 0, vertices, 0, vertexCount);
+				} else if (setupPose) {
+					let vertexAttachment = slotAttachment as VertexAttachment;
+					if (vertexAttachment.bones == null) {
+						// Unweighted vertex positions, with alpha.
+						let setupVertices = vertexAttachment.vertices;
+						for (let i = 0; i < vertexCount; i++) {
+							let setup = setupVertices[i];
+							vertices[i] = setup + (lastVertices[i] - setup) * alpha;
+						}
+					} else {
+						// Weighted deform offsets, with alpha.
+						for (let i = 0; i < vertexCount; i++)
+							vertices[i] = lastVertices[i] * alpha;
+					}
+				} else {
 					for (let i = 0; i < vertexCount; i++)
 					for (let i = 0; i < vertexCount; i++)
 						vertices[i] += (lastVertices[i] - vertices[i]) * alpha;
 						vertices[i] += (lastVertices[i] - vertices[i]) * alpha;
-				} else
-					Utils.arrayCopy(lastVertices, 0, vertices, 0, vertexCount);
+				}
 				return;
 				return;
 			}
 			}
 
 
@@ -577,15 +680,32 @@ module spine {
 			let frameTime = frames[frame];
 			let frameTime = frames[frame];
 			let percent = this.getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime));
 			let percent = this.getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime));
 
 
-			if (alpha < 1) {
+			if (alpha == 1) {
 				for (let i = 0; i < vertexCount; i++) {
 				for (let i = 0; i < vertexCount; i++) {
 					let prev = prevVertices[i];
 					let prev = prevVertices[i];
-					vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha;
+					vertices[i] = prev + (nextVertices[i] - prev) * percent;
+				}
+			} else if (setupPose) {
+				let vertexAttachment = slotAttachment as VertexAttachment;
+				if (vertexAttachment.bones == null) {
+					// Unweighted vertex positions, with alpha.
+					let setupVertices = vertexAttachment.vertices;
+					for (let i = 0; i < vertexCount; i++) {
+						let prev = prevVertices[i], setup = setupVertices[i];
+						vertices[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha;
+					}
+				} else {
+					// Weighted deform offsets, with alpha.
+					for (let i = 0; i < vertexCount; i++) {
+						let prev = prevVertices[i];
+						vertices[i] = (prev + (nextVertices[i] - prev) * percent) * alpha;
+					}
 				}
 				}
 			} else {
 			} else {
+				// Vertex positions or deform offsets, with alpha.
 				for (let i = 0; i < vertexCount; i++) {
 				for (let i = 0; i < vertexCount; i++) {
 					let prev = prevVertices[i];
 					let prev = prevVertices[i];
-					vertices[i] = prev + (nextVertices[i] - prev) * percent;
+					vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha;
 				}
 				}
 			}
 			}
 		}
 		}
@@ -604,6 +724,10 @@ module spine {
 			this.frames = Utils.newFloatArray(frameCount * IkConstraintTimeline.ENTRIES);
 			this.frames = Utils.newFloatArray(frameCount * IkConstraintTimeline.ENTRIES);
 		}
 		}
 
 
+		getPropertyId () {
+			return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex;
+		}
+
 		/** Sets the time, mix and bend direction of the specified keyframe. */
 		/** Sets the time, mix and bend direction of the specified keyframe. */
 		setFrame (frameIndex: number, time: number, mix: number, bendDirection: number) {
 		setFrame (frameIndex: number, time: number, mix: number, bendDirection: number) {
 			frameIndex *= IkConstraintTimeline.ENTRIES;
 			frameIndex *= IkConstraintTimeline.ENTRIES;
@@ -612,15 +736,21 @@ module spine {
 			this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection;
 			this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection;
 		}
 		}
 
 
-		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number) {
+		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean) {
 			let frames = this.frames;
 			let frames = this.frames;
 			if (time < frames[0]) return; // Time is before first frame.
 			if (time < frames[0]) return; // Time is before first frame.
 
 
 			let constraint: IkConstraint = skeleton.ikConstraints[this.ikConstraintIndex];
 			let constraint: IkConstraint = skeleton.ikConstraints[this.ikConstraintIndex];
 
 
 			if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { // Time is after last frame.
 			if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { // Time is after last frame.
-				constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha;
-				constraint.bendDirection = Math.floor(frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]);
+				if (setupPose) {
+					constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha;
+					constraint.bendDirection = mixingOut ? constraint.data.bendDirection
+						: frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
+				} else {
+					constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha;
+					if (!mixingOut) constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
+				}
 				return;
 				return;
 			}
 			}
 
 
@@ -631,8 +761,13 @@ module spine {
 			let percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1,
 			let percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1,
 				1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime));
 				1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime));
 
 
-			constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha;
-			constraint.bendDirection = Math.floor(frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]);
+			if (setupPose) {
+				constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha;
+				constraint.bendDirection = mixingOut ? constraint.data.bendDirection : frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
+			} else {
+				constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha;
+				if (!mixingOut) constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
+			}
 		}
 		}
 	}
 	}
 
 
@@ -649,6 +784,10 @@ module spine {
 			this.frames = Utils.newFloatArray(frameCount * TransformConstraintTimeline.ENTRIES);
 			this.frames = Utils.newFloatArray(frameCount * TransformConstraintTimeline.ENTRIES);
 		}
 		}
 
 
+		getPropertyId () {
+			return (TimelineType.transformConstraint << 24) + this.transformConstraintIndex;
+		}
+
 		/** Sets the time and mixes of the specified keyframe. */
 		/** Sets the time and mixes of the specified keyframe. */
 		setFrame (frameIndex: number, time: number, rotateMix: number, translateMix: number, scaleMix: number, shearMix: number) {
 		setFrame (frameIndex: number, time: number, rotateMix: number, translateMix: number, scaleMix: number, shearMix: number) {
 			frameIndex *= TransformConstraintTimeline.ENTRIES;
 			frameIndex *= TransformConstraintTimeline.ENTRIES;
@@ -659,36 +798,47 @@ module spine {
 			this.frames[frameIndex + TransformConstraintTimeline.SHEAR] = shearMix;
 			this.frames[frameIndex + TransformConstraintTimeline.SHEAR] = shearMix;
 		}
 		}
 
 
-		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number) {
+		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean) {
 			let frames = this.frames;
 			let frames = this.frames;
 			if (time < frames[0]) return; // Time is before first frame.
 			if (time < frames[0]) return; // Time is before first frame.
 
 
 			let constraint: TransformConstraint = skeleton.transformConstraints[this.transformConstraintIndex];
 			let constraint: TransformConstraint = skeleton.transformConstraints[this.transformConstraintIndex];
 
 
+			let rotate = 0, translate = 0, scale = 0, shear = 0;
 			if (time >= frames[frames.length - TransformConstraintTimeline.ENTRIES]) { // Time is after last frame.
 			if (time >= frames[frames.length - TransformConstraintTimeline.ENTRIES]) { // Time is after last frame.
 				let i = frames.length;
 				let i = frames.length;
-				constraint.rotateMix += (frames[i + TransformConstraintTimeline.PREV_ROTATE] - constraint.rotateMix) * alpha;
-				constraint.translateMix += (frames[i + TransformConstraintTimeline.PREV_TRANSLATE] - constraint.translateMix) * alpha;
-				constraint.scaleMix += (frames[i + TransformConstraintTimeline.PREV_SCALE] - constraint.scaleMix) * alpha;
-				constraint.shearMix += (frames[i + TransformConstraintTimeline.PREV_SHEAR] - constraint.shearMix) * alpha;
-				return;
-			}
+				rotate = frames[i + TransformConstraintTimeline.PREV_ROTATE];
+				translate = frames[i + TransformConstraintTimeline.PREV_TRANSLATE];
+				scale = frames[i + TransformConstraintTimeline.PREV_SCALE];
+				shear = frames[i + TransformConstraintTimeline.PREV_SHEAR];
+			} else {
+				// Interpolate between the previous frame and the current frame.
+				let frame = Animation.binarySearch(frames, time, TransformConstraintTimeline.ENTRIES);
+				rotate = frames[frame + TransformConstraintTimeline.PREV_ROTATE];
+				translate = frames[frame + TransformConstraintTimeline.PREV_TRANSLATE];
+				scale = frames[frame + TransformConstraintTimeline.PREV_SCALE];
+				shear = frames[frame + TransformConstraintTimeline.PREV_SHEAR];
+				let frameTime = frames[frame];
+				let percent = this.getCurvePercent(frame / TransformConstraintTimeline.ENTRIES - 1,
+					1 - (time - frameTime) / (frames[frame + TransformConstraintTimeline.PREV_TIME] - frameTime));
 
 
-			// Interpolate between the previous frame and the current frame.
-			let frame = Animation.binarySearch(frames, time, TransformConstraintTimeline.ENTRIES);
-			let frameTime = frames[frame];
-			let percent = this.getCurvePercent(frame / TransformConstraintTimeline.ENTRIES - 1,
-				1 - (time - frameTime) / (frames[frame + TransformConstraintTimeline.PREV_TIME] - frameTime));
-
-			let rotate = frames[frame + TransformConstraintTimeline.PREV_ROTATE];
-			let translate = frames[frame + TransformConstraintTimeline.PREV_TRANSLATE];
-			let scale = frames[frame + TransformConstraintTimeline.PREV_SCALE];
-			let shear = frames[frame + TransformConstraintTimeline.PREV_SHEAR];
-			constraint.rotateMix += (rotate + (frames[frame + TransformConstraintTimeline.ROTATE] - rotate) * percent - constraint.rotateMix) * alpha;
-			constraint.translateMix += (translate + (frames[frame + TransformConstraintTimeline.TRANSLATE] - translate) * percent - constraint.translateMix)
-				* alpha;
-			constraint.scaleMix += (scale + (frames[frame + TransformConstraintTimeline.SCALE] - scale) * percent - constraint.scaleMix) * alpha;
-			constraint.shearMix += (shear + (frames[frame + TransformConstraintTimeline.SHEAR] - shear) * percent - constraint.shearMix) * alpha;
+				rotate += (frames[frame + TransformConstraintTimeline.ROTATE] - rotate) * percent;
+				translate += (frames[frame + TransformConstraintTimeline.TRANSLATE] - translate) * percent;
+				scale += (frames[frame + TransformConstraintTimeline.SCALE] - scale) * percent;
+				shear += (frames[frame + TransformConstraintTimeline.SHEAR] - shear) * percent;
+			}
+			if (setupPose) {
+				let data = constraint.data;
+				constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha;
+				constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha;
+				constraint.scaleMix = data.scaleMix + (scale - data.scaleMix) * alpha;
+				constraint.shearMix = data.shearMix + (shear - data.shearMix) * alpha;
+			} else {
+				constraint.rotateMix += (rotate - constraint.rotateMix) * alpha;
+				constraint.translateMix += (translate - constraint.translateMix) * alpha;
+				constraint.scaleMix += (scale - constraint.scaleMix) * alpha;
+				constraint.shearMix += (shear - constraint.shearMix) * alpha;
+			}
 		}
 		}
 	}
 	}
 
 
@@ -706,6 +856,10 @@ module spine {
 			this.frames = Utils.newFloatArray(frameCount * PathConstraintPositionTimeline.ENTRIES);
 			this.frames = Utils.newFloatArray(frameCount * PathConstraintPositionTimeline.ENTRIES);
 		}
 		}
 
 
+		getPropertyId () {
+			return (TimelineType.pathConstraintPosition << 24) + this.pathConstraintIndex;
+		}
+
 		/** Sets the time and value of the specified keyframe. */
 		/** Sets the time and value of the specified keyframe. */
 		setFrame (frameIndex: number, time: number, value: number) {
 		setFrame (frameIndex: number, time: number, value: number) {
 			frameIndex *= PathConstraintPositionTimeline.ENTRIES;
 			frameIndex *= PathConstraintPositionTimeline.ENTRIES;
@@ -713,26 +867,29 @@ module spine {
 			this.frames[frameIndex + PathConstraintPositionTimeline.VALUE] = value;
 			this.frames[frameIndex + PathConstraintPositionTimeline.VALUE] = value;
 		}
 		}
 
 
-		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number) {
+		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean) {
 			let frames = this.frames;
 			let frames = this.frames;
 			if (time < frames[0]) return; // Time is before first frame.
 			if (time < frames[0]) return; // Time is before first frame.
 
 
 			let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex];
 			let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex];
 
 
-			if (time >= frames[frames.length - PathConstraintPositionTimeline.ENTRIES]) { // Time is after last frame.
-				let i = frames.length;
-				constraint.position += (frames[i + PathConstraintPositionTimeline.PREV_VALUE] - constraint.position) * alpha;
-				return;
-			}
-
-			// Interpolate between the previous frame and the current frame.
-			let frame = Animation.binarySearch(frames, time, PathConstraintPositionTimeline.ENTRIES);
-			let position = frames[frame + PathConstraintPositionTimeline.PREV_VALUE];
-			let frameTime = frames[frame];
-			let percent = this.getCurvePercent(frame / PathConstraintPositionTimeline.ENTRIES - 1,
-				1 - (time - frameTime) / (frames[frame + PathConstraintPositionTimeline.PREV_TIME] - frameTime));
+			let position = 0;
+			if (time >= frames[frames.length - PathConstraintPositionTimeline.ENTRIES]) // Time is after last frame.
+				position = frames[frames.length + PathConstraintPositionTimeline.PREV_VALUE];
+			else {
+				// Interpolate between the previous frame and the current frame.
+				let frame = Animation.binarySearch(frames, time, PathConstraintPositionTimeline.ENTRIES);
+				position = frames[frame + PathConstraintPositionTimeline.PREV_VALUE];
+				let frameTime = frames[frame];
+				let percent = this.getCurvePercent(frame / PathConstraintPositionTimeline.ENTRIES - 1,
+					1 - (time - frameTime) / (frames[frame + PathConstraintPositionTimeline.PREV_TIME] - frameTime));
 
 
-			constraint.position += (position + (frames[frame + PathConstraintPositionTimeline.VALUE] - position) * percent - constraint.position) * alpha;
+				position += (frames[frame + PathConstraintPositionTimeline.VALUE] - position) * percent;
+			}
+			if (setupPose)
+				constraint.position = constraint.data.position + (position - constraint.data.position) * alpha;
+			else
+				constraint.position += (position - constraint.position) * alpha;
 		}
 		}
 	}
 	}
 
 
@@ -741,26 +898,34 @@ module spine {
 			super(frameCount);
 			super(frameCount);
 		}
 		}
 
 
-		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number) {
+		getPropertyId () {
+			return (TimelineType.pathConstraintSpacing << 24) + this.pathConstraintIndex;
+		}
+
+		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean) {
 			let frames = this.frames;
 			let frames = this.frames;
 			if (time < frames[0]) return; // Time is before first frame.
 			if (time < frames[0]) return; // Time is before first frame.
 
 
 			let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex];
 			let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex];
 
 
-			if (time >= frames[frames.length - PathConstraintSpacingTimeline.ENTRIES]) { // Time is after last frame.
-				let i = frames.length;
-				constraint.spacing += (frames[i + PathConstraintSpacingTimeline.PREV_VALUE] - constraint.spacing) * alpha;
-				return;
-			}
+			let spacing = 0;
+			if (time >= frames[frames.length - PathConstraintSpacingTimeline.ENTRIES]) // Time is after last frame.
+				spacing = frames[frames.length + PathConstraintSpacingTimeline.PREV_VALUE];
+			else {
+				// Interpolate between the previous frame and the current frame.
+				let frame = Animation.binarySearch(frames, time, PathConstraintSpacingTimeline.ENTRIES);
+				spacing = frames[frame + PathConstraintSpacingTimeline.PREV_VALUE];
+				let frameTime = frames[frame];
+				let percent = this.getCurvePercent(frame / PathConstraintSpacingTimeline.ENTRIES - 1,
+					1 - (time - frameTime) / (frames[frame + PathConstraintSpacingTimeline.PREV_TIME] - frameTime));
 
 
-			// Interpolate between the previous frame and the current frame.
-			let frame = Animation.binarySearch(frames, time, PathConstraintSpacingTimeline.ENTRIES);
-			let spacing = frames[frame + PathConstraintSpacingTimeline.PREV_VALUE];
-			let frameTime = frames[frame];
-			let percent = this.getCurvePercent(frame / PathConstraintSpacingTimeline.ENTRIES - 1,
-				1 - (time - frameTime) / (frames[frame + PathConstraintSpacingTimeline.PREV_TIME] - frameTime));
+				spacing += (frames[frame + PathConstraintSpacingTimeline.VALUE] - spacing) * percent;
+			}
 
 
-			constraint.spacing += (spacing + (frames[frame + PathConstraintSpacingTimeline.VALUE] - spacing) * percent - constraint.spacing) * alpha;
+			if (setupPose)
+				constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha;
+			else
+				constraint.spacing += (spacing - constraint.spacing) * alpha;
 		}
 		}
 	}
 	}
 
 
@@ -778,6 +943,10 @@ module spine {
 			this.frames = Utils.newFloatArray(frameCount * PathConstraintMixTimeline.ENTRIES);
 			this.frames = Utils.newFloatArray(frameCount * PathConstraintMixTimeline.ENTRIES);
 		}
 		}
 
 
+		getPropertyId () {
+			return (TimelineType.pathConstraintMix << 24) + this.pathConstraintIndex;
+		}
+
 		/** Sets the time and mixes of the specified keyframe. */
 		/** Sets the time and mixes of the specified keyframe. */
 		setFrame (frameIndex: number, time: number, rotateMix: number, translateMix: number) {
 		setFrame (frameIndex: number, time: number, rotateMix: number, translateMix: number) {
 			frameIndex *= PathConstraintMixTimeline.ENTRIES;
 			frameIndex *= PathConstraintMixTimeline.ENTRIES;
@@ -786,30 +955,36 @@ module spine {
 			this.frames[frameIndex + PathConstraintMixTimeline.TRANSLATE] = translateMix;
 			this.frames[frameIndex + PathConstraintMixTimeline.TRANSLATE] = translateMix;
 		}
 		}
 
 
-		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number) {
+		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean) {
 			let frames = this.frames;
 			let frames = this.frames;
 			if (time < frames[0]) return; // Time is before first frame.
 			if (time < frames[0]) return; // Time is before first frame.
 
 
 			let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex];
 			let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex];
 
 
+			let rotate = 0, translate = 0;
 			if (time >= frames[frames.length - PathConstraintMixTimeline.ENTRIES]) { // Time is after last frame.
 			if (time >= frames[frames.length - PathConstraintMixTimeline.ENTRIES]) { // Time is after last frame.
-				let i = frames.length;
-				constraint.rotateMix += (frames[i + PathConstraintMixTimeline.PREV_ROTATE] - constraint.rotateMix) * alpha;
-				constraint.translateMix += (frames[i + PathConstraintMixTimeline.PREV_TRANSLATE] - constraint.translateMix) * alpha;
-				return;
-			}
+				rotate = frames[frames.length + PathConstraintMixTimeline.PREV_ROTATE];
+				translate = frames[frames.length + PathConstraintMixTimeline.PREV_TRANSLATE];
+			} else {
+				// Interpolate between the previous frame and the current frame.
+				let frame = Animation.binarySearch(frames, time, PathConstraintMixTimeline.ENTRIES);
+				rotate = frames[frame + PathConstraintMixTimeline.PREV_ROTATE];
+				translate = frames[frame + PathConstraintMixTimeline.PREV_TRANSLATE];
+				let frameTime = frames[frame];
+				let percent = this.getCurvePercent(frame / PathConstraintMixTimeline.ENTRIES - 1,
+					1 - (time - frameTime) / (frames[frame + PathConstraintMixTimeline.PREV_TIME] - frameTime));
 
 
-			// Interpolate between the previous frame and the current frame.
-			let frame = Animation.binarySearch(frames, time, PathConstraintMixTimeline.ENTRIES);
-			let rotate = frames[frame + PathConstraintMixTimeline.PREV_ROTATE];
-			let translate = frames[frame + PathConstraintMixTimeline.PREV_TRANSLATE];
-			let frameTime = frames[frame];
-			let percent = this.getCurvePercent(frame / PathConstraintMixTimeline.ENTRIES - 1,
-				1 - (time - frameTime) / (frames[frame + PathConstraintMixTimeline.PREV_TIME] - frameTime));
+				rotate += (frames[frame + PathConstraintMixTimeline.ROTATE] - rotate) * percent;
+				translate += (frames[frame + PathConstraintMixTimeline.TRANSLATE] - translate) * percent;
+			}
 
 
-			constraint.rotateMix += (rotate + (frames[frame + PathConstraintMixTimeline.ROTATE] - rotate) * percent - constraint.rotateMix) * alpha;
-			constraint.translateMix += (translate + (frames[frame + PathConstraintMixTimeline.TRANSLATE] - translate) * percent - constraint.translateMix)
-				* alpha;
+			if (setupPose) {
+				constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha;
+				constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha;
+			} else {
+				constraint.rotateMix += (rotate - constraint.rotateMix) * alpha;
+				constraint.translateMix += (translate - constraint.translateMix) * alpha;
+			}
 		}
 		}
 	}
 	}
 }
 }

+ 590 - 160
spine-ts/core/src/AnimationState.ts

@@ -30,104 +30,291 @@
 
 
 module spine {
 module spine {
 	export class AnimationState {
 	export class AnimationState {
+		static emptyAnimation = new Animation("<empty>", [], 0);
+
 		data: AnimationStateData;
 		data: AnimationStateData;
 		tracks = new Array<TrackEntry>();
 		tracks = new Array<TrackEntry>();
 		events = new Array<Event>();
 		events = new Array<Event>();
-		listeners = new Array<AnimationStateListener>();
+		listeners = new Array<AnimationStateListener2>();
+		queue = new EventQueue(this);
+		propertyIDs = new IntSet();
+		animationsChanged = false;
 		timeScale = 1;
 		timeScale = 1;
 
 
-		constructor (data: AnimationStateData = null) {
-			if (data == null) throw new Error("data cannot be null.");
+		trackEntryPool = new Pool<TrackEntry>(() => new TrackEntry());
+
+		constructor (data: AnimationStateData) {
 			this.data = data;
 			this.data = data;
 		}
 		}
 
 
 		update (delta: number) {
 		update (delta: number) {
 			delta *= this.timeScale;
 			delta *= this.timeScale;
-			for (let i = 0; i < this.tracks.length; i++) {
-				let current = this.tracks[i];
+			let tracks = this.tracks;
+			for (let i = 0, n = tracks.length; i < n; i++) {
+				let current = tracks[i];
 				if (current == null) continue;
 				if (current == null) continue;
 
 
+				current.animationLast = current.nextAnimationLast;
+				current.trackLast = current.nextTrackLast;
+
+				let currentDelta = delta * current.timeScale;
+
+				if (current.delay > 0) {
+					current.delay -= currentDelta;
+					if (current.delay > 0) continue;
+					currentDelta = -current.delay;
+					current.delay = 0;
+				}
+
 				let next = current.next;
 				let next = current.next;
 				if (next != null) {
 				if (next != null) {
-					let nextTime = current.lastTime - next.delay;
+					// When the next entry's delay is passed, change to the next entry, preserving leftover time.
+					let nextTime = current.trackLast - next.delay;
 					if (nextTime >= 0) {
 					if (nextTime >= 0) {
-						let nextDelta = delta * next.timeScale;
-						next.time = nextTime + nextDelta; // For start event to see correct time.
-						current.time += delta * current.timeScale; // For end event to see correct time.
+						next.delay = 0;
+						next.trackTime = nextTime + delta * next.timeScale;
+						current.trackTime += currentDelta;
 						this.setCurrent(i, next);
 						this.setCurrent(i, next);
-						next.time -= nextDelta; // Prevent increasing time twice, below.
-						current = next;
+						while (next.mixingFrom != null) {
+							next.mixTime += currentDelta;
+							next = next.mixingFrom;
+						}
+						continue;
+					}
+					this.updateMixingFrom(current, delta, true);
+				} else {
+					this.updateMixingFrom(current, delta, true);
+					// Clear the track when there is no next entry, the track end time is reached, and there is no mixingFrom.
+					if (current.trackLast >= current.trackEnd && current.mixingFrom == null) {
+						tracks[i] = null;
+						this.queue.end(current);
+						this.disposeNext(current);
+						continue;
 					}
 					}
-				} else if (!current.loop && current.lastTime >= current.endTime) {
-					// End non-looping animation when it reaches its end time and there is no next entry.
-					this.clearTrack(i);
-					continue;
 				}
 				}
 
 
-				current.time += delta * current.timeScale;
-				if (current.previous != null) {
-					let previousDelta = delta * current.previous.timeScale;
-					current.previous.time += previousDelta;
-					current.mixTime += previousDelta;
-				}
+				current.trackTime += currentDelta;
 			}
 			}
+
+			this.queue.drain();
+		}
+
+		updateMixingFrom (entry: TrackEntry, delta: number, canEnd: boolean) {
+			let from = entry.mixingFrom;
+			if (from == null) return;
+
+			if (canEnd && entry.mixTime >= entry.mixDuration && entry.mixTime > 0) {
+				this.queue.end(from);
+				let newFrom = from.mixingFrom;
+				entry.mixingFrom = newFrom;
+				if (newFrom == null) return;
+				entry.mixTime = from.mixTime;
+				entry.mixDuration = from.mixDuration;
+				from = newFrom;
+			}
+
+			from.animationLast = from.nextAnimationLast;
+			from.trackLast = from.nextTrackLast;
+			let mixingFromDelta = delta * from.timeScale;
+			from.trackTime += mixingFromDelta;
+			entry.mixTime += mixingFromDelta;
+
+			this.updateMixingFrom(from, delta, canEnd && from.alpha == 1);
 		}
 		}
 
 
 		apply (skeleton: Skeleton) {
 		apply (skeleton: Skeleton) {
-			let events = this.events;
-			let listenerCount = this.listeners.length;
+			if (skeleton == null) throw new Error("skeleton cannot be null.");
+			if (this.animationsChanged) this._animationsChanged();
 
 
-			for (let i = 0; i < this.tracks.length; i++) {
-				let current = this.tracks[i];
-				if (current == null) continue;
+			let events = this.events;
+			let tracks = this.tracks;
+
+			for (let i = 0, n = tracks.length; i < n; i++) {
+				let current = tracks[i];
+				if (current == null || current.delay > 0) continue;
+
+				// Apply mixing from entries first.
+				let mix = current.alpha;
+				if (current.mixingFrom != null) mix = this.applyMixingFrom(current, skeleton, mix);
+
+				// Apply current entry.
+				let animationLast = current.animationLast, animationTime = current.getAnimationTime();
+				let timelineCount = current.animation.timelines.length;
+				let timelines = current.animation.timelines;
+				if (mix == 1) {
+					for (let ii = 0; ii < timelineCount; ii++)
+						timelines[ii].apply(skeleton, animationLast, animationTime, events, 1, true, false);
+				} else {
+					let firstFrame = current.timelinesRotation.length == 0;
+					if (firstFrame) Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null);
+					let timelinesRotation = current.timelinesRotation;
+
+					let timelinesFirst = current.timelinesFirst;
+					for (let ii = 0; ii < timelineCount; ii++) {
+						let timeline = timelines[ii];
+						if (timeline instanceof RotateTimeline) {
+							this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelinesFirst[ii], timelinesRotation, ii << 1,
+								firstFrame);
+						} else
+							timeline.apply(skeleton, animationLast, animationTime, events, mix, timelinesFirst[ii], false);
+					}
+				}
+				this.queueEvents(current, animationTime);
+				current.nextAnimationLast = animationTime;
+				current.nextTrackLast = current.trackTime;
+			}
 
 
-				events.length = 0;
+			this.queue.drain();
+		}
 
 
-				let time = current.time;
-				let lastTime = current.lastTime;
-				let endTime = current.endTime;
-				let loop = current.loop;
-				if (!loop && time > endTime) time = endTime;
+		applyMixingFrom (entry: TrackEntry, skeleton: Skeleton, alpha: number) {
+			let from = entry.mixingFrom;
+			if (from.mixingFrom != null) this.applyMixingFrom(from, skeleton, alpha);
+
+			let mix = 0;
+			if (entry.mixDuration == 0) // Single frame mix to undo mixingFrom changes.
+				mix = 1;
+			else {
+				mix = entry.mixTime / entry.mixDuration;
+				if (mix > 1) mix = 1;
+				mix *= alpha;
+			}
 
 
-				let previous = current.previous;
-				if (previous == null)
-					current.animation.mix(skeleton, lastTime, time, loop, events, current.mix);
+			let events = mix < from.eventThreshold ? this.events : null;
+			let attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold;
+			let animationLast = from.animationLast, animationTime = from.getAnimationTime();
+			alpha = from.alpha * (1 - mix);
+			let timelineCount = from.animation.timelines.length;
+			let timelines = from.animation.timelines;
+			let timelinesFirst = from.timelinesFirst;
+
+			let firstFrame = from.timelinesRotation.length == 0;
+			if (firstFrame) Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null);
+			let timelinesRotation = from.timelinesRotation;
+
+			for (let i = 0; i < timelineCount; i++) {
+				let timeline = timelines[i];
+				let setupPose = timelinesFirst[i];
+				if (timeline instanceof RotateTimeline)
+					this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, setupPose, timelinesRotation, i << 1, firstFrame);
 				else {
 				else {
-					let previousTime = previous.time;
-					if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime;
-					previous.animation.apply(skeleton, previousTime, previousTime, previous.loop, null);
-
-					let alpha = current.mixTime / current.mixDuration * current.mix;
-					if (alpha >= 1) {
-						alpha = 1;
-						current.previous = null;
+					if (!setupPose) {
+						if (!attachments && timeline instanceof AttachmentTimeline) continue;
+						if (!drawOrder && timeline instanceof DrawOrderTimeline) continue;
 					}
 					}
-					current.animation.mix(skeleton, lastTime, time, loop, events, alpha);
+					timeline.apply(skeleton, animationLast, animationTime, events, alpha, setupPose, true);
 				}
 				}
+			}
 
 
-				for (let ii = 0, nn = events.length; ii < nn; ii++) {
-					let event = events[ii];
-					if (current.listener != null && current.listener.event != null) current.listener.event(i, event);
-					for (let iii = 0; iii < listenerCount; iii++)
-						if (this.listeners[iii].event) this.listeners[iii].event(i, event);
-				}
+			this.queueEvents(from, animationTime);
+			from.nextAnimationLast = animationTime;
+			from.nextTrackLast = from.trackTime;
+
+			return mix;
+		}
+
+		applyRotateTimeline (timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean,
+			timelinesRotation: Array<number>, i: number, firstFrame: boolean) {
+			if (alpha == 1) {
+				timeline.apply(skeleton, 0, time, null, 1, setupPose, false);
+				return;
+			}
+
+			let rotateTimeline = timeline as RotateTimeline;
+			let frames = rotateTimeline.frames;
+			if (time < frames[0]) return; // Time is before first frame.
+
+			let bone = skeleton.bones[rotateTimeline.boneIndex];
+
+			let r2 = 0;
+			if (time >= frames[frames.length - RotateTimeline.ENTRIES]) // Time is after last frame.
+				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 - Math.floor((16384.499999999996 - r2 / 360))) * 360;
+				r2 = prevRotation + r2 * percent + bone.data.rotation;
+				r2 -= (16384 - Math.floor((16384.499999999996 - r2 / 360))) * 360;
+			}
 
 
-				// Check if completed the animation or a loop iteration.
-				if (loop ? (lastTime % endTime > time % endTime) : (lastTime < endTime && time >= endTime)) {
-					let count = MathUtils.toInt(time / endTime);
-					if (current.listener != null && current.listener.complete) current.listener.complete(i, count);
-					for (let ii = 0, nn = this.listeners.length; ii < nn; ii++)
-						if (this.listeners[ii].complete) this.listeners[ii].complete(i, count);
+			// Mix between rotations using the direction of the shortest route on the first frame while detecting crosses.
+			let r1 = setupPose ? bone.data.rotation : bone.rotation;
+			let total = 0, diff = r2 - r1;
+			if (diff == 0) {
+				if (firstFrame) {
+					timelinesRotation[i] = 0;
+					total = 0;
+				} else
+					total = timelinesRotation[i];
+			} else {
+				diff -= (16384 - Math.floor((16384.499999999996 - diff / 360))) * 360;
+				let lastTotal = 0, lastDiff = 0;
+				if (firstFrame) {
+					lastTotal = 0;
+					lastDiff = diff;
+				} else {
+					lastTotal = timelinesRotation[i]; // Angle and direction of mix, including loops.
+					lastDiff = timelinesRotation[i + 1]; // Difference between bones.
 				}
 				}
+				let current = diff > 0, dir = lastTotal >= 0;
+				// Detect cross at 0 (not 180).
+				if (MathUtils.signum(lastDiff) != MathUtils.signum(diff) && Math.abs(lastDiff) <= 90) {
+					// A cross after a 360 rotation is a loop.
+					if (Math.abs(lastTotal) > 180) lastTotal += 360 * MathUtils.signum(lastTotal);
+					dir = current;
+				}
+				total = diff + lastTotal - lastTotal % 360; // Store loops as part of lastTotal.
+				if (dir != current) total += 360 * MathUtils.signum(lastTotal);
+				timelinesRotation[i] = total;
+			}
+			timelinesRotation[i + 1] = diff;
+			r1 += total * alpha;
+			bone.rotation = r1 - (16384 - Math.floor((16384.499999999996 - r1 / 360))) * 360;
+		}
+
+		queueEvents (entry: TrackEntry, animationTime: number) {
+			let animationStart = entry.animationStart, animationEnd = entry.animationEnd;
+			let duration = animationEnd - animationStart;
+			let trackLastWrapped = entry.trackLast % duration;
 
 
-				current.lastTime = current.time;
+			// Queue events before complete.
+			let events = this.events;
+			let i = 0, n = events.length;
+			for (; i < n; i++) {
+				let event = events[i];
+				if (event.time < trackLastWrapped) break;
+				if (event.time > animationEnd) continue; // Discard events outside animation start/end.
+				this.queue.event(entry, event);
+			}
+
+			// Queue complete if completed a loop iteration or the animation.
+			if (entry.loop ? (trackLastWrapped > entry.trackTime % duration)
+				: (animationTime >= animationEnd && entry.animationLast < animationEnd)) {
+				this.queue.complete(entry);
+			}
+
+			// Queue events after complete.
+			for (; i < n; i++) {
+				let event = events[i];
+				if (event.time < animationStart) continue; // Discard events outside animation start/end.
+				this.queue.event(entry, events[i]);
 			}
 			}
+			this.events.length = 0;
 		}
 		}
 
 
 		clearTracks () {
 		clearTracks () {
+			this.queue.drainDisabled = true;
 			for (let i = 0, n = this.tracks.length; i < n; i++)
 			for (let i = 0, n = this.tracks.length; i < n; i++)
 				this.clearTrack(i);
 				this.clearTrack(i);
 			this.tracks.length = 0;
 			this.tracks.length = 0;
+			this.queue.drainDisabled = false;
+			this.queue.drain();
 		}
 		}
 
 
 		clearTrack (trackIndex: number) {
 		clearTrack (trackIndex: number) {
@@ -135,126 +322,235 @@ module spine {
 			let current = this.tracks[trackIndex];
 			let current = this.tracks[trackIndex];
 			if (current == null) return;
 			if (current == null) return;
 
 
-			if (current.listener != null && current.listener.end != null) current.listener.end(trackIndex);
-			for (let i = 0, n = this.listeners.length; i < n; i++)
-				if (this.listeners[i].end) this.listeners[i].end(trackIndex);
+			this.queue.end(current);
 
 
-			this.tracks[trackIndex] = null;
+			this.disposeNext(current);
 
 
-			this.freeAll(current);
-		}
-
-		freeAll (entry: TrackEntry) {
-			while (entry != null) {
-				let next = entry.next;
-				entry = next;
+			let entry = current;
+			while (true) {
+				let from = entry.mixingFrom;
+				if (from == null) break;
+				this.queue.end(from);
+				entry.mixingFrom = null;
+				entry = from;
 			}
 			}
-		}
 
 
-		expandToIndex (index: number) {
-			if (index < this.tracks.length) return this.tracks[index];
-			Utils.setArraySize(this.tracks, index - this.tracks.length + 1, null);
-			this.tracks.length = index + 1;
-			return null;
+			this.tracks[current.trackIndex] = null;
+
+			this.queue.drain();
 		}
 		}
 
 
-		setCurrent (index: number, entry: TrackEntry) {
-			let current = this.expandToIndex(index);
-			if (current != null) {
-				let previous = current.previous;
-				current.previous = null;
-
-				if (current.listener != null && current.listener.end != null) current.listener.end(index);
-				for (let i = 0, n = this.listeners.length; i < n; i++)
-					if (this.listeners[i].end) this.listeners[i].end(index);
-
-				entry.mixDuration = this.data.getMix(current.animation, entry.animation);
-				if (entry.mixDuration > 0) {
-					entry.mixTime = 0;
-					// If a mix is in progress, mix from the closest animation.
-					if (previous != null && current.mixTime / current.mixDuration < 0.5) {
-						entry.previous = previous;
-						previous = current;
-					} else
-						entry.previous = current;
-				}
-			}
+		setCurrent (index: number, current: TrackEntry) {
+			let from = this.expandToIndex(index);
+			this.tracks[index] = current;
+
+			if (from != null) {
+				this.queue.interrupt(from);
+				current.mixingFrom = from;
+				current.mixTime = 0;
+
+				from.timelinesRotation.length = 0;
 
 
-			this.tracks[index] = entry;
+				// If not completely mixed in, set alpha so mixing out happens from current mix to zero.
+				if (from.mixingFrom != null) from.alpha *= Math.min(from.mixTime / from.mixDuration, 1);
+			}
 
 
-			if (entry.listener != null && entry.listener.start != null) entry.listener.start(index);
-			for (let i = 0, n = this.listeners.length; i < n; i++)
-				if (this.listeners[i].start) this.listeners[i].start(index);
+			this.queue.start(current);
 		}
 		}
 
 
-		/** @see #setAnimation(int, Animation, boolean) */
-		setAnimation (trackIndex: number, animationName: string, loop: boolean) {
+		setAnimationByName (trackIndex: number, animationName: string, loop: boolean) {
 			let animation = this.data.skeletonData.findAnimation(animationName);
 			let animation = this.data.skeletonData.findAnimation(animationName);
 			if (animation == null) throw new Error("Animation not found: " + animationName);
 			if (animation == null) throw new Error("Animation not found: " + animationName);
-			return this.setAnimationWith(trackIndex, animation, loop);
+			return this.setAnimation(trackIndex, animation, loop);
 		}
 		}
 
 
-		/** Set the current animation. Any queued animations are cleared. */
-		setAnimationWith (trackIndex: number, animation: Animation, loop: boolean) {
+		setAnimation (trackIndex: number, animation: Animation, loop: boolean) {
+			if (animation == null) throw new Error("animation cannot be null.");
 			let current = this.expandToIndex(trackIndex);
 			let current = this.expandToIndex(trackIndex);
-			if (current != null) this.freeAll(current.next);
-
-			let entry = new TrackEntry();
-			entry.animation = animation;
-			entry.loop = loop;
-			entry.endTime = animation.duration;
+			if (current != null) {
+				if (current.nextTrackLast == -1) {
+					// Don't mix from an entry that was never applied.
+					this.tracks[trackIndex] = null;
+					this.queue.interrupt(current);
+					this.queue.end(current);
+					this.disposeNext(current);
+					current = null;
+				} else
+					this.disposeNext(current);
+			}
+			let entry = this.trackEntry(trackIndex, animation, loop, current);
 			this.setCurrent(trackIndex, entry);
 			this.setCurrent(trackIndex, entry);
+			this.queue.drain();
 			return entry;
 			return entry;
 		}
 		}
 
 
-		/** {@link #addAnimation(int, Animation, boolean, float)} */
-		addAnimation (trackIndex: number, animationName: string, loop: boolean, delay: number) {
+		addAnimationByName (trackIndex: number, animationName: string, loop: boolean, delay: number) {
 			let animation = this.data.skeletonData.findAnimation(animationName);
 			let animation = this.data.skeletonData.findAnimation(animationName);
 			if (animation == null) throw new Error("Animation not found: " + animationName);
 			if (animation == null) throw new Error("Animation not found: " + animationName);
-			return this.addAnimationWith(trackIndex, animation, loop, delay);
+			return this.addAnimation(trackIndex, animation, loop, delay);
 		}
 		}
 
 
-		/** Adds an animation to be played delay seconds after the current or last queued animation.
-		 * @param delay May be <= 0 to use duration of previous animation minus any mix duration plus the negative delay. */
-		addAnimationWith (trackIndex: number, animation: Animation, loop: boolean, delay: number) {
-			let entry = new TrackEntry();
-			entry.animation = animation;
-			entry.loop = loop;
-			entry.endTime = animation.duration;
+		addAnimation (trackIndex: number, animation: Animation, loop: boolean, delay: number) {
+			if (animation == null) throw new Error("animation cannot be null.");
 
 
 			let last = this.expandToIndex(trackIndex);
 			let last = this.expandToIndex(trackIndex);
 			if (last != null) {
 			if (last != null) {
 				while (last.next != null)
 				while (last.next != null)
 					last = last.next;
 					last = last.next;
+			}
+
+			let entry = this.trackEntry(trackIndex, animation, loop, last);
+
+			if (last == null) {
+				this.setCurrent(trackIndex, entry);
+				this.queue.drain();
+			} else {
 				last.next = entry;
 				last.next = entry;
-			} else
-				this.tracks[trackIndex] = entry;
-
-			if (delay <= 0) {
-				if (last != null)
-					delay += last.endTime - this.data.getMix(last.animation, animation);
-				else
-					delay = 0;
+				if (delay <= 0) {
+					let duration = last.animationEnd - last.animationStart;
+					if (duration != 0)
+						delay += duration * (1 + Math.floor(last.trackTime / duration)) - this.data.getMix(last.animation, animation);
+					else
+						delay = 0;
+				}
 			}
 			}
+
 			entry.delay = delay;
 			entry.delay = delay;
+			return entry;
+		}
+
+		setEmptyAnimation (trackIndex: number, mixDuration: number) {
+			let entry = this.setAnimation(trackIndex, AnimationState.emptyAnimation, false);
+			entry.mixDuration = mixDuration;
+			entry.trackEnd = mixDuration;
+			return entry;
+		}
 
 
+		addEmptyAnimation (trackIndex: number, mixDuration: number, delay: number) {
+			if (delay <= 0) delay -= mixDuration;
+			let entry = this.addAnimation(trackIndex, AnimationState.emptyAnimation, false, delay);
+			entry.mixDuration = mixDuration;
+			entry.trackEnd = mixDuration;
 			return entry;
 			return entry;
 		}
 		}
 
 
-		/** @return May be null. */
+		setEmptyAnimations (mixDuration: number) {
+			this.queue.drainDisabled = true;
+			for (let i = 0, n = this.tracks.length; i < n; i++) {
+				let current = this.tracks[i];
+				if (current != null) this.setEmptyAnimation(current.trackIndex, mixDuration);
+			}
+			this.queue.drainDisabled = false;
+			this.queue.drain();
+		}
+
+		expandToIndex (index: number) {
+			if (index < this.tracks.length) return this.tracks[index];
+			Utils.ensureArrayCapacity(this.tracks, index - this.tracks.length + 1);
+			this.tracks.length = index + 1;
+			return null;
+		}
+
+		trackEntry (trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry) {
+			let entry = this.trackEntryPool.obtain();
+			entry.trackIndex = trackIndex;
+			entry.animation = animation;
+			entry.loop = loop;
+
+			entry.eventThreshold = 0;
+			entry.attachmentThreshold = 0;
+			entry.drawOrderThreshold = 0;
+
+			entry.animationStart = 0;
+			entry.animationEnd = animation.duration;
+			entry.animationLast = -1;
+			entry.nextAnimationLast = -1;
+
+			entry.delay = 0;
+			entry.trackTime = 0;
+			entry.trackLast = -1;
+			entry.nextTrackLast = -1;
+			entry.trackEnd = loop ? Number.MAX_VALUE : entry.animationEnd;
+			entry.timeScale = 1;
+
+			entry.alpha = 1;
+			entry.mixTime = 0;
+			entry.mixDuration = last == null ? 0 : this.data.getMix(last.animation, animation);
+			return entry;
+		}
+
+		disposeNext (entry: TrackEntry) {
+			let next = entry.next;
+			while (next != null) {
+				this.queue.dispose(next);
+				next = next.next;
+			}
+			entry.next = null;
+		}
+
+		_animationsChanged () {
+			this.animationsChanged = false;
+
+			let propertyIDs = this.propertyIDs;
+
+			// Compute timelinesFirst from lowest to highest track entries.
+			let i = 0, n = this.tracks.length;
+			propertyIDs.clear();
+			for (; i < n; i++) { // Find first non-null entry.
+				let entry = this.tracks[i];
+				if (entry == null) continue;
+				this.setTimelinesFirst(entry);
+				i++;
+				break;
+			}
+			for (; i < n; i++) { // Rest of entries.
+				let entry = this.tracks[i];
+				if (entry != null) this.checkTimelinesFirst(entry);
+			}
+		}
+
+		setTimelinesFirst (entry: TrackEntry) {
+			if (entry.mixingFrom != null) {
+				this.setTimelinesFirst(entry.mixingFrom);
+				this.checkTimelinesUsage(entry, entry.timelinesFirst);
+				return;
+			}
+			let propertyIDs = this.propertyIDs;
+			let timelines = entry.animation.timelines;
+			let n = timelines.length;
+			let usage = Utils.setArraySize(entry.timelinesFirst, n, false);
+			for (let i = 0; i < n; i++) {
+				propertyIDs.add(timelines[i].getPropertyId());
+				usage[i] = true;
+			}
+		}
+
+		checkTimelinesFirst (entry: TrackEntry) {
+			if (entry.mixingFrom != null) this.checkTimelinesFirst(entry.mixingFrom);
+			this.checkTimelinesUsage(entry, entry.timelinesFirst);
+		}
+
+		checkTimelinesUsage (entry: TrackEntry, usageArray: Array<boolean>) {
+			let propertyIDs = this.propertyIDs;
+			let timelines = entry.animation.timelines;
+			let n = timelines.length;
+			let usage = Utils.setArraySize(usageArray, n);
+			for (let i = 0; i < n; i++)
+				usage[i] = propertyIDs.add(timelines[i].getPropertyId());
+		}
+
 		getCurrent (trackIndex: number) {
 		getCurrent (trackIndex: number) {
 			if (trackIndex >= this.tracks.length) return null;
 			if (trackIndex >= this.tracks.length) return null;
 			return this.tracks[trackIndex];
 			return this.tracks[trackIndex];
 		}
 		}
 
 
-		/** Adds a listener to receive events for all animations. */
-		addListener (listener: AnimationStateListener) {
+		addListener (listener: AnimationStateListener2) {
 			if (listener == null) throw new Error("listener cannot be null.");
 			if (listener == null) throw new Error("listener cannot be null.");
 			this.listeners.push(listener);
 			this.listeners.push(listener);
 		}
 		}
 
 
 		/** Removes the listener added with {@link #addListener(AnimationStateListener)}. */
 		/** Removes the listener added with {@link #addListener(AnimationStateListener)}. */
-		removeListener (listener: AnimationStateListener) {
+		removeListener (listener: AnimationStateListener2) {
 			let index = this.listeners.indexOf(listener);
 			let index = this.listeners.indexOf(listener);
 			if (index >= 0) this.listeners.splice(index, 1);
 			if (index >= 0) this.listeners.splice(index, 1);
 		}
 		}
@@ -262,59 +558,193 @@ module spine {
 		clearListeners () {
 		clearListeners () {
 			this.listeners.length = 0;
 			this.listeners.length = 0;
 		}
 		}
+
+		clearListenerNotifications () {
+			this.queue.clear();
+		}
 	}
 	}
 
 
 	export class TrackEntry {
 	export class TrackEntry {
-		next: TrackEntry; previous: TrackEntry;
 		animation: Animation;
 		animation: Animation;
-		loop = false;
-		delay = 0; time = 0; lastTime = -1; endTime = 0; timeScale = 1;
-		mixTime = 0; mixDuration = 0;
-		listener: AnimationStateListener;
-		mix = 1;
+		next: TrackEntry; mixingFrom: TrackEntry;
+		listener: AnimationStateListener2;
+		trackIndex: number;
+		loop: boolean;
+		eventThreshold: number; attachmentThreshold: number; drawOrderThreshold: number;
+		animationStart: number; animationEnd: number; animationLast: number; nextAnimationLast: number;
+		delay: number; trackTime: number; trackLast: number; nextTrackLast: number; trackEnd: number; timeScale: number;
+		alpha: number; mixTime: number; mixDuration: number; mixAlpha: number;
+		timelinesFirst = new Array<boolean>();
+		timelinesRotation = new Array<number>();
 
 
 		reset () {
 		reset () {
 			this.next = null;
 			this.next = null;
-			this.previous = null;
+			this.mixingFrom = null;
 			this.animation = null;
 			this.animation = null;
 			this.listener = null;
 			this.listener = null;
-			this.timeScale = 1;
-			this.lastTime = -1; // Trigger events on frame zero.
-			this.time = 0;
+			this.timelinesFirst.length = 0;
+			this.timelinesRotation.length = 0;
 		}
 		}
 
 
-		/** Returns true if the current time is greater than the end time, regardless of looping. */
-		isComplete () : boolean {
-			return this.time >= this.endTime;
+		getAnimationTime () {
+			if (this.loop) {
+				let duration = this.animationEnd - this.animationStart;
+				if (duration == 0) return this.animationStart;
+				return (this.trackTime % duration) + this.animationStart;
+			}
+			return Math.min(this.trackTime + this.animationStart, this.animationEnd);
+		}
+
+		setAnimationLast(animationLast: number) {
+			this.animationLast = animationLast;
+			this.nextAnimationLast = animationLast;
+		}
+
+		isComplete () {
+			return this.trackTime >= this.animationEnd - this.animationStart;
 		}
 		}
 	}
 	}
 
 
-	export abstract class AnimationStateAdapter implements AnimationStateListener {
-		event (trackIndex: number, event: Event) {
+	export class EventQueue {
+		objects: Array<any> = [];
+		drainDisabled = false;
+		animState: AnimationState;
+
+		constructor(animState: AnimationState) {
+			this.animState = animState;
+		}
+
+		start (entry: TrackEntry) {
+			this.objects.push(EventType.start);
+			this.objects.push(entry);
+			this.animState.animationsChanged = true;
+		}
+
+		interrupt (entry: TrackEntry) {
+			this.objects.push(EventType.interrupt);
+			this.objects.push(entry);
 		}
 		}
 
 
-		complete (trackIndex: number, loopCount: number) {
+		end (entry: TrackEntry) {
+			this.objects.push(EventType.end);
+			this.objects.push(entry);
+			this.animState.animationsChanged = true;
 		}
 		}
 
 
-		start (trackIndex: number) {
+		dispose (entry: TrackEntry) {
+			this.objects.push(EventType.dispose);
+			this.objects.push(entry);
+		}
+
+		complete (entry: TrackEntry) {
+			this.objects.push(EventType.complete);
+			this.objects.push(entry);
+		}
+
+		event (entry: TrackEntry, event: Event) {
+			this.objects.push(EventType.event);
+			this.objects.push(entry);
+			this.objects.push(event);
+		}
+
+		drain () {
+			if (this.drainDisabled) return;
+			this.drainDisabled = true;
+
+			let objects = this.objects;
+			let listeners = this.animState.listeners;
+
+			for (let i = 0; i < objects.length; i += 2) {
+				let type = objects[i] as EventType;
+				let entry = objects[i + 1] as TrackEntry;
+				switch (type) {
+				case EventType.start:
+					if (entry.listener != null) entry.listener.end(entry);
+					for (let ii = 0; ii < listeners.length; ii++)
+						listeners[ii].start(entry);
+					break;
+				case EventType.interrupt:
+					if (entry.listener != null) entry.listener.end(entry);
+					for (let ii = 0; ii < listeners.length; ii++)
+						listeners[ii].interrupt(entry);
+					break;
+				case EventType.end:
+					if (entry.listener != null) entry.listener.end(entry);
+					for (let ii = 0; ii < listeners.length; ii++)
+						listeners[ii].end(entry);
+					// Fall through.
+				case EventType.dispose:
+					if (entry.listener != null) entry.listener.end(entry);
+					for (let ii = 0; ii < listeners.length; ii++)
+						listeners[ii].dispose(entry);
+					this.animState.trackEntryPool.free(entry);
+					break;
+				case EventType.complete:
+					if (entry.listener != null) entry.listener.complete(entry);
+					for (let ii = 0; ii < listeners.length; ii++)
+						listeners[ii].complete(entry);
+					break;
+				case EventType.event:
+					let event = objects[i++ + 2] as Event;
+					if (entry.listener != null) entry.listener.event(entry, event);
+					for (let ii = 0; ii < listeners.length; ii++)
+						listeners[ii].event(entry, event);
+					break;
+				}
+			}
+			this.clear();
+
+			this.drainDisabled = false;
 		}
 		}
 
 
-		end (trackIndex: number) {
+		clear () {
+			this.objects.length = 0;
 		}
 		}
 	}
 	}
 
 
-	export interface AnimationStateListener {
-		/** Invoked when the current animation triggers an event. */
-		event (trackIndex: number, event: Event): void;
+	export enum EventType {
+		start, interrupt, end, dispose, complete, event
+	}
+
+	export interface AnimationStateListener2 {
+		/** Invoked when this entry has been set as the current entry. */
+		start (entry: TrackEntry): void;
+
+		/** Invoked when another entry has replaced this entry as the current entry. This entry may continue being applied for
+		 * mixing. */
+		interrupt (entry: TrackEntry): void;
 
 
-		/** Invoked when the current animation has completed.
-		 * @param loopCount The number of times the animation reached the end. */
-		complete (trackIndex: number, loopCount: number): void;
+		/** Invoked when this entry is no longer the current entry and will never be applied again. */
+		end (entry: TrackEntry): void;
 
 
-		/** Invoked just after the current animation is set. */
-		start (trackIndex: number): void;
+		/** Invoked when this entry will be disposed. This may occur without the entry ever being set as the current entry.
+		 * References to the entry should not be kept after dispose is called, as it may be destroyed or reused. */
+		dispose (entry: TrackEntry): void;
 
 
-		/** Invoked just before the current animation is replaced. */
-		end (trackIndex: number): void;
+		/** Invoked every time this entry's animation completes a loop. */
+		complete (entry: TrackEntry): void;
+
+		/** Invoked when this entry's animation triggers an event. */
+		event (entry: TrackEntry, event: Event): void;
+	}
+
+	export abstract class AnimationStateAdapter2 implements AnimationStateListener2 {
+		start (entry: TrackEntry) {
+		}
+
+		interrupt (entry: TrackEntry) {
+		}
+
+		end (entry: TrackEntry) {
+		}
+
+		dispose (entry: TrackEntry) {
+		}
+
+		complete (entry: TrackEntry) {
+		}
+
+		event (entry: TrackEntry, event: Event) {
+		}
 	}
 	}
 }
 }

+ 32 - 1
spine-ts/core/src/Utils.ts

@@ -33,6 +33,28 @@ module spine {
 		[key: string]: T;
 		[key: string]: T;
 	}
 	}
 
 
+	export class IntSet {
+		array = new Array<number>();
+
+		add (value: number): boolean {
+			let contains = this.contains(value);
+			this.array[value | 0] = value | 0;
+			return !contains;
+		}
+
+		contains (value: number) {
+			return this.array[value | 0] != undefined;
+		}
+
+		remove (value: number) {
+			this.array[value | 0] = undefined;
+		}
+
+		clear () {
+			this.array.length = 0;
+		}
+	}
+
 	export interface Disposable {
 	export interface Disposable {
 		dispose (): void;
 		dispose (): void;
 	}
 	}
@@ -153,6 +175,11 @@ module spine {
 			return array;
 			return array;
 		}
 		}
 
 
+		static ensureArrayCapacity<T> (array: Array<T>, size: number, value: any = 0): Array<T> {
+			if (array.length >= size) return array;
+			return Utils.setArraySize(array, size, value);
+		}
+
 		static newArray<T> (size: number, defaultValue: T): Array<T> {
 		static newArray<T> (size: number, defaultValue: T): Array<T> {
 			let array = new Array<T>(size);
 			let array = new Array<T>(size);
 			for (let i = 0; i < size; i++) array[i] = defaultValue;
 			for (let i = 0; i < size; i++) array[i] = defaultValue;
@@ -196,11 +223,15 @@ module spine {
 		}
 		}
 
 
 		free (item: T) {
 		free (item: T) {
+			if ((item as any).reset) (item as any).reset();
 			this.items.push(item);
 			this.items.push(item);
 		}
 		}
 
 
 		freeAll (items: ArrayLike<T>) {
 		freeAll (items: ArrayLike<T>) {
-			for (let i = 0; i < items.length; i++) this.items[i] = items[i];
+			for (let i = 0; i < items.length; i++) {
+				if ((items[i] as any).reset) (items[i] as any).reset();
+				this.items[i] = items[i];
+			}
 		}
 		}
 
 
 		clear () {
 		clear () {

+ 2 - 2
spine-ts/widget/src/Widget.ts

@@ -143,7 +143,7 @@ module spine {
 				}
 				}
 
 
 				var animationState = this.state = new spine.AnimationState(new spine.AnimationStateData(skeleton.data));
 				var animationState = this.state = new spine.AnimationState(new spine.AnimationStateData(skeleton.data));
-				animationState.setAnimation(0, config.animation, true);
+				animationState.setAnimationByName(0, config.animation, true);
 				if (config.success) config.success(this);
 				if (config.success) config.success(this);
 				this.loaded = true;
 				this.loaded = true;
 				requestAnimationFrame(() => { this.render(); });
 				requestAnimationFrame(() => { this.render(); });
@@ -246,7 +246,7 @@ module spine {
 		setAnimation (animationName: string) {
 		setAnimation (animationName: string) {
 			if (!this.loaded) throw new Error("Widget isn't loaded yet");
 			if (!this.loaded) throw new Error("Widget isn't loaded yet");
 			this.skeleton.setToSetupPose();
 			this.skeleton.setToSetupPose();
-			this.state.setAnimation(0, animationName, this.config.loop);
+			this.state.setAnimationByName(0, animationName, this.config.loop);
 		}
 		}
 
 
 
 

Vissa filer visades inte eftersom för många filer har ändrats