[ts] Ported additive animation blending, see #1029.

This commit is contained in:
badlogic 2017-10-30 13:31:36 +01:00
parent 2d2344d32c
commit f750b3f708
6 changed files with 10864 additions and 10602 deletions

View File

@ -4,18 +4,19 @@ declare module spine {
timelines: Array<Timeline>; timelines: Array<Timeline>;
duration: number; duration: number;
constructor(name: string, timelines: Array<Timeline>, duration: number); constructor(name: string, timelines: Array<Timeline>, duration: number);
apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
static binarySearch(values: ArrayLike<number>, target: number, step?: number): number; static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
static linearSearch(values: ArrayLike<number>, target: number, step: number): number; static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
} }
interface Timeline { interface Timeline {
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
getPropertyId(): number; getPropertyId(): number;
} }
enum MixPose { enum MixBlend {
setup = 0, setup = 0,
current = 1, first = 1,
currentLayered = 2, replace = 2,
add = 3,
} }
enum MixDirection { enum MixDirection {
in = 0, in = 0,
@ -52,7 +53,7 @@ declare module spine {
getCurveType(frameIndex: number): number; getCurveType(frameIndex: number): number;
setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void; setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
getCurvePercent(frameIndex: number, percent: number): number; getCurvePercent(frameIndex: number, percent: number): number;
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class RotateTimeline extends CurveTimeline { class RotateTimeline extends CurveTimeline {
static ENTRIES: number; static ENTRIES: number;
@ -64,7 +65,7 @@ declare module spine {
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
setFrame(frameIndex: number, time: number, degrees: number): void; setFrame(frameIndex: number, time: number, degrees: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class TranslateTimeline extends CurveTimeline { class TranslateTimeline extends CurveTimeline {
static ENTRIES: number; static ENTRIES: number;
@ -78,17 +79,17 @@ declare module spine {
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
setFrame(frameIndex: number, time: number, x: number, y: number): void; setFrame(frameIndex: number, time: number, x: number, y: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class ScaleTimeline extends TranslateTimeline { class ScaleTimeline extends TranslateTimeline {
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class ShearTimeline extends TranslateTimeline { class ShearTimeline extends TranslateTimeline {
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class ColorTimeline extends CurveTimeline { class ColorTimeline extends CurveTimeline {
static ENTRIES: number; static ENTRIES: number;
@ -106,7 +107,7 @@ declare module spine {
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
setFrame(frameIndex: number, time: number, r: number, g: number, b: number, a: number): void; setFrame(frameIndex: number, time: number, r: number, g: number, b: number, a: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class TwoColorTimeline extends CurveTimeline { class TwoColorTimeline extends CurveTimeline {
static ENTRIES: number; static ENTRIES: number;
@ -130,7 +131,7 @@ declare module spine {
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
setFrame(frameIndex: number, time: number, r: number, g: number, b: number, a: number, r2: number, g2: number, b2: number): void; setFrame(frameIndex: number, time: number, r: number, g: number, b: number, a: number, r2: number, g2: number, b2: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class AttachmentTimeline implements Timeline { class AttachmentTimeline implements Timeline {
slotIndex: number; slotIndex: number;
@ -140,7 +141,7 @@ declare module spine {
getPropertyId(): number; getPropertyId(): number;
getFrameCount(): number; getFrameCount(): number;
setFrame(frameIndex: number, time: number, attachmentName: string): void; setFrame(frameIndex: number, time: number, attachmentName: string): void;
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class DeformTimeline extends CurveTimeline { class DeformTimeline extends CurveTimeline {
slotIndex: number; slotIndex: number;
@ -150,7 +151,7 @@ declare module spine {
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void; setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class EventTimeline implements Timeline { class EventTimeline implements Timeline {
frames: ArrayLike<number>; frames: ArrayLike<number>;
@ -159,7 +160,7 @@ declare module spine {
getPropertyId(): number; getPropertyId(): number;
getFrameCount(): number; getFrameCount(): number;
setFrame(frameIndex: number, event: Event): void; setFrame(frameIndex: number, event: Event): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class DrawOrderTimeline implements Timeline { class DrawOrderTimeline implements Timeline {
frames: ArrayLike<number>; frames: ArrayLike<number>;
@ -168,7 +169,7 @@ declare module spine {
getPropertyId(): number; getPropertyId(): number;
getFrameCount(): number; getFrameCount(): number;
setFrame(frameIndex: number, time: number, drawOrder: Array<number>): void; setFrame(frameIndex: number, time: number, drawOrder: Array<number>): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class IkConstraintTimeline extends CurveTimeline { class IkConstraintTimeline extends CurveTimeline {
static ENTRIES: number; static ENTRIES: number;
@ -182,7 +183,7 @@ declare module spine {
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void; setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class TransformConstraintTimeline extends CurveTimeline { class TransformConstraintTimeline extends CurveTimeline {
static ENTRIES: number; static ENTRIES: number;
@ -200,7 +201,7 @@ declare module spine {
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number, scaleMix: number, shearMix: number): void; setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number, scaleMix: number, shearMix: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class PathConstraintPositionTimeline extends CurveTimeline { class PathConstraintPositionTimeline extends CurveTimeline {
static ENTRIES: number; static ENTRIES: number;
@ -212,12 +213,12 @@ declare module spine {
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
setFrame(frameIndex: number, time: number, value: number): void; setFrame(frameIndex: number, time: number, value: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline { class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class PathConstraintMixTimeline extends CurveTimeline { class PathConstraintMixTimeline extends CurveTimeline {
static ENTRIES: number; static ENTRIES: number;
@ -231,7 +232,7 @@ declare module spine {
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void; setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
} }
declare module spine { declare module spine {
@ -255,8 +256,8 @@ declare module spine {
update(delta: number): void; update(delta: number): void;
updateMixingFrom(to: TrackEntry, delta: number): boolean; updateMixingFrom(to: TrackEntry, delta: number): boolean;
apply(skeleton: Skeleton): boolean; apply(skeleton: Skeleton): boolean;
applyMixingFrom(to: TrackEntry, skeleton: Skeleton, currentPose: MixPose): number; applyMixingFrom(to: TrackEntry, skeleton: Skeleton, blend: MixBlend): number;
applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, pose: MixPose, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void; applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, blend: MixBlend, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
queueEvents(entry: TrackEntry, animationTime: number): void; queueEvents(entry: TrackEntry, animationTime: number): void;
clearTracks(): void; clearTracks(): void;
clearTrack(trackIndex: number): void; clearTrack(trackIndex: number): void;
@ -303,6 +304,7 @@ declare module spine {
mixDuration: number; mixDuration: number;
interruptAlpha: number; interruptAlpha: number;
totalAlpha: number; totalAlpha: number;
mixBlend: MixBlend;
timelineData: number[]; timelineData: number[];
timelineDipMix: TrackEntry[]; timelineDipMix: TrackEntry[];
timelinesRotation: number[]; timelinesRotation: number[];
@ -399,156 +401,6 @@ declare module spine {
newClippingAttachment(skin: Skin, name: string): ClippingAttachment; newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
} }
} }
declare module spine {
abstract class Attachment {
name: string;
constructor(name: string);
}
abstract class VertexAttachment extends Attachment {
private static nextID;
id: number;
bones: Array<number>;
vertices: ArrayLike<number>;
worldVerticesLength: number;
constructor(name: string);
computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
applyDeform(sourceAttachment: VertexAttachment): boolean;
}
}
declare module spine {
interface AttachmentLoader {
newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
newPathAttachment(skin: Skin, name: string): PathAttachment;
newPointAttachment(skin: Skin, name: string): PointAttachment;
newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
}
}
declare module spine {
enum AttachmentType {
Region = 0,
BoundingBox = 1,
Mesh = 2,
LinkedMesh = 3,
Path = 4,
Point = 5,
}
}
declare module spine {
class BoundingBoxAttachment extends VertexAttachment {
color: Color;
constructor(name: string);
}
}
declare module spine {
class ClippingAttachment extends VertexAttachment {
endSlot: SlotData;
color: Color;
constructor(name: string);
}
}
declare module spine {
class MeshAttachment extends VertexAttachment {
region: TextureRegion;
path: string;
regionUVs: ArrayLike<number>;
uvs: ArrayLike<number>;
triangles: Array<number>;
color: Color;
hullLength: number;
private parentMesh;
inheritDeform: boolean;
tempColor: Color;
constructor(name: string);
updateUVs(): void;
applyDeform(sourceAttachment: VertexAttachment): boolean;
getParentMesh(): MeshAttachment;
setParentMesh(parentMesh: MeshAttachment): void;
}
}
declare module spine {
class PathAttachment extends VertexAttachment {
lengths: Array<number>;
closed: boolean;
constantSpeed: boolean;
color: Color;
constructor(name: string);
}
}
declare module spine {
class PointAttachment extends VertexAttachment {
x: number;
y: number;
rotation: number;
color: Color;
constructor(name: string);
computeWorldPosition(bone: Bone, point: Vector2): Vector2;
computeWorldRotation(bone: Bone): number;
}
}
declare module spine {
class RegionAttachment extends Attachment {
static OX1: number;
static OY1: number;
static OX2: number;
static OY2: number;
static OX3: number;
static OY3: number;
static OX4: number;
static OY4: number;
static X1: number;
static Y1: number;
static C1R: number;
static C1G: number;
static C1B: number;
static C1A: number;
static U1: number;
static V1: number;
static X2: number;
static Y2: number;
static C2R: number;
static C2G: number;
static C2B: number;
static C2A: number;
static U2: number;
static V2: number;
static X3: number;
static Y3: number;
static C3R: number;
static C3G: number;
static C3B: number;
static C3A: number;
static U3: number;
static V3: number;
static X4: number;
static Y4: number;
static C4R: number;
static C4G: number;
static C4B: number;
static C4A: number;
static U4: number;
static V4: number;
x: number;
y: number;
scaleX: number;
scaleY: number;
rotation: number;
width: number;
height: number;
color: Color;
path: string;
rendererObject: any;
region: TextureRegion;
offset: ArrayLike<number>;
uvs: ArrayLike<number>;
tempColor: Color;
constructor(name: string);
updateOffset(): void;
setRegion(region: TextureRegion): void;
computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
}
}
declare module spine { declare module spine {
enum BlendMode { enum BlendMode {
Normal = 0, Normal = 0,
@ -1196,6 +1048,156 @@ declare module spine {
end(): void; end(): void;
} }
} }
declare module spine {
abstract class Attachment {
name: string;
constructor(name: string);
}
abstract class VertexAttachment extends Attachment {
private static nextID;
id: number;
bones: Array<number>;
vertices: ArrayLike<number>;
worldVerticesLength: number;
constructor(name: string);
computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
applyDeform(sourceAttachment: VertexAttachment): boolean;
}
}
declare module spine {
interface AttachmentLoader {
newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
newPathAttachment(skin: Skin, name: string): PathAttachment;
newPointAttachment(skin: Skin, name: string): PointAttachment;
newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
}
}
declare module spine {
enum AttachmentType {
Region = 0,
BoundingBox = 1,
Mesh = 2,
LinkedMesh = 3,
Path = 4,
Point = 5,
}
}
declare module spine {
class BoundingBoxAttachment extends VertexAttachment {
color: Color;
constructor(name: string);
}
}
declare module spine {
class ClippingAttachment extends VertexAttachment {
endSlot: SlotData;
color: Color;
constructor(name: string);
}
}
declare module spine {
class MeshAttachment extends VertexAttachment {
region: TextureRegion;
path: string;
regionUVs: ArrayLike<number>;
uvs: ArrayLike<number>;
triangles: Array<number>;
color: Color;
hullLength: number;
private parentMesh;
inheritDeform: boolean;
tempColor: Color;
constructor(name: string);
updateUVs(): void;
applyDeform(sourceAttachment: VertexAttachment): boolean;
getParentMesh(): MeshAttachment;
setParentMesh(parentMesh: MeshAttachment): void;
}
}
declare module spine {
class PathAttachment extends VertexAttachment {
lengths: Array<number>;
closed: boolean;
constantSpeed: boolean;
color: Color;
constructor(name: string);
}
}
declare module spine {
class PointAttachment extends VertexAttachment {
x: number;
y: number;
rotation: number;
color: Color;
constructor(name: string);
computeWorldPosition(bone: Bone, point: Vector2): Vector2;
computeWorldRotation(bone: Bone): number;
}
}
declare module spine {
class RegionAttachment extends Attachment {
static OX1: number;
static OY1: number;
static OX2: number;
static OY2: number;
static OX3: number;
static OY3: number;
static OX4: number;
static OY4: number;
static X1: number;
static Y1: number;
static C1R: number;
static C1G: number;
static C1B: number;
static C1A: number;
static U1: number;
static V1: number;
static X2: number;
static Y2: number;
static C2R: number;
static C2G: number;
static C2B: number;
static C2A: number;
static U2: number;
static V2: number;
static X3: number;
static Y3: number;
static C3R: number;
static C3G: number;
static C3B: number;
static C3A: number;
static U3: number;
static V3: number;
static X4: number;
static Y4: number;
static C4R: number;
static C4G: number;
static C4B: number;
static C4A: number;
static U4: number;
static V4: number;
x: number;
y: number;
scaleX: number;
scaleY: number;
rotation: number;
width: number;
height: number;
color: Color;
path: string;
rendererObject: any;
region: TextureRegion;
offset: ArrayLike<number>;
uvs: ArrayLike<number>;
tempColor: Color;
constructor(name: string);
updateOffset(): void;
setRegion(region: TextureRegion): void;
computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
}
}
declare module spine { declare module spine {
class JitterEffect implements VertexEffect { class JitterEffect implements VertexEffect {
jitterX: number; jitterX: number;
@ -1312,22 +1314,22 @@ declare module spine.webgl {
} }
} }
declare module spine.webgl { declare module spine.webgl {
const M00: number; const M00 = 0;
const M01: number; const M01 = 4;
const M02: number; const M02 = 8;
const M03: number; const M03 = 12;
const M10: number; const M10 = 1;
const M11: number; const M11 = 5;
const M12: number; const M12 = 9;
const M13: number; const M13 = 13;
const M20: number; const M20 = 2;
const M21: number; const M21 = 6;
const M22: number; const M22 = 10;
const M23: number; const M23 = 14;
const M30: number; const M30 = 3;
const M31: number; const M31 = 7;
const M32: number; const M32 = 11;
const M33: number; const M33 = 15;
class Matrix4 { class Matrix4 {
temp: Float32Array; temp: Float32Array;
values: Float32Array; values: 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; this.duration = duration;
} }
apply (skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
if (skeleton == null) throw new Error("skeleton cannot be null."); if (skeleton == null) throw new Error("skeleton cannot be null.");
if (loop && this.duration != 0) { if (loop && this.duration != 0) {
@ -52,7 +52,7 @@ module spine {
let timelines = this.timelines; let timelines = this.timelines;
for (let i = 0, n = timelines.length; i < n; i++) for (let i = 0, n = timelines.length; i < n; i++)
timelines[i].apply(skeleton, lastTime, time, events, alpha, pose, direction); timelines[i].apply(skeleton, lastTime, time, events, alpha, blend, direction);
} }
static binarySearch (values: ArrayLike<number>, target: number, step: number = 1) { static binarySearch (values: ArrayLike<number>, target: number, step: number = 1) {
@ -78,14 +78,15 @@ module spine {
} }
export interface Timeline { export interface Timeline {
apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
getPropertyId (): number; getPropertyId (): number;
} }
export enum MixPose { export enum MixBlend {
setup, setup,
current, first,
currentLayered replace,
add
} }
export enum MixDirection { export enum MixDirection {
@ -188,7 +189,7 @@ module spine {
return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1. return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1.
} }
abstract apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection): void; abstract apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
export class RotateTimeline extends CurveTimeline { export class RotateTimeline extends CurveTimeline {
@ -215,29 +216,33 @@ module spine {
this.frames[frameIndex + RotateTimeline.ROTATION] = degrees; this.frames[frameIndex + RotateTimeline.ROTATION] = degrees;
} }
apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let frames = this.frames; let frames = this.frames;
let bone = skeleton.bones[this.boneIndex]; let bone = skeleton.bones[this.boneIndex];
if (time < frames[0]) { if (time < frames[0]) {
switch (pose) { switch (blend) {
case MixPose.setup: case MixBlend.setup:
bone.rotation = bone.data.rotation; bone.rotation = bone.data.rotation;
return; return;
case MixPose.current: case MixBlend.first:
let r = bone.data.rotation - bone.rotation; let r = bone.data.rotation - bone.rotation;
r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; bone.rotation += (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha;
bone.rotation += r * alpha;
} }
return; return;
} }
if (time >= frames[frames.length - RotateTimeline.ENTRIES]) { // Time is after last frame. if (time >= frames[frames.length - RotateTimeline.ENTRIES]) { // Time is after last frame.
if (pose == MixPose.setup) var r = frames[frames.length + RotateTimeline.PREV_ROTATION];
bone.rotation = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION] * alpha; switch (blend) {
else { case MixBlend.setup:
let r = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION] - bone.rotation; bone.rotation = bone.data.rotation + r * alpha;
break;
case MixBlend.first:
case MixBlend.replace:
r += bone.data.rotation - bone.rotation;
r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; // Wrap within -180 and 180. r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; // Wrap within -180 and 180.
case MixBlend.add:
bone.rotation += r * alpha; bone.rotation += r * alpha;
} }
return; return;
@ -250,16 +255,17 @@ module spine {
let percent = this.getCurvePercent((frame >> 1) - 1, let percent = this.getCurvePercent((frame >> 1) - 1,
1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime)); 1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime));
let r = frames[frame + RotateTimeline.ROTATION] - prevRotation; r = frames[frame + RotateTimeline.ROTATION] - prevRotation;
r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; r = prevRotation + (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * percent;
r = prevRotation + r * percent; switch (blend) {
if (pose == MixPose.setup) { case MixBlend.setup:
r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; bone.rotation = bone.data.rotation + (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha;
bone.rotation = bone.data.rotation + r * alpha; break;
} else { case MixBlend.first:
r = bone.data.rotation + r - bone.rotation; case MixBlend.replace:
r -= (16384 - ((16384.499999999996 - r / 360) |0)) * 360; r += bone.data.rotation - bone.rotation;
bone.rotation += r * alpha; case MixBlend.add:
bone.rotation += (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha;
} }
} }
} }
@ -289,17 +295,17 @@ module spine {
this.frames[frameIndex + TranslateTimeline.Y] = y; this.frames[frameIndex + TranslateTimeline.Y] = y;
} }
apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let frames = this.frames; let frames = this.frames;
let bone = skeleton.bones[this.boneIndex]; let bone = skeleton.bones[this.boneIndex];
if (time < frames[0]) { if (time < frames[0]) {
switch (pose) { switch (blend) {
case MixPose.setup: case MixBlend.setup:
bone.x = bone.data.x; bone.x = bone.data.x;
bone.y = bone.data.y; bone.y = bone.data.y;
return; return;
case MixPose.current: case MixBlend.first:
bone.x += (bone.data.x - bone.x) * alpha; bone.x += (bone.data.x - bone.x) * alpha;
bone.y += (bone.data.y - bone.y) * alpha; bone.y += (bone.data.y - bone.y) * alpha;
} }
@ -322,12 +328,19 @@ module spine {
x += (frames[frame + TranslateTimeline.X] - x) * percent; x += (frames[frame + TranslateTimeline.X] - x) * percent;
y += (frames[frame + TranslateTimeline.Y] - y) * percent; y += (frames[frame + TranslateTimeline.Y] - y) * percent;
} }
if (pose == MixPose.setup) { switch (blend) {
case MixBlend.setup:
bone.x = bone.data.x + x * alpha; bone.x = bone.data.x + x * alpha;
bone.y = bone.data.y + y * alpha; bone.y = bone.data.y + y * alpha;
} else { break;
case MixBlend.first:
case MixBlend.replace:
bone.x += (bone.data.x + x - bone.x) * alpha; bone.x += (bone.data.x + x - bone.x) * alpha;
bone.y += (bone.data.y + y - bone.y) * alpha; bone.y += (bone.data.y + y - bone.y) * alpha;
break;
case MixBlend.add:
bone.x += x * alpha;
bone.y += y * alpha;
} }
} }
} }
@ -341,17 +354,17 @@ module spine {
return (TimelineType.scale << 24) + this.boneIndex; return (TimelineType.scale << 24) + this.boneIndex;
} }
apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let frames = this.frames; let frames = this.frames;
let bone = skeleton.bones[this.boneIndex]; let bone = skeleton.bones[this.boneIndex];
if (time < frames[0]) { if (time < frames[0]) {
switch (pose) { switch (blend) {
case MixPose.setup: case MixBlend.setup:
bone.scaleX = bone.data.scaleX; bone.scaleX = bone.data.scaleX;
bone.scaleY = bone.data.scaleY; bone.scaleY = bone.data.scaleY;
return; return;
case MixPose.current: case MixBlend.first:
bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha; bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha;
bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha; bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha;
} }
@ -375,27 +388,56 @@ module spine {
y = (y + (frames[frame + ScaleTimeline.Y] - y) * percent) * bone.data.scaleY; y = (y + (frames[frame + ScaleTimeline.Y] - y) * percent) * bone.data.scaleY;
} }
if (alpha == 1) { if (alpha == 1) {
if (blend == MixBlend.add) {
bone.scaleX += x - bone.data.scaleX;
bone.scaleY += y - bone.data.scaleY;
} else {
bone.scaleX = x; bone.scaleX = x;
bone.scaleY = y; bone.scaleY = y;
}
} else { } else {
let bx = 0, by = 0; let bx = 0, by = 0;
if (pose == MixPose.setup) { if (direction == MixDirection.out) {
switch (blend) {
case MixBlend.setup:
bx = bone.data.scaleX; bx = bone.data.scaleX;
by = bone.data.scaleY; by = bone.data.scaleY;
} else { bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha;
bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha;
break;
case MixBlend.first:
case MixBlend.replace:
bx = bone.scaleX; bx = bone.scaleX;
by = bone.scaleY; by = bone.scaleY;
bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bx) * alpha;
bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - by) * alpha;
break;
case MixBlend.add:
bx = bone.scaleX;
by = bone.scaleY;
bone.scaleX = bx + (Math.abs(x) * MathUtils.signum(bx) - bone.data.scaleX) * alpha;
bone.scaleY = by + (Math.abs(y) * MathUtils.signum(by) - bone.data.scaleY) * alpha;
} }
// Mixing out uses sign of setup or current pose, else use sign of key.
if (direction == MixDirection.out) {
x = Math.abs(x) * MathUtils.signum(bx);
y = Math.abs(y) * MathUtils.signum(by);
} else { } else {
bx = Math.abs(bx) * MathUtils.signum(x); switch (blend) {
by = Math.abs(by) * MathUtils.signum(y); case MixBlend.setup:
} bx = Math.abs(bone.data.scaleX) * MathUtils.signum(x);
by = Math.abs(bone.data.scaleY) * MathUtils.signum(y);
bone.scaleX = bx + (x - bx) * alpha; bone.scaleX = bx + (x - bx) * alpha;
bone.scaleY = by + (y - by) * alpha; bone.scaleY = by + (y - by) * alpha;
break;
case MixBlend.first:
case MixBlend.replace:
bone.scaleX += (x - bone.scaleX * MathUtils.signum(x)) * alpha;
bone.scaleY += (y - bone.scaleY * MathUtils.signum(y)) * alpha;
break;
case MixBlend.add:
bx = MathUtils.signum(x);
by = MathUtils.signum(y);
bone.scaleX = Math.abs(bone.scaleX) * bx + (x - Math.abs(bone.data.scaleX) * bx) * alpha;
bone.scaleY = Math.abs(bone.scaleY) * by + (y - Math.abs(bone.data.scaleY) * by) * alpha;
}
}
} }
} }
} }
@ -409,17 +451,17 @@ module spine {
return (TimelineType.shear << 24) + this.boneIndex; return (TimelineType.shear << 24) + this.boneIndex;
} }
apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let frames = this.frames; let frames = this.frames;
let bone = skeleton.bones[this.boneIndex]; let bone = skeleton.bones[this.boneIndex];
if (time < frames[0]) { if (time < frames[0]) {
switch (pose) { switch (blend) {
case MixPose.setup: case MixBlend.setup:
bone.shearX = bone.data.shearX; bone.shearX = bone.data.shearX;
bone.shearY = bone.data.shearY; bone.shearY = bone.data.shearY;
return; return;
case MixPose.current: case MixBlend.first:
bone.shearX += (bone.data.shearX - bone.shearX) * alpha; bone.shearX += (bone.data.shearX - bone.shearX) * alpha;
bone.shearY += (bone.data.shearY - bone.shearY) * alpha; bone.shearY += (bone.data.shearY - bone.shearY) * alpha;
} }
@ -442,12 +484,19 @@ module spine {
x = x + (frames[frame + ShearTimeline.X] - x) * percent; x = x + (frames[frame + ShearTimeline.X] - x) * percent;
y = y + (frames[frame + ShearTimeline.Y] - y) * percent; y = y + (frames[frame + ShearTimeline.Y] - y) * percent;
} }
if (pose == MixPose.setup) { switch (blend) {
case MixBlend.setup:
bone.shearX = bone.data.shearX + x * alpha; bone.shearX = bone.data.shearX + x * alpha;
bone.shearY = bone.data.shearY + y * alpha; bone.shearY = bone.data.shearY + y * alpha;
} else { break;
case MixBlend.first:
case MixBlend.replace:
bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha; bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha;
bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha; bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha;
break;
case MixBlend.add:
bone.shearX += x * alpha;
bone.shearY += y * alpha;
} }
} }
} }
@ -479,15 +528,15 @@ module spine {
this.frames[frameIndex + ColorTimeline.A] = a; this.frames[frameIndex + ColorTimeline.A] = a;
} }
apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let slot = skeleton.slots[this.slotIndex]; let slot = skeleton.slots[this.slotIndex];
let frames = this.frames; let frames = this.frames;
if (time < frames[0]) { if (time < frames[0]) {
switch (pose) { switch (blend) {
case MixPose.setup: case MixBlend.setup:
slot.color.setFromColor(slot.data.color); slot.color.setFromColor(slot.data.color);
return; return;
case MixPose.current: case MixBlend.first:
let color = slot.color, setup = slot.data.color; let color = slot.color, setup = slot.data.color;
color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha, color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha,
(setup.a - color.a) * alpha); (setup.a - color.a) * alpha);
@ -522,7 +571,7 @@ module spine {
slot.color.set(r, g, b, a); slot.color.set(r, g, b, a);
else { else {
let color = slot.color; let color = slot.color;
if (pose == MixPose.setup) color.setFromColor(slot.data.color); if (blend == MixBlend.setup) color.setFromColor(slot.data.color);
color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha); color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha);
} }
} }
@ -559,16 +608,16 @@ module spine {
this.frames[frameIndex + TwoColorTimeline.B2] = b2; this.frames[frameIndex + TwoColorTimeline.B2] = b2;
} }
apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let slot = skeleton.slots[this.slotIndex]; let slot = skeleton.slots[this.slotIndex];
let frames = this.frames; let frames = this.frames;
if (time < frames[0]) { if (time < frames[0]) {
switch (pose) { switch (blend) {
case MixPose.setup: case MixBlend.setup:
slot.color.setFromColor(slot.data.color); slot.color.setFromColor(slot.data.color);
slot.darkColor.setFromColor(slot.data.darkColor); slot.darkColor.setFromColor(slot.data.darkColor);
return; return;
case MixPose.current: case MixBlend.setup:
let light = slot.color, dark = slot.darkColor, setupLight = slot.data.color, setupDark = slot.data.darkColor; let light = slot.color, dark = slot.darkColor, setupLight = slot.data.color, setupDark = slot.data.darkColor;
light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha, light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha,
(setupLight.a - light.a) * alpha); (setupLight.a - light.a) * alpha);
@ -614,7 +663,7 @@ module spine {
slot.darkColor.set(r2, g2, b2, 1); slot.darkColor.set(r2, g2, b2, 1);
} else { } else {
let light = slot.color, dark = slot.darkColor; let light = slot.color, dark = slot.darkColor;
if (pose == MixPose.setup) { if (blend == MixBlend.setup) {
light.setFromColor(slot.data.color); light.setFromColor(slot.data.color);
dark.setFromColor(slot.data.darkColor); dark.setFromColor(slot.data.darkColor);
} }
@ -648,9 +697,9 @@ module spine {
this.attachmentNames[frameIndex] = attachmentName; this.attachmentNames[frameIndex] = attachmentName;
} }
apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let slot = skeleton.slots[this.slotIndex]; let slot = skeleton.slots[this.slotIndex];
if (direction == MixDirection.out && pose == MixPose.setup) { if (direction == MixDirection.out && blend == MixBlend.setup) {
let attachmentName = slot.data.attachmentName; let attachmentName = slot.data.attachmentName;
slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName)); slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName));
return; return;
@ -658,7 +707,7 @@ module spine {
let frames = this.frames; let frames = this.frames;
if (time < frames[0]) { if (time < frames[0]) {
if (pose == MixPose.setup) { if (blend == MixBlend.setup) {
let attachmentName = slot.data.attachmentName; let attachmentName = slot.data.attachmentName;
slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName)); slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName));
} }
@ -702,13 +751,13 @@ module spine {
this.frameVertices[frameIndex] = vertices; this.frameVertices[frameIndex] = vertices;
} }
apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let slot: Slot = skeleton.slots[this.slotIndex]; let slot: Slot = skeleton.slots[this.slotIndex];
let slotAttachment: Attachment = slot.getAttachment(); let slotAttachment: Attachment = slot.getAttachment();
if (!(slotAttachment instanceof VertexAttachment) || !(<VertexAttachment>slotAttachment).applyDeform(this.attachment)) return; if (!(slotAttachment instanceof VertexAttachment) || !(<VertexAttachment>slotAttachment).applyDeform(this.attachment)) return;
let verticesArray: Array<number> = slot.attachmentVertices; let verticesArray: Array<number> = slot.attachmentVertices;
if (verticesArray.length == 0) alpha = 1; if (verticesArray.length == 0) blend = MixBlend.setup;
let frameVertices = this.frameVertices; let frameVertices = this.frameVertices;
let vertexCount = frameVertices[0].length; let vertexCount = frameVertices[0].length;
@ -716,11 +765,11 @@ module spine {
let frames = this.frames; let frames = this.frames;
if (time < frames[0]) { if (time < frames[0]) {
let vertexAttachment = <VertexAttachment>slotAttachment; let vertexAttachment = <VertexAttachment>slotAttachment;
switch (pose) { switch (blend) {
case MixPose.setup: case MixBlend.setup:
verticesArray.length = 0; verticesArray.length = 0;
return; return;
case MixPose.current: case MixBlend.first:
if (alpha == 1) { if (alpha == 1) {
verticesArray.length = 0; verticesArray.length = 0;
break; break;
@ -745,8 +794,25 @@ module spine {
if (time >= frames[frames.length - 1]) { // Time is after last frame. if (time >= frames[frames.length - 1]) { // Time is after last frame.
let lastVertices = frameVertices[frames.length - 1]; let lastVertices = frameVertices[frames.length - 1];
if (alpha == 1) { if (alpha == 1) {
if (blend == MixBlend.add) {
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++) {
vertices[i] += lastVertices[i] - setupVertices[i];
}
} else {
// Weighted deform offsets, with alpha.
for (let i = 0; i < vertexCount; i++)
vertices[i] += lastVertices[i];
}
} else {
Utils.arrayCopy(lastVertices, 0, vertices, 0, vertexCount); Utils.arrayCopy(lastVertices, 0, vertices, 0, vertexCount);
} else if (pose == MixPose.setup) { }
} else {
switch (blend) {
case MixBlend.setup:
let vertexAttachment = slotAttachment as VertexAttachment; let vertexAttachment = slotAttachment as VertexAttachment;
if (vertexAttachment.bones == null) { if (vertexAttachment.bones == null) {
// Unweighted vertex positions, with alpha. // Unweighted vertex positions, with alpha.
@ -760,9 +826,15 @@ module spine {
for (let i = 0; i < vertexCount; i++) for (let i = 0; i < vertexCount; i++)
vertices[i] = lastVertices[i] * alpha; vertices[i] = lastVertices[i] * alpha;
} }
} else { break;
case MixBlend.first:
case MixBlend.replace:
for (let i = 0; i < vertexCount; i++) for (let i = 0; i < vertexCount; i++)
vertices[i] += (lastVertices[i] - vertices[i]) * alpha; vertices[i] += (lastVertices[i] - vertices[i]) * alpha;
case MixBlend.add:
for (let i = 0; i < vertexCount; i++)
vertices[i] += lastVertices[i] * alpha;
}
} }
return; return;
} }
@ -775,11 +847,31 @@ module spine {
let percent = this.getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime)); let percent = this.getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime));
if (alpha == 1) { if (alpha == 1) {
if (blend == MixBlend.add) {
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];
vertices[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i];
}
} else {
// Weighted deform offsets, with alpha.
for (let i = 0; i < vertexCount; i++) {
let prev = prevVertices[i];
vertices[i] += prev + (nextVertices[i] - prev) * percent;
}
}
} else {
for (let i = 0; i < vertexCount; i++) { for (let i = 0; i < vertexCount; i++) {
let prev = prevVertices[i]; let prev = prevVertices[i];
vertices[i] = prev + (nextVertices[i] - prev) * percent; vertices[i] = prev + (nextVertices[i] - prev) * percent;
} }
} else if (pose == MixPose.setup) { }
} else {
switch (blend) {
case MixBlend.setup: {
let vertexAttachment = slotAttachment as VertexAttachment; let vertexAttachment = slotAttachment as VertexAttachment;
if (vertexAttachment.bones == null) { if (vertexAttachment.bones == null) {
// Unweighted vertex positions, with alpha. // Unweighted vertex positions, with alpha.
@ -795,12 +887,32 @@ module spine {
vertices[i] = (prev + (nextVertices[i] - prev) * percent) * alpha; vertices[i] = (prev + (nextVertices[i] - prev) * percent) * alpha;
} }
} }
} else { break;
// Vertex positions or deform offsets, with alpha. }
case MixBlend.first:
case MixBlend.replace:
for (let i = 0; i < vertexCount; i++) { for (let i = 0; i < vertexCount; i++) {
let prev = prevVertices[i]; let prev = prevVertices[i];
vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha; vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha;
} }
break;
case MixBlend.add:
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];
vertices[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * 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;
}
}
}
} }
} }
} }
@ -829,13 +941,13 @@ module spine {
} }
/** Fires events for frames > lastTime and <= time. */ /** Fires events for frames > lastTime and <= time. */
apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
if (firedEvents == null) return; if (firedEvents == null) return;
let frames = this.frames; let frames = this.frames;
let frameCount = this.frames.length; let frameCount = this.frames.length;
if (lastTime > time) { // Fire events after last time for looped animations. if (lastTime > time) { // Fire events after last time for looped animations.
this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, pose, direction); this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, blend, direction);
lastTime = -1; lastTime = -1;
} else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame. } else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame.
return; return;
@ -881,17 +993,17 @@ module spine {
this.drawOrders[frameIndex] = drawOrder; this.drawOrders[frameIndex] = drawOrder;
} }
apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let drawOrder: Array<Slot> = skeleton.drawOrder; let drawOrder: Array<Slot> = skeleton.drawOrder;
let slots: Array<Slot> = skeleton.slots; let slots: Array<Slot> = skeleton.slots;
if (direction == MixDirection.out && pose == MixPose.setup) { if (direction == MixDirection.out && blend == MixBlend.setup) {
Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);
return; return;
} }
let frames = this.frames; let frames = this.frames;
if (time < frames[0]) { if (time < frames[0]) {
if (pose == MixPose.setup) Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); if (blend == MixBlend.setup) Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);
return; return;
} }
@ -936,16 +1048,16 @@ module spine {
this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection; this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection;
} }
apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let frames = this.frames; let frames = this.frames;
let constraint: IkConstraint = skeleton.ikConstraints[this.ikConstraintIndex]; let constraint: IkConstraint = skeleton.ikConstraints[this.ikConstraintIndex];
if (time < frames[0]) { if (time < frames[0]) {
switch (pose) { switch (blend) {
case MixPose.setup: case MixBlend.setup:
constraint.mix = constraint.data.mix; constraint.mix = constraint.data.mix;
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
return; return;
case MixPose.current: case MixBlend.first:
constraint.mix += (constraint.data.mix - constraint.mix) * alpha; constraint.mix += (constraint.data.mix - constraint.mix) * alpha;
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
} }
@ -953,7 +1065,7 @@ module spine {
} }
if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { // Time is after last frame. if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { // Time is after last frame.
if (pose == MixPose.setup) { if (blend == MixBlend.setup) {
constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha; constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha;
constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection
: frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; : frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
@ -971,7 +1083,7 @@ module spine {
let percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, let percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1,
1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime)); 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime));
if (pose == MixPose.setup) { if (blend == MixBlend.setup) {
constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha; constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha;
constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection : frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection : frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
} else { } else {
@ -1008,20 +1120,20 @@ module spine {
this.frames[frameIndex + TransformConstraintTimeline.SHEAR] = shearMix; this.frames[frameIndex + TransformConstraintTimeline.SHEAR] = shearMix;
} }
apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let frames = this.frames; let frames = this.frames;
let constraint: TransformConstraint = skeleton.transformConstraints[this.transformConstraintIndex]; let constraint: TransformConstraint = skeleton.transformConstraints[this.transformConstraintIndex];
if (time < frames[0]) { if (time < frames[0]) {
let data = constraint.data; let data = constraint.data;
switch (pose) { switch (blend) {
case MixPose.setup: case MixBlend.setup:
constraint.rotateMix = data.rotateMix; constraint.rotateMix = data.rotateMix;
constraint.translateMix = data.translateMix; constraint.translateMix = data.translateMix;
constraint.scaleMix = data.scaleMix; constraint.scaleMix = data.scaleMix;
constraint.shearMix = data.shearMix; constraint.shearMix = data.shearMix;
return; return;
case MixPose.current: case MixBlend.setup:
constraint.rotateMix += (data.rotateMix - constraint.rotateMix) * alpha; constraint.rotateMix += (data.rotateMix - constraint.rotateMix) * alpha;
constraint.translateMix += (data.translateMix - constraint.translateMix) * alpha; constraint.translateMix += (data.translateMix - constraint.translateMix) * alpha;
constraint.scaleMix += (data.scaleMix - constraint.scaleMix) * alpha; constraint.scaleMix += (data.scaleMix - constraint.scaleMix) * alpha;
@ -1053,7 +1165,7 @@ module spine {
scale += (frames[frame + TransformConstraintTimeline.SCALE] - scale) * percent; scale += (frames[frame + TransformConstraintTimeline.SCALE] - scale) * percent;
shear += (frames[frame + TransformConstraintTimeline.SHEAR] - shear) * percent; shear += (frames[frame + TransformConstraintTimeline.SHEAR] - shear) * percent;
} }
if (pose == MixPose.setup) { if (blend == MixBlend.setup) {
let data = constraint.data; let data = constraint.data;
constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha; constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha;
constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha; constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha;
@ -1093,15 +1205,15 @@ module spine {
this.frames[frameIndex + PathConstraintPositionTimeline.VALUE] = value; this.frames[frameIndex + PathConstraintPositionTimeline.VALUE] = value;
} }
apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let frames = this.frames; let frames = this.frames;
let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex]; let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex];
if (time < frames[0]) { if (time < frames[0]) {
switch (pose) { switch (blend) {
case MixPose.setup: case MixBlend.setup:
constraint.position = constraint.data.position; constraint.position = constraint.data.position;
return; return;
case MixPose.current: case MixBlend.first:
constraint.position += (constraint.data.position - constraint.position) * alpha; constraint.position += (constraint.data.position - constraint.position) * alpha;
} }
return; return;
@ -1120,7 +1232,7 @@ module spine {
position += (frames[frame + PathConstraintPositionTimeline.VALUE] - position) * percent; position += (frames[frame + PathConstraintPositionTimeline.VALUE] - position) * percent;
} }
if (pose == MixPose.setup) if (blend == MixBlend.setup)
constraint.position = constraint.data.position + (position - constraint.data.position) * alpha; constraint.position = constraint.data.position + (position - constraint.data.position) * alpha;
else else
constraint.position += (position - constraint.position) * alpha; constraint.position += (position - constraint.position) * alpha;
@ -1136,15 +1248,15 @@ module spine {
return (TimelineType.pathConstraintSpacing << 24) + this.pathConstraintIndex; return (TimelineType.pathConstraintSpacing << 24) + this.pathConstraintIndex;
} }
apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let frames = this.frames; let frames = this.frames;
let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex]; let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex];
if (time < frames[0]) { if (time < frames[0]) {
switch (pose) { switch (blend) {
case MixPose.setup: case MixBlend.setup:
constraint.spacing = constraint.data.spacing; constraint.spacing = constraint.data.spacing;
return; return;
case MixPose.current: case MixBlend.first:
constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha; constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha;
} }
return; return;
@ -1164,7 +1276,7 @@ module spine {
spacing += (frames[frame + PathConstraintSpacingTimeline.VALUE] - spacing) * percent; spacing += (frames[frame + PathConstraintSpacingTimeline.VALUE] - spacing) * percent;
} }
if (pose == MixPose.setup) if (blend == MixBlend.setup)
constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha; constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha;
else else
constraint.spacing += (spacing - constraint.spacing) * alpha; constraint.spacing += (spacing - constraint.spacing) * alpha;
@ -1197,17 +1309,17 @@ module spine {
this.frames[frameIndex + PathConstraintMixTimeline.TRANSLATE] = translateMix; this.frames[frameIndex + PathConstraintMixTimeline.TRANSLATE] = translateMix;
} }
apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, pose: MixPose, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let frames = this.frames; let frames = this.frames;
let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex]; let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex];
if (time < frames[0]) { if (time < frames[0]) {
switch (pose) { switch (blend) {
case MixPose.setup: case MixBlend.setup:
constraint.rotateMix = constraint.data.rotateMix; constraint.rotateMix = constraint.data.rotateMix;
constraint.translateMix = constraint.data.translateMix; constraint.translateMix = constraint.data.translateMix;
return; return;
case MixPose.current: case MixBlend.first:
constraint.rotateMix += (constraint.data.rotateMix - constraint.rotateMix) * alpha; constraint.rotateMix += (constraint.data.rotateMix - constraint.rotateMix) * alpha;
constraint.translateMix += (constraint.data.translateMix - constraint.translateMix) * alpha; constraint.translateMix += (constraint.data.translateMix - constraint.translateMix) * alpha;
} }
@ -1231,7 +1343,7 @@ module spine {
translate += (frames[frame + PathConstraintMixTimeline.TRANSLATE] - translate) * percent; translate += (frames[frame + PathConstraintMixTimeline.TRANSLATE] - translate) * percent;
} }
if (pose == MixPose.setup) { if (blend == MixBlend.setup) {
constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha; constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha;
constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha; constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha;
} else { } else {

View File

@ -144,12 +144,12 @@ module spine {
let current = tracks[i]; let current = tracks[i];
if (current == null || current.delay > 0) continue; if (current == null || current.delay > 0) continue;
applied = true; applied = true;
let currentPose = i == 0 ? MixPose.current : MixPose.currentLayered; let blend: MixBlend = i == 0 ? MixBlend.first : current.mixBlend;
// Apply mixing from entries first. // Apply mixing from entries first.
let mix = current.alpha; let mix = current.alpha;
if (current.mixingFrom != null) if (current.mixingFrom != null)
mix *= this.applyMixingFrom(current, skeleton, currentPose); mix *= this.applyMixingFrom(current, skeleton, blend);
else if (current.trackTime >= current.trackEnd && current.next == null) else if (current.trackTime >= current.trackEnd && current.next == null)
mix = 0; mix = 0;
@ -157,9 +157,9 @@ module spine {
let animationLast = current.animationLast, animationTime = current.getAnimationTime(); let animationLast = current.animationLast, animationTime = current.getAnimationTime();
let timelineCount = current.animation.timelines.length; let timelineCount = current.animation.timelines.length;
let timelines = current.animation.timelines; let timelines = current.animation.timelines;
if (mix == 1) { if (mix == 1 || blend == MixBlend.add) {
for (let ii = 0; ii < timelineCount; ii++) for (let ii = 0; ii < timelineCount; ii++)
timelines[ii].apply(skeleton, animationLast, animationTime, events, 1, MixPose.setup, MixDirection.in); timelines[ii].apply(skeleton, animationLast, animationTime, events, mix, blend, MixDirection.in);
} else { } else {
let timelineData = current.timelineData; let timelineData = current.timelineData;
@ -169,11 +169,11 @@ module spine {
for (let ii = 0; ii < timelineCount; ii++) { for (let ii = 0; ii < timelineCount; ii++) {
let timeline = timelines[ii]; let timeline = timelines[ii];
let pose = timelineData[ii] >= AnimationState.FIRST ? MixPose.setup : currentPose; let timelineBlend = timelineData[ii] == AnimationState.SUBSEQUENT ? blend : MixBlend.setup;
if (timeline instanceof RotateTimeline) { if (timeline instanceof RotateTimeline) {
this.applyRotateTimeline(timeline, skeleton, animationTime, mix, pose, timelinesRotation, ii << 1, firstFrame); this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
} else } else
timeline.apply(skeleton, animationLast, animationTime, events, mix, pose, MixDirection.in); timeline.apply(skeleton, animationLast, animationTime, events, mix, timelineBlend, MixDirection.in);
} }
} }
this.queueEvents(current, animationTime); this.queueEvents(current, animationTime);
@ -186,17 +186,18 @@ module spine {
return applied; return applied;
} }
applyMixingFrom (to: TrackEntry, skeleton: Skeleton, currentPose: MixPose) { applyMixingFrom (to: TrackEntry, skeleton: Skeleton, blend: MixBlend) {
let from = to.mixingFrom; let from = to.mixingFrom;
if (from.mixingFrom != null) this.applyMixingFrom(from, skeleton, currentPose); if (from.mixingFrom != null) this.applyMixingFrom(from, skeleton, blend);
let mix = 0; let mix = 0;
if (to.mixDuration == 0) { // Single frame mix to undo mixingFrom changes. if (to.mixDuration == 0) { // Single frame mix to undo mixingFrom changes.
mix = 1; mix = 1;
currentPose = MixPose.setup; if (blend == MixBlend.first) blend = MixBlend.setup;
} else { } else {
mix = to.mixTime / to.mixDuration; mix = to.mixTime / to.mixDuration;
if (mix > 1) mix = 1; if (mix > 1) mix = 1;
if (blend != MixBlend.first) blend = from.mixBlend;
} }
let events = mix < from.eventThreshold ? this.events : null; let events = mix < from.eventThreshold ? this.events : null;
@ -204,6 +205,11 @@ module spine {
let animationLast = from.animationLast, animationTime = from.getAnimationTime(); let animationLast = from.animationLast, animationTime = from.getAnimationTime();
let timelineCount = from.animation.timelines.length; let timelineCount = from.animation.timelines.length;
let timelines = from.animation.timelines; let timelines = from.animation.timelines;
let alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix);
if (blend == MixBlend.add) {
for (var i = 0; i < timelineCount; i++)
timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, MixDirection.out);
} else {
let timelineData = from.timelineData; let timelineData = from.timelineData;
let timelineDipMix = from.timelineDipMix; let timelineDipMix = from.timelineDipMix;
@ -211,38 +217,38 @@ module spine {
if (firstFrame) Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null); if (firstFrame) Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null);
let timelinesRotation = from.timelinesRotation; let timelinesRotation = from.timelinesRotation;
let pose: MixPose;
let alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha = 0;
from.totalAlpha = 0; from.totalAlpha = 0;
for (var i = 0; i < timelineCount; i++) { for (var i = 0; i < timelineCount; i++) {
let timeline = timelines[i]; let timeline = timelines[i];
var timelineBlend: MixBlend;
var alpha = 0;
switch (timelineData[i]) { switch (timelineData[i]) {
case AnimationState.SUBSEQUENT: case AnimationState.SUBSEQUENT:
if (!attachments && timeline instanceof AttachmentTimeline) continue; if (!attachments && timeline instanceof AttachmentTimeline) continue;
if (!drawOrder && timeline instanceof DrawOrderTimeline) continue; if (!drawOrder && timeline instanceof DrawOrderTimeline) continue;
pose = currentPose; timelineBlend = blend;
alpha = alphaMix; alpha = alphaMix;
break; break;
case AnimationState.FIRST: case AnimationState.FIRST:
pose = MixPose.setup timelineBlend = MixBlend.setup;
alpha = alphaMix; alpha = alphaMix;
break; break;
case AnimationState.DIP: case AnimationState.DIP:
pose = MixPose.setup; timelineBlend = MixBlend.setup;
alpha = alphaDip; alpha = alphaDip;
break; break;
default: default:
pose = MixPose.setup; timelineBlend = MixBlend.setup;
alpha = alphaDip;
let dipMix = timelineDipMix[i]; let dipMix = timelineDipMix[i];
alpha *= Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration); alpha = alphaDip * Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration);
break; break;
} }
from.totalAlpha += alpha; from.totalAlpha += alpha;
if (timeline instanceof RotateTimeline) if (timeline instanceof RotateTimeline)
this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, pose, timelinesRotation, i << 1, firstFrame); this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame);
else { else {
timeline.apply(skeleton, animationLast, animationTime, events, alpha, pose, MixDirection.out); timeline.apply(skeleton, animationLast, animationTime, events, alpha, timelineBlend, MixDirection.out);
}
} }
} }
@ -254,13 +260,13 @@ module spine {
return mix; return mix;
} }
applyRotateTimeline (timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, pose: MixPose, applyRotateTimeline (timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, blend: MixBlend,
timelinesRotation: Array<number>, i: number, firstFrame: boolean) { timelinesRotation: Array<number>, i: number, firstFrame: boolean) {
if (firstFrame) timelinesRotation[i] = 0; if (firstFrame) timelinesRotation[i] = 0;
if (alpha == 1) { if (alpha == 1) {
timeline.apply(skeleton, 0, time, null, 1, pose, MixDirection.in); timeline.apply(skeleton, 0, time, null, 1, blend, MixDirection.in);
return; return;
} }
@ -268,7 +274,7 @@ module spine {
let frames = rotateTimeline.frames; let frames = rotateTimeline.frames;
let bone = skeleton.bones[rotateTimeline.boneIndex]; let bone = skeleton.bones[rotateTimeline.boneIndex];
if (time < frames[0]) { if (time < frames[0]) {
if (pose == MixPose.setup) bone.rotation = bone.data.rotation; if (blend == MixBlend.setup) bone.rotation = bone.data.rotation;
return; return;
} }
@ -290,7 +296,7 @@ module spine {
} }
// Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. // Mix between rotations using the direction of the shortest route on the first frame while detecting crosses.
let r1 = pose == MixPose.setup ? bone.data.rotation : bone.rotation; let r1 = blend == MixBlend.setup ? bone.data.rotation : bone.rotation;
let total = 0, diff = r2 - r1; let total = 0, diff = r2 - r1;
if (diff == 0) { if (diff == 0) {
total = timelinesRotation[i]; total = timelinesRotation[i];
@ -544,7 +550,7 @@ module spine {
for (var i = 0, n = this.tracks.length; i < n; i++) { for (var i = 0, n = this.tracks.length; i < n; i++) {
let entry = this.tracks[i]; let entry = this.tracks[i];
if (entry != null) entry.setTimelineData(null, mixingTo, propertyIDs); if (entry != null && entry.mixBlend != MixBlend.add) entry.setTimelineData(null, mixingTo, propertyIDs);
} }
} }
@ -583,6 +589,7 @@ module spine {
animationStart: number; animationEnd: number; animationLast: number; nextAnimationLast: number; animationStart: number; animationEnd: number; animationLast: number; nextAnimationLast: number;
delay: number; trackTime: number; trackLast: number; nextTrackLast: number; trackEnd: number; timeScale: number; delay: number; trackTime: number; trackLast: number; nextTrackLast: number; trackEnd: number; timeScale: number;
alpha: number; mixTime: number; mixDuration: number; interruptAlpha: number; totalAlpha: number; alpha: number; mixTime: number; mixDuration: number; interruptAlpha: number; totalAlpha: number;
mixBlend = MixBlend.replace;
timelineData = new Array<number>(); timelineData = new Array<number>();
timelineDipMix = new Array<TrackEntry>(); timelineDipMix = new Array<TrackEntry>();
timelinesRotation = new Array<number>(); timelinesRotation = new Array<number>();

View File

@ -59,7 +59,7 @@ var skinsDemo = function(canvas, bgColor) {
} }
function setupAnimations(state) { function setupAnimations(state) {
state.addAnimation(0, "idle", true, 1); /*state.addAnimation(0, "idle", true, 1);
state.addAnimation(0, "walk", true, 2); state.addAnimation(0, "walk", true, 2);
state.addAnimation(0, "run", true, 4); state.addAnimation(0, "run", true, 4);
state.addAnimation(0, "roll", false, 3); state.addAnimation(0, "roll", false, 3);
@ -78,10 +78,10 @@ var skinsDemo = function(canvas, bgColor) {
state.addAnimation(0, "punch1", false, 1.5); state.addAnimation(0, "punch1", false, 1.5);
state.addAnimation(0, "punch2", false, 0); state.addAnimation(0, "punch2", false, 0);
state.addAnimation(0, "block", true, 0); state.addAnimation(0, "block", true, 0);
state.addAnimation(0, "hitBig", false, 1.5); state.addAnimation(0, "hitBig", false, 1.5);*/
state.addAnimation(0, "floorIdle", true, 0); state.addAnimation(0, "floorIdle", true, 0);
state.addAnimation(0, "floorGetUp", false, 1.5); state.addAnimation(0, "floorGetUp", false, 1.5);
state.addAnimation(0, "idle", true, 0); /*state.addAnimation(0, "idle", true, 0);
state.addAnimation(0, "meleeSwing1-fullBody", false, 1.5); state.addAnimation(0, "meleeSwing1-fullBody", false, 1.5);
state.addAnimation(0, "idle", true, 0); state.addAnimation(0, "idle", true, 0);
state.addAnimation(0, "meleeSwing2-fullBody", false, 1.5); state.addAnimation(0, "meleeSwing2-fullBody", false, 1.5);
@ -96,7 +96,7 @@ var skinsDemo = function(canvas, bgColor) {
}; };
state.setAnimation(1, "empty", false, 0); state.setAnimation(1, "empty", false, 0);
state.setAnimation(1, "hideSword", false, 2); state.setAnimation(1, "hideSword", false, 2);*/
} }
function setupUI() { function setupUI() {