[ts] Port of new AnimationState, needs testing

This commit is contained in:
badlogic 2016-10-24 13:32:58 +02:00
parent eb0876818f
commit 787af5c8f8
22 changed files with 7211 additions and 2423 deletions

View File

@ -92,13 +92,29 @@ declare module spine {
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 linearSearch(values: ArrayLike<number>, target: number, step: number): number;
}
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 {
static LINEAR: number;
@ -106,6 +122,7 @@ declare module spine {
static BEZIER: number;
static BEZIER_SIZE: number;
private curves;
abstract getPropertyId(): number;
constructor(frameCount: number);
getFrameCount(): number;
setLinear(frameIndex: number): void;
@ -113,7 +130,7 @@ declare module spine {
getCurveType(frameIndex: number): number;
setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
getCurvePercent(frameIndex: number, percent: number): number;
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class RotateTimeline extends CurveTimeline {
static ENTRIES: number;
@ -123,8 +140,9 @@ declare module spine {
boneIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, degrees: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class TranslateTimeline extends CurveTimeline {
static ENTRIES: number;
@ -136,16 +154,19 @@ declare module spine {
boneIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, x: number, y: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class ScaleTimeline extends TranslateTimeline {
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 {
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 {
static ENTRIES: number;
@ -161,42 +182,47 @@ declare module spine {
slotIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
slotIndex: number;
frames: ArrayLike<number>;
attachmentNames: Array<string>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
events: Array<Event>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
drawOrders: Array<Array<number>>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
frameVertices: Array<ArrayLike<number>>;
slotIndex: number;
attachment: VertexAttachment;
frames: ArrayLike<number>;
frameVertices: Array<ArrayLike<number>>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -208,8 +234,9 @@ declare module spine {
ikConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -225,8 +252,9 @@ declare module spine {
transformConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -236,12 +264,14 @@ declare module spine {
pathConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
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 {
static ENTRIES: number;
@ -253,62 +283,121 @@ declare module spine {
pathConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
}
declare module spine {
class AnimationState {
static emptyAnimation: Animation;
data: AnimationStateData;
tracks: TrackEntry[];
events: Event[];
listeners: AnimationStateListener[];
listeners: AnimationStateListener2[];
queue: EventQueue;
propertyIDs: IntSet;
animationsChanged: boolean;
timeScale: number;
constructor(data?: AnimationStateData);
trackEntryPool: Pool<TrackEntry>;
constructor(data: AnimationStateData);
update(delta: number): void;
updateMixingFrom(entry: TrackEntry, delta: number, canEnd: boolean): 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;
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;
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;
addListener(listener: AnimationStateListener): void;
removeListener(listener: AnimationStateListener): void;
addListener(listener: AnimationStateListener2): void;
removeListener(listener: AnimationStateListener2): void;
clearListeners(): void;
clearListenerNotifications(): void;
}
class TrackEntry {
next: TrackEntry;
previous: TrackEntry;
animation: Animation;
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;
time: number;
lastTime: number;
endTime: number;
trackTime: number;
trackLast: number;
nextTrackLast: number;
trackEnd: number;
timeScale: number;
alpha: number;
mixTime: number;
mixDuration: number;
listener: AnimationStateListener;
mix: number;
mixAlpha: number;
timelinesFirst: boolean[];
timelinesRotation: number[];
reset(): void;
getAnimationTime(): number;
setAnimationLast(animationLast: number): void;
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 {
@ -898,6 +987,13 @@ declare module spine {
interface Map<T> {
[key: string]: T;
}
class IntSet {
array: number[];
add(value: number): boolean;
contains(value: number): boolean;
remove(value: number): void;
clear(): void;
}
interface Disposable {
dispose(): void;
}
@ -936,6 +1032,7 @@ declare module spine {
static SUPPORTS_TYPED_ARRAYS: boolean;
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 ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
static newArray<T>(size: number, defaultValue: T): Array<T>;
static newFloatArray(size: number): ArrayLike<number>;
static toFloatArray(array: Array<number>): number[] | Float32Array;

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -92,13 +92,29 @@ declare module spine {
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 linearSearch(values: ArrayLike<number>, target: number, step: number): number;
}
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 {
static LINEAR: number;
@ -106,6 +122,7 @@ declare module spine {
static BEZIER: number;
static BEZIER_SIZE: number;
private curves;
abstract getPropertyId(): number;
constructor(frameCount: number);
getFrameCount(): number;
setLinear(frameIndex: number): void;
@ -113,7 +130,7 @@ declare module spine {
getCurveType(frameIndex: number): number;
setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
getCurvePercent(frameIndex: number, percent: number): number;
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class RotateTimeline extends CurveTimeline {
static ENTRIES: number;
@ -123,8 +140,9 @@ declare module spine {
boneIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, degrees: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class TranslateTimeline extends CurveTimeline {
static ENTRIES: number;
@ -136,16 +154,19 @@ declare module spine {
boneIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, x: number, y: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class ScaleTimeline extends TranslateTimeline {
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 {
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 {
static ENTRIES: number;
@ -161,42 +182,47 @@ declare module spine {
slotIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
slotIndex: number;
frames: ArrayLike<number>;
attachmentNames: Array<string>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
events: Array<Event>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
drawOrders: Array<Array<number>>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
frameVertices: Array<ArrayLike<number>>;
slotIndex: number;
attachment: VertexAttachment;
frames: ArrayLike<number>;
frameVertices: Array<ArrayLike<number>>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -208,8 +234,9 @@ declare module spine {
ikConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -225,8 +252,9 @@ declare module spine {
transformConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -236,12 +264,14 @@ declare module spine {
pathConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
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 {
static ENTRIES: number;
@ -253,62 +283,121 @@ declare module spine {
pathConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
}
declare module spine {
class AnimationState {
static emptyAnimation: Animation;
data: AnimationStateData;
tracks: TrackEntry[];
events: Event[];
listeners: AnimationStateListener[];
listeners: AnimationStateListener2[];
queue: EventQueue;
propertyIDs: IntSet;
animationsChanged: boolean;
timeScale: number;
constructor(data?: AnimationStateData);
trackEntryPool: Pool<TrackEntry>;
constructor(data: AnimationStateData);
update(delta: number): void;
updateMixingFrom(entry: TrackEntry, delta: number, canEnd: boolean): 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;
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;
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;
addListener(listener: AnimationStateListener): void;
removeListener(listener: AnimationStateListener): void;
addListener(listener: AnimationStateListener2): void;
removeListener(listener: AnimationStateListener2): void;
clearListeners(): void;
clearListenerNotifications(): void;
}
class TrackEntry {
next: TrackEntry;
previous: TrackEntry;
animation: Animation;
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;
time: number;
lastTime: number;
endTime: number;
trackTime: number;
trackLast: number;
nextTrackLast: number;
trackEnd: number;
timeScale: number;
alpha: number;
mixTime: number;
mixDuration: number;
listener: AnimationStateListener;
mix: number;
mixAlpha: number;
timelinesFirst: boolean[];
timelinesRotation: number[];
reset(): void;
getAnimationTime(): number;
setAnimationLast(animationLast: number): void;
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 {
@ -898,6 +987,13 @@ declare module spine {
interface Map<T> {
[key: string]: T;
}
class IntSet {
array: number[];
add(value: number): boolean;
contains(value: number): boolean;
remove(value: number): void;
clear(): void;
}
interface Disposable {
dispose(): void;
}
@ -936,6 +1032,7 @@ declare module spine {
static SUPPORTS_TYPED_ARRAYS: boolean;
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 ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
static newArray<T>(size: number, defaultValue: T): Array<T>;
static newFloatArray(size: number): ArrayLike<number>;
static toFloatArray(array: Array<number>): number[] | Float32Array;

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -4,13 +4,29 @@ declare module spine {
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 linearSearch(values: ArrayLike<number>, target: number, step: number): number;
}
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 {
static LINEAR: number;
@ -18,6 +34,7 @@ declare module spine {
static BEZIER: number;
static BEZIER_SIZE: number;
private curves;
abstract getPropertyId(): number;
constructor(frameCount: number);
getFrameCount(): number;
setLinear(frameIndex: number): void;
@ -25,7 +42,7 @@ declare module spine {
getCurveType(frameIndex: number): number;
setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
getCurvePercent(frameIndex: number, percent: number): number;
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class RotateTimeline extends CurveTimeline {
static ENTRIES: number;
@ -35,8 +52,9 @@ declare module spine {
boneIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, degrees: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class TranslateTimeline extends CurveTimeline {
static ENTRIES: number;
@ -48,16 +66,19 @@ declare module spine {
boneIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, x: number, y: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class ScaleTimeline extends TranslateTimeline {
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 {
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 {
static ENTRIES: number;
@ -73,42 +94,47 @@ declare module spine {
slotIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
slotIndex: number;
frames: ArrayLike<number>;
attachmentNames: Array<string>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
events: Array<Event>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
drawOrders: Array<Array<number>>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
frameVertices: Array<ArrayLike<number>>;
slotIndex: number;
attachment: VertexAttachment;
frames: ArrayLike<number>;
frameVertices: Array<ArrayLike<number>>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -120,8 +146,9 @@ declare module spine {
ikConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -137,8 +164,9 @@ declare module spine {
transformConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -148,12 +176,14 @@ declare module spine {
pathConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
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 {
static ENTRIES: number;
@ -165,62 +195,121 @@ declare module spine {
pathConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
}
declare module spine {
class AnimationState {
static emptyAnimation: Animation;
data: AnimationStateData;
tracks: TrackEntry[];
events: Event[];
listeners: AnimationStateListener[];
listeners: AnimationStateListener2[];
queue: EventQueue;
propertyIDs: IntSet;
animationsChanged: boolean;
timeScale: number;
constructor(data?: AnimationStateData);
trackEntryPool: Pool<TrackEntry>;
constructor(data: AnimationStateData);
update(delta: number): void;
updateMixingFrom(entry: TrackEntry, delta: number, canEnd: boolean): 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;
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;
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;
addListener(listener: AnimationStateListener): void;
removeListener(listener: AnimationStateListener): void;
addListener(listener: AnimationStateListener2): void;
removeListener(listener: AnimationStateListener2): void;
clearListeners(): void;
clearListenerNotifications(): void;
}
class TrackEntry {
next: TrackEntry;
previous: TrackEntry;
animation: Animation;
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;
time: number;
lastTime: number;
endTime: number;
trackTime: number;
trackLast: number;
nextTrackLast: number;
trackEnd: number;
timeScale: number;
alpha: number;
mixTime: number;
mixDuration: number;
listener: AnimationStateListener;
mix: number;
mixAlpha: number;
timelinesFirst: boolean[];
timelinesRotation: number[];
reset(): void;
getAnimationTime(): number;
setAnimationLast(animationLast: number): void;
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 {
@ -872,6 +961,13 @@ declare module spine {
interface Map<T> {
[key: string]: T;
}
class IntSet {
array: number[];
add(value: number): boolean;
contains(value: number): boolean;
remove(value: number): void;
clear(): void;
}
interface Disposable {
dispose(): void;
}
@ -910,6 +1006,7 @@ declare module spine {
static SUPPORTS_TYPED_ARRAYS: boolean;
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 ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
static newArray<T>(size: number, defaultValue: T): Array<T>;
static newFloatArray(size: number): ArrayLike<number>;
static toFloatArray(array: Array<number>): number[] | Float32Array;

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -4,13 +4,29 @@ declare module spine {
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 linearSearch(values: ArrayLike<number>, target: number, step: number): number;
}
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 {
static LINEAR: number;
@ -18,6 +34,7 @@ declare module spine {
static BEZIER: number;
static BEZIER_SIZE: number;
private curves;
abstract getPropertyId(): number;
constructor(frameCount: number);
getFrameCount(): number;
setLinear(frameIndex: number): void;
@ -25,7 +42,7 @@ declare module spine {
getCurveType(frameIndex: number): number;
setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
getCurvePercent(frameIndex: number, percent: number): number;
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class RotateTimeline extends CurveTimeline {
static ENTRIES: number;
@ -35,8 +52,9 @@ declare module spine {
boneIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, degrees: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class TranslateTimeline extends CurveTimeline {
static ENTRIES: number;
@ -48,16 +66,19 @@ declare module spine {
boneIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, x: number, y: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class ScaleTimeline extends TranslateTimeline {
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 {
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 {
static ENTRIES: number;
@ -73,42 +94,47 @@ declare module spine {
slotIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
slotIndex: number;
frames: ArrayLike<number>;
attachmentNames: Array<string>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
events: Array<Event>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
drawOrders: Array<Array<number>>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
frameVertices: Array<ArrayLike<number>>;
slotIndex: number;
attachment: VertexAttachment;
frames: ArrayLike<number>;
frameVertices: Array<ArrayLike<number>>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -120,8 +146,9 @@ declare module spine {
ikConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -137,8 +164,9 @@ declare module spine {
transformConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -148,12 +176,14 @@ declare module spine {
pathConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
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 {
static ENTRIES: number;
@ -165,62 +195,121 @@ declare module spine {
pathConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
}
declare module spine {
class AnimationState {
static emptyAnimation: Animation;
data: AnimationStateData;
tracks: TrackEntry[];
events: Event[];
listeners: AnimationStateListener[];
listeners: AnimationStateListener2[];
queue: EventQueue;
propertyIDs: IntSet;
animationsChanged: boolean;
timeScale: number;
constructor(data?: AnimationStateData);
trackEntryPool: Pool<TrackEntry>;
constructor(data: AnimationStateData);
update(delta: number): void;
updateMixingFrom(entry: TrackEntry, delta: number, canEnd: boolean): 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;
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;
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;
addListener(listener: AnimationStateListener): void;
removeListener(listener: AnimationStateListener): void;
addListener(listener: AnimationStateListener2): void;
removeListener(listener: AnimationStateListener2): void;
clearListeners(): void;
clearListenerNotifications(): void;
}
class TrackEntry {
next: TrackEntry;
previous: TrackEntry;
animation: Animation;
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;
time: number;
lastTime: number;
endTime: number;
trackTime: number;
trackLast: number;
nextTrackLast: number;
trackEnd: number;
timeScale: number;
alpha: number;
mixTime: number;
mixDuration: number;
listener: AnimationStateListener;
mix: number;
mixAlpha: number;
timelinesFirst: boolean[];
timelinesRotation: number[];
reset(): void;
getAnimationTime(): number;
setAnimationLast(animationLast: number): void;
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 {
@ -872,6 +961,13 @@ declare module spine {
interface Map<T> {
[key: string]: T;
}
class IntSet {
array: number[];
add(value: number): boolean;
contains(value: number): boolean;
remove(value: number): void;
clear(): void;
}
interface Disposable {
dispose(): void;
}
@ -910,6 +1006,7 @@ declare module spine {
static SUPPORTS_TYPED_ARRAYS: boolean;
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 ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
static newArray<T>(size: number, defaultValue: T): Array<T>;
static newFloatArray(size: number): ArrayLike<number>;
static toFloatArray(array: Array<number>): number[] | Float32Array;

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -4,13 +4,29 @@ declare module spine {
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 linearSearch(values: ArrayLike<number>, target: number, step: number): number;
}
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 {
static LINEAR: number;
@ -18,6 +34,7 @@ declare module spine {
static BEZIER: number;
static BEZIER_SIZE: number;
private curves;
abstract getPropertyId(): number;
constructor(frameCount: number);
getFrameCount(): number;
setLinear(frameIndex: number): void;
@ -25,7 +42,7 @@ declare module spine {
getCurveType(frameIndex: number): number;
setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
getCurvePercent(frameIndex: number, percent: number): number;
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class RotateTimeline extends CurveTimeline {
static ENTRIES: number;
@ -35,8 +52,9 @@ declare module spine {
boneIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, degrees: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class TranslateTimeline extends CurveTimeline {
static ENTRIES: number;
@ -48,16 +66,19 @@ declare module spine {
boneIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, x: number, y: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class ScaleTimeline extends TranslateTimeline {
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 {
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 {
static ENTRIES: number;
@ -73,42 +94,47 @@ declare module spine {
slotIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
slotIndex: number;
frames: ArrayLike<number>;
attachmentNames: Array<string>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
events: Array<Event>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
drawOrders: Array<Array<number>>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
frameVertices: Array<ArrayLike<number>>;
slotIndex: number;
attachment: VertexAttachment;
frames: ArrayLike<number>;
frameVertices: Array<ArrayLike<number>>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -120,8 +146,9 @@ declare module spine {
ikConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -137,8 +164,9 @@ declare module spine {
transformConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -148,12 +176,14 @@ declare module spine {
pathConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
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 {
static ENTRIES: number;
@ -165,62 +195,121 @@ declare module spine {
pathConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
}
declare module spine {
class AnimationState {
static emptyAnimation: Animation;
data: AnimationStateData;
tracks: TrackEntry[];
events: Event[];
listeners: AnimationStateListener[];
listeners: AnimationStateListener2[];
queue: EventQueue;
propertyIDs: IntSet;
animationsChanged: boolean;
timeScale: number;
constructor(data?: AnimationStateData);
trackEntryPool: Pool<TrackEntry>;
constructor(data: AnimationStateData);
update(delta: number): void;
updateMixingFrom(entry: TrackEntry, delta: number, canEnd: boolean): 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;
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;
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;
addListener(listener: AnimationStateListener): void;
removeListener(listener: AnimationStateListener): void;
addListener(listener: AnimationStateListener2): void;
removeListener(listener: AnimationStateListener2): void;
clearListeners(): void;
clearListenerNotifications(): void;
}
class TrackEntry {
next: TrackEntry;
previous: TrackEntry;
animation: Animation;
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;
time: number;
lastTime: number;
endTime: number;
trackTime: number;
trackLast: number;
nextTrackLast: number;
trackEnd: number;
timeScale: number;
alpha: number;
mixTime: number;
mixDuration: number;
listener: AnimationStateListener;
mix: number;
mixAlpha: number;
timelinesFirst: boolean[];
timelinesRotation: number[];
reset(): void;
getAnimationTime(): number;
setAnimationLast(animationLast: number): void;
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 {
@ -872,6 +961,13 @@ declare module spine {
interface Map<T> {
[key: string]: T;
}
class IntSet {
array: number[];
add(value: number): boolean;
contains(value: number): boolean;
remove(value: number): void;
clear(): void;
}
interface Disposable {
dispose(): void;
}
@ -910,6 +1006,7 @@ declare module spine {
static SUPPORTS_TYPED_ARRAYS: boolean;
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 ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
static newArray<T>(size: number, defaultValue: T): Array<T>;
static newFloatArray(size: number): ArrayLike<number>;
static toFloatArray(array: Array<number>): number[] | Float32Array;

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -4,13 +4,29 @@ declare module spine {
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 linearSearch(values: ArrayLike<number>, target: number, step: number): number;
}
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 {
static LINEAR: number;
@ -18,6 +34,7 @@ declare module spine {
static BEZIER: number;
static BEZIER_SIZE: number;
private curves;
abstract getPropertyId(): number;
constructor(frameCount: number);
getFrameCount(): number;
setLinear(frameIndex: number): void;
@ -25,7 +42,7 @@ declare module spine {
getCurveType(frameIndex: number): number;
setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
getCurvePercent(frameIndex: number, percent: number): number;
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class RotateTimeline extends CurveTimeline {
static ENTRIES: number;
@ -35,8 +52,9 @@ declare module spine {
boneIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, degrees: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class TranslateTimeline extends CurveTimeline {
static ENTRIES: number;
@ -48,16 +66,19 @@ declare module spine {
boneIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, x: number, y: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
class ScaleTimeline extends TranslateTimeline {
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 {
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 {
static ENTRIES: number;
@ -73,42 +94,47 @@ declare module spine {
slotIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
slotIndex: number;
frames: ArrayLike<number>;
attachmentNames: Array<string>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
events: Array<Event>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
drawOrders: Array<Array<number>>;
constructor(frameCount: number);
getPropertyId(): number;
getFrameCount(): number;
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 {
frames: ArrayLike<number>;
frameVertices: Array<ArrayLike<number>>;
slotIndex: number;
attachment: VertexAttachment;
frames: ArrayLike<number>;
frameVertices: Array<ArrayLike<number>>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -120,8 +146,9 @@ declare module spine {
ikConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -137,8 +164,9 @@ declare module spine {
transformConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
static ENTRIES: number;
@ -148,12 +176,14 @@ declare module spine {
pathConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
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 {
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 {
static ENTRIES: number;
@ -165,62 +195,121 @@ declare module spine {
pathConstraintIndex: number;
frames: ArrayLike<number>;
constructor(frameCount: number);
getPropertyId(): number;
setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
}
}
declare module spine {
class AnimationState {
static emptyAnimation: Animation;
data: AnimationStateData;
tracks: TrackEntry[];
events: Event[];
listeners: AnimationStateListener[];
listeners: AnimationStateListener2[];
queue: EventQueue;
propertyIDs: IntSet;
animationsChanged: boolean;
timeScale: number;
constructor(data?: AnimationStateData);
trackEntryPool: Pool<TrackEntry>;
constructor(data: AnimationStateData);
update(delta: number): void;
updateMixingFrom(entry: TrackEntry, delta: number, canEnd: boolean): 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;
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;
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;
addListener(listener: AnimationStateListener): void;
removeListener(listener: AnimationStateListener): void;
addListener(listener: AnimationStateListener2): void;
removeListener(listener: AnimationStateListener2): void;
clearListeners(): void;
clearListenerNotifications(): void;
}
class TrackEntry {
next: TrackEntry;
previous: TrackEntry;
animation: Animation;
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;
time: number;
lastTime: number;
endTime: number;
trackTime: number;
trackLast: number;
nextTrackLast: number;
trackEnd: number;
timeScale: number;
alpha: number;
mixTime: number;
mixDuration: number;
listener: AnimationStateListener;
mix: number;
mixAlpha: number;
timelinesFirst: boolean[];
timelinesRotation: number[];
reset(): void;
getAnimationTime(): number;
setAnimationLast(animationLast: number): void;
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 {
@ -872,6 +961,13 @@ declare module spine {
interface Map<T> {
[key: string]: T;
}
class IntSet {
array: number[];
add(value: number): boolean;
contains(value: number): boolean;
remove(value: number): void;
clear(): void;
}
interface Disposable {
dispose(): void;
}
@ -910,6 +1006,7 @@ declare module spine {
static SUPPORTS_TYPED_ARRAYS: boolean;
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 ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
static newArray<T>(size: number, defaultValue: T): Array<T>;
static newFloatArray(size: number): ArrayLike<number>;
static toFloatArray(array: Array<number>): number[] | Float32Array;

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -42,7 +42,7 @@ module spine {
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 (loop && this.duration != 0) {
@ -52,20 +52,7 @@ module spine {
let timelines = this.timelines;
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) {
@ -91,7 +78,16 @@ module spine {
}
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 {
@ -100,6 +96,8 @@ module spine {
private curves: ArrayLike<number>; // type, x, y, ...
abstract getPropertyId(): number;
constructor (frameCount: number) {
if (frameCount <= 0) throw new Error("frameCount must be > 0: " + frameCount);
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.
}
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 {
@ -195,6 +193,10 @@ module spine {
this.frames = Utils.newFloatArray(frameCount << 1);
}
getPropertyId () {
return (TimelineType.rotate << 24) + this.boneIndex;
}
/** Sets the time and angle of the specified keyframe. */
setFrame (frameIndex: number, time: number, degrees: number) {
frameIndex <<= 1;
@ -202,19 +204,20 @@ module spine {
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;
if (time < frames[0]) return; // Time is before first frame.
let bone = skeleton.bones[this.boneIndex];
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;
}
@ -225,17 +228,17 @@ module spine {
let percent = this.getCurvePercent((frame >> 1) - 1,
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);
}
getPropertyId () {
return (TimelineType.translate << 24) + this.boneIndex;
}
/** Sets the time and value of the specified keyframe. */
setFrame (frameIndex: number, time: number, x: number, y: number) {
frameIndex *= TranslateTimeline.ENTRIES;
@ -260,28 +267,35 @@ module spine {
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;
if (time < frames[0]) return; // Time is before first frame.
let bone = skeleton.bones[this.boneIndex];
let x = 0, y = 0;
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;
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));
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;
}
// 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));
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;
}
}
@ -290,27 +304,54 @@ module spine {
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;
if (time < frames[0]) return; // Time is before first frame.
let bone = skeleton.bones[this.boneIndex];
let x = 0, y = 0;
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;
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));
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;
}
// 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));
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;
}
}
@ -319,27 +360,39 @@ module spine {
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;
if (time < frames[0]) return; // Time is before first frame.
let bone = skeleton.bones[this.boneIndex];
let x = 0, y = 0;
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;
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));
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;
}
// 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));
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;
}
}
@ -356,6 +409,10 @@ module spine {
this.frames = Utils.newFloatArray(frameCount * ColorTimeline.ENTRIES);
}
getPropertyId () {
return (TimelineType.color << 24) + this.slotIndex;
}
/** Sets the time and value of the specified keyframe. */
setFrame (frameIndex: number, time: number, r: number, g: number, b: number, a: number) {
frameIndex *= ColorTimeline.ENTRIES;
@ -366,7 +423,7 @@ module spine {
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;
if (time < frames[0]) return; // Time is before first frame.
@ -393,11 +450,14 @@ module spine {
b += (frames[frame + ColorTimeline.B] - b) * 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);
else
color.set(r, g, b, a);
}
}
}
@ -411,6 +471,10 @@ module spine {
this.attachmentNames = new Array<string>(frameCount);
}
getPropertyId () {
return (TimelineType.attachment << 24) + this.slotIndex;
}
getFrameCount () {
return this.frames.length;
}
@ -421,7 +485,14 @@ module spine {
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;
if (time < frames[0]) return; // Time is before first frame.
@ -446,6 +517,10 @@ module spine {
this.events = new Array<Event>(frameCount);
}
getPropertyId () {
return TimelineType.event << 24;
}
getFrameCount () {
return this.frames.length;
}
@ -457,13 +532,13 @@ module spine {
}
/** 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;
let frames = this.frames;
let frameCount = this.frames.length;
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;
} else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame.
return;
@ -494,6 +569,10 @@ module spine {
this.drawOrders = new Array<Array<number>>(frameCount);
}
getPropertyId () {
return TimelineType.drawOrder << 24;
}
getFrameCount () {
return this.frames.length;
}
@ -505,7 +584,12 @@ module spine {
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;
if (time < frames[0]) return; // Time is before first frame.
@ -528,10 +612,10 @@ module spine {
}
export class DeformTimeline extends CurveTimeline {
frames: ArrayLike<number>; // time, ...
frameVertices: Array<ArrayLike<number>>;
slotIndex: number;
attachment: VertexAttachment;
frames: ArrayLike<number>; // time, ...
frameVertices: Array<ArrayLike<number>>;
constructor (frameCount: number) {
super(frameCount);
@ -539,13 +623,17 @@ module spine {
this.frameVertices = new Array<ArrayLike<number>>(frameCount);
}
getPropertyId () {
return (TimelineType.deform << 24) + this.slotIndex;
}
/** Sets the time of the specified keyframe. */
setFrame (frameIndex: number, time: number, vertices: ArrayLike<number>) {
this.frames[frameIndex] = time;
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 slotAttachment: Attachment = slot.getAttachment();
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.
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++)
vertices[i] += (lastVertices[i] - vertices[i]) * alpha;
} else
Utils.arrayCopy(lastVertices, 0, vertices, 0, vertexCount);
}
return;
}
@ -577,16 +680,33 @@ module spine {
let frameTime = frames[frame];
let percent = this.getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime));
if (alpha < 1) {
for (let i = 0; i < vertexCount; i++) {
let prev = prevVertices[i];
vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha;
}
} else {
if (alpha == 1) {
for (let i = 0; i < vertexCount; i++) {
let prev = prevVertices[i];
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 {
// Vertex positions or deform offsets, with alpha.
for (let i = 0; i < vertexCount; i++) {
let prev = prevVertices[i];
vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha;
}
}
}
}
@ -604,6 +724,10 @@ module spine {
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. */
setFrame (frameIndex: number, time: number, mix: number, bendDirection: number) {
frameIndex *= IkConstraintTimeline.ENTRIES;
@ -612,15 +736,21 @@ module spine {
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;
if (time < frames[0]) return; // Time is before first frame.
let constraint: IkConstraint = skeleton.ikConstraints[this.ikConstraintIndex];
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;
}
@ -631,8 +761,13 @@ module spine {
let percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1,
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);
}
getPropertyId () {
return (TimelineType.transformConstraint << 24) + this.transformConstraintIndex;
}
/** Sets the time and mixes of the specified keyframe. */
setFrame (frameIndex: number, time: number, rotateMix: number, translateMix: number, scaleMix: number, shearMix: number) {
frameIndex *= TransformConstraintTimeline.ENTRIES;
@ -659,36 +798,47 @@ module spine {
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;
if (time < frames[0]) return; // Time is before first frame.
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.
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));
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;
}
// 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;
}
}
@ -706,6 +856,10 @@ module spine {
this.frames = Utils.newFloatArray(frameCount * PathConstraintPositionTimeline.ENTRIES);
}
getPropertyId () {
return (TimelineType.pathConstraintPosition << 24) + this.pathConstraintIndex;
}
/** Sets the time and value of the specified keyframe. */
setFrame (frameIndex: number, time: number, value: number) {
frameIndex *= PathConstraintPositionTimeline.ENTRIES;
@ -713,26 +867,29 @@ module spine {
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;
if (time < frames[0]) return; // Time is before first frame.
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;
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));
position += (frames[frame + PathConstraintPositionTimeline.VALUE] - position) * percent;
}
// 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));
constraint.position += (position + (frames[frame + PathConstraintPositionTimeline.VALUE] - position) * percent - constraint.position) * alpha;
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);
}
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;
if (time < frames[0]) return; // Time is before first frame.
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));
spacing += (frames[frame + PathConstraintSpacingTimeline.VALUE] - spacing) * percent;
}
// 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));
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);
}
getPropertyId () {
return (TimelineType.pathConstraintMix << 24) + this.pathConstraintIndex;
}
/** Sets the time and mixes of the specified keyframe. */
setFrame (frameIndex: number, time: number, rotateMix: number, translateMix: number) {
frameIndex *= PathConstraintMixTimeline.ENTRIES;
@ -786,30 +955,36 @@ module spine {
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;
if (time < frames[0]) return; // Time is before first frame.
let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex];
let rotate = 0, translate = 0;
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));
rotate += (frames[frame + PathConstraintMixTimeline.ROTATE] - rotate) * percent;
translate += (frames[frame + PathConstraintMixTimeline.TRANSLATE] - translate) * percent;
}
// 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));
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;
}
}
}
}

View File

@ -30,104 +30,291 @@
module spine {
export class AnimationState {
static emptyAnimation = new Animation("<empty>", [], 0);
data: AnimationStateData;
tracks = new Array<TrackEntry>();
events = new Array<Event>();
listeners = new Array<AnimationStateListener>();
listeners = new Array<AnimationStateListener2>();
queue = new EventQueue(this);
propertyIDs = new IntSet();
animationsChanged = false;
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;
}
update (delta: number) {
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;
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;
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) {
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);
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) {
if (skeleton == null) throw new Error("skeleton cannot be null.");
if (this.animationsChanged) this._animationsChanged();
let events = this.events;
let listenerCount = this.listeners.length;
let tracks = this.tracks;
for (let i = 0; i < this.tracks.length; i++) {
let current = this.tracks[i];
if (current == null) continue;
for (let i = 0, n = tracks.length; i < n; i++) {
let current = tracks[i];
if (current == null || current.delay > 0) continue;
events.length = 0;
// Apply mixing from entries first.
let mix = current.alpha;
if (current.mixingFrom != null) mix = this.applyMixingFrom(current, skeleton, mix);
let time = current.time;
let lastTime = current.lastTime;
let endTime = current.endTime;
let loop = current.loop;
if (!loop && time > endTime) time = endTime;
// 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 previous = current.previous;
if (previous == null)
current.animation.mix(skeleton, lastTime, time, loop, events, current.mix);
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;
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);
}
current.animation.mix(skeleton, lastTime, time, loop, events, alpha);
}
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);
}
// 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);
}
current.lastTime = current.time;
this.queueEvents(current, animationTime);
current.nextAnimationLast = animationTime;
current.nextTrackLast = current.trackTime;
}
this.queue.drain();
}
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 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 {
if (!setupPose) {
if (!attachments && timeline instanceof AttachmentTimeline) continue;
if (!drawOrder && timeline instanceof DrawOrderTimeline) continue;
}
timeline.apply(skeleton, animationLast, animationTime, events, alpha, setupPose, true);
}
}
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;
}
// 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;
// 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 () {
this.queue.drainDisabled = true;
for (let i = 0, n = this.tracks.length; i < n; i++)
this.clearTrack(i);
this.tracks.length = 0;
this.queue.drainDisabled = false;
this.queue.drain();
}
clearTrack (trackIndex: number) {
@ -135,126 +322,235 @@ module spine {
let current = this.tracks[trackIndex];
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;
}
}
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;
}
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;
}
let entry = current;
while (true) {
let from = entry.mixingFrom;
if (from == null) break;
this.queue.end(from);
entry.mixingFrom = null;
entry = from;
}
this.tracks[index] = entry;
this.tracks[current.trackIndex] = null;
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.drain();
}
/** @see #setAnimation(int, Animation, boolean) */
setAnimation (trackIndex: number, animationName: string, loop: boolean) {
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;
// 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);
}
this.queue.start(current);
}
setAnimationByName (trackIndex: number, animationName: string, loop: boolean) {
let animation = this.data.skeletonData.findAnimation(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);
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.queue.drain();
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);
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);
if (last != null) {
while (last.next != null)
last = last.next;
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;
}
entry.delay = delay;
let entry = this.trackEntry(trackIndex, animation, loop, last);
if (last == null) {
this.setCurrent(trackIndex, entry);
this.queue.drain();
} else {
last.next = entry;
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;
return entry;
}
/** @return May be null. */
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;
}
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) {
if (trackIndex >= this.tracks.length) return null;
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.");
this.listeners.push(listener);
}
/** Removes the listener added with {@link #addListener(AnimationStateListener)}. */
removeListener (listener: AnimationStateListener) {
removeListener (listener: AnimationStateListener2) {
let index = this.listeners.indexOf(listener);
if (index >= 0) this.listeners.splice(index, 1);
}
@ -262,59 +558,193 @@ module spine {
clearListeners () {
this.listeners.length = 0;
}
clearListenerNotifications () {
this.queue.clear();
}
}
export class TrackEntry {
next: TrackEntry; previous: TrackEntry;
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 () {
this.next = null;
this.previous = null;
this.mixingFrom = null;
this.animation = 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;
}
complete (trackIndex: number, loopCount: number) {
start (entry: TrackEntry) {
this.objects.push(EventType.start);
this.objects.push(entry);
this.animState.animationsChanged = true;
}
start (trackIndex: number) {
interrupt (entry: TrackEntry) {
this.objects.push(EventType.interrupt);
this.objects.push(entry);
}
end (trackIndex: number) {
end (entry: TrackEntry) {
this.objects.push(EventType.end);
this.objects.push(entry);
this.animState.animationsChanged = true;
}
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;
}
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
}
/** Invoked when the current animation has completed.
* @param loopCount The number of times the animation reached the end. */
complete (trackIndex: number, loopCount: number): void;
export interface AnimationStateListener2 {
/** Invoked when this entry has been set as the current entry. */
start (entry: TrackEntry): void;
/** Invoked just after the current animation is set. */
start (trackIndex: number): 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 just before the current animation is replaced. */
end (trackIndex: number): void;
/** Invoked when this entry is no longer the current entry and will never be applied again. */
end (entry: TrackEntry): 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 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) {
}
}
}

View File

@ -33,6 +33,28 @@ module spine {
[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 {
dispose (): void;
}
@ -153,6 +175,11 @@ module spine {
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> {
let array = new Array<T>(size);
for (let i = 0; i < size; i++) array[i] = defaultValue;
@ -196,11 +223,15 @@ module spine {
}
free (item: T) {
if ((item as any).reset) (item as any).reset();
this.items.push(item);
}
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 () {

View File

@ -143,7 +143,7 @@ module spine {
}
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);
this.loaded = true;
requestAnimationFrame(() => { this.render(); });
@ -246,7 +246,7 @@ module spine {
setAnimation (animationName: string) {
if (!this.loaded) throw new Error("Widget isn't loaded yet");
this.skeleton.setToSetupPose();
this.state.setAnimation(0, animationName, this.config.loop);
this.state.setAnimationByName(0, animationName, this.config.loop);
}