[ts] Formatter pass

This commit is contained in:
Mario Zechner 2021-08-27 17:24:18 +02:00
parent ef6f2efb1a
commit 39df4c7cbb
66 changed files with 711 additions and 711 deletions

View File

@ -4,7 +4,7 @@ This folder contains formatter configuration files to be used with IDEs as well
You will need the following on your `PATH`: You will need the following on your `PATH`:
- JDK 10+ - JDK 10+
- clang-format 12 (i.e. `brew install clang-format`) - clang-format 12 (i.e. `brew install clang-format`). Also set the environment variable `CLANGFORMAT` to the path of the `clang-format` executable.
- dotnet format (i.e. `dotnet tool install -g dotnet-format`, comes with dotnet 6 out of the box) - dotnet format (i.e. `dotnet tool install -g dotnet-format`, comes with dotnet 6 out of the box)
- tsfmt, (i.e. `npm install -g typescript-formatter`) - tsfmt, (i.e. `npm install -g typescript-formatter`)

View File

@ -31,7 +31,7 @@ import { AssetManagerBase, Downloader } from "@esotericsoftware/spine-core"
import { CanvasTexture } from "./CanvasTexture"; import { CanvasTexture } from "./CanvasTexture";
export class AssetManager extends AssetManagerBase { export class AssetManager extends AssetManagerBase {
constructor(pathPrefix: string = "", downloader: Downloader = null) { constructor (pathPrefix: string = "", downloader: Downloader = null) {
super((image: HTMLImageElement) => { return new CanvasTexture(image); }, pathPrefix, downloader); super((image: HTMLImageElement) => { return new CanvasTexture(image); }, pathPrefix, downloader);
} }
} }

View File

@ -30,11 +30,11 @@
import { Texture, TextureFilter, TextureWrap } from "@esotericsoftware/spine-core"; import { Texture, TextureFilter, TextureWrap } from "@esotericsoftware/spine-core";
export class CanvasTexture extends Texture { export class CanvasTexture extends Texture {
constructor(image: HTMLImageElement) { constructor (image: HTMLImageElement) {
super(image); super(image);
} }
setFilters(minFilter: TextureFilter, magFilter: TextureFilter) { } setFilters (minFilter: TextureFilter, magFilter: TextureFilter) { }
setWraps(uWrap: TextureWrap, vWrap: TextureWrap) { } setWraps (uWrap: TextureWrap, vWrap: TextureWrap) { }
dispose() { } dispose () { }
} }

View File

@ -41,16 +41,16 @@ export class SkeletonRenderer {
private vertices = Utils.newFloatArray(8 * 1024); private vertices = Utils.newFloatArray(8 * 1024);
private tempColor = new Color(); private tempColor = new Color();
constructor(context: CanvasRenderingContext2D) { constructor (context: CanvasRenderingContext2D) {
this.ctx = context; this.ctx = context;
} }
draw(skeleton: Skeleton) { draw (skeleton: Skeleton) {
if (this.triangleRendering) this.drawTriangles(skeleton); if (this.triangleRendering) this.drawTriangles(skeleton);
else this.drawImages(skeleton); else this.drawImages(skeleton);
} }
private drawImages(skeleton: Skeleton) { private drawImages (skeleton: Skeleton) {
let ctx = this.ctx; let ctx = this.ctx;
let color = this.tempColor; let color = this.tempColor;
let skeletonColor = skeleton.color; let skeletonColor = skeleton.color;
@ -107,7 +107,7 @@ export class SkeletonRenderer {
} }
} }
private drawTriangles(skeleton: Skeleton) { private drawTriangles (skeleton: Skeleton) {
let ctx = this.ctx; let ctx = this.ctx;
let color = this.tempColor; let color = this.tempColor;
let skeletonColor = skeleton.color; let skeletonColor = skeleton.color;
@ -182,7 +182,7 @@ export class SkeletonRenderer {
// Adapted from http://extremelysatisfactorytotalitarianism.com/blog/?p=2120 // Adapted from http://extremelysatisfactorytotalitarianism.com/blog/?p=2120
// Apache 2 licensed // Apache 2 licensed
private drawTriangle(img: HTMLImageElement, x0: number, y0: number, u0: number, v0: number, private drawTriangle (img: HTMLImageElement, x0: number, y0: number, u0: number, v0: number,
x1: number, y1: number, u1: number, v1: number, x1: number, y1: number, u1: number, v1: number,
x2: number, y2: number, u2: number, v2: number) { x2: number, y2: number, u2: number, v2: number) {
let ctx = this.ctx; let ctx = this.ctx;
@ -229,7 +229,7 @@ export class SkeletonRenderer {
ctx.restore(); ctx.restore();
} }
private computeRegionVertices(slot: Slot, region: RegionAttachment, pma: boolean) { private computeRegionVertices (slot: Slot, region: RegionAttachment, pma: boolean) {
let skeletonColor = slot.bone.skeleton.color; let skeletonColor = slot.bone.skeleton.color;
let slotColor = slot.color; let slotColor = slot.color;
let regionColor = region.color; let regionColor = region.color;
@ -277,7 +277,7 @@ export class SkeletonRenderer {
return vertices; return vertices;
} }
private computeMeshVertices(slot: Slot, mesh: MeshAttachment, pma: boolean) { private computeMeshVertices (slot: Slot, mesh: MeshAttachment, pma: boolean) {
let skeletonColor = slot.bone.skeleton.color; let skeletonColor = slot.bone.skeleton.color;
let slotColor = slot.color; let slotColor = slot.color;
let regionColor = mesh.color; let regionColor = mesh.color;

View File

@ -46,14 +46,14 @@ export class Animation {
/** The duration of the animation in seconds, which is the highest time of all keys in the timeline. */ /** The duration of the animation in seconds, which is the highest time of all keys in the timeline. */
duration: number; duration: number;
constructor(name: string, timelines: Array<Timeline>, duration: number) { constructor (name: string, timelines: Array<Timeline>, duration: number) {
if (!name) throw new Error("name cannot be null."); if (!name) throw new Error("name cannot be null.");
this.name = name; this.name = name;
this.setTimelines(timelines); this.setTimelines(timelines);
this.duration = duration; this.duration = duration;
} }
setTimelines(timelines: Array<Timeline>) { setTimelines (timelines: Array<Timeline>) {
if (!timelines) throw new Error("timelines cannot be null."); if (!timelines) throw new Error("timelines cannot be null.");
this.timelines = timelines; this.timelines = timelines;
this.timelineIds = new StringSet(); this.timelineIds = new StringSet();
@ -61,7 +61,7 @@ export class Animation {
this.timelineIds.addAll(timelines[i].getPropertyIds()); this.timelineIds.addAll(timelines[i].getPropertyIds());
} }
hasTimeline(ids: string[]): boolean { hasTimeline (ids: string[]): boolean {
for (let i = 0; i < ids.length; i++) for (let i = 0; i < ids.length; i++)
if (this.timelineIds.contains(ids[i])) return true; if (this.timelineIds.contains(ids[i])) return true;
return false; return false;
@ -72,7 +72,7 @@ export class Animation {
* See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}. * See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}.
* @param loop If true, the animation repeats after {@link #getDuration()}. * @param loop If true, the animation repeats after {@link #getDuration()}.
* @param events May be null to ignore fired events. */ * @param events May be null to ignore fired events. */
apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
if (!skeleton) throw new Error("skeleton cannot be null."); if (!skeleton) throw new Error("skeleton cannot be null.");
if (loop && this.duration != 0) { if (loop && this.duration != 0) {
@ -154,37 +154,37 @@ export abstract class Timeline {
propertyIds: string[]; propertyIds: string[];
frames: NumberArrayLike; frames: NumberArrayLike;
constructor(frameCount: number, propertyIds: string[]) { constructor (frameCount: number, propertyIds: string[]) {
this.propertyIds = propertyIds; this.propertyIds = propertyIds;
this.frames = Utils.newFloatArray(frameCount * this.getFrameEntries()); this.frames = Utils.newFloatArray(frameCount * this.getFrameEntries());
} }
getPropertyIds() { getPropertyIds () {
return this.propertyIds; return this.propertyIds;
} }
getFrameEntries(): number { getFrameEntries (): number {
return 1; return 1;
} }
getFrameCount() { getFrameCount () {
return this.frames.length / this.getFrameEntries(); return this.frames.length / this.getFrameEntries();
} }
getDuration(): number { getDuration (): number {
return this.frames[this.frames.length - this.getFrameEntries()]; return this.frames[this.frames.length - this.getFrameEntries()];
} }
abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; abstract apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
static search1(frames: NumberArrayLike, time: number) { static search1 (frames: NumberArrayLike, time: number) {
let n = frames.length; let n = frames.length;
for (let i = 1; i < n; i++) for (let i = 1; i < n; i++)
if (frames[i] > time) return i - 1; if (frames[i] > time) return i - 1;
return n - 1; return n - 1;
} }
static search(frames: NumberArrayLike, time: number, step: number) { static search (frames: NumberArrayLike, time: number, step: number) {
let n = frames.length; let n = frames.length;
for (let i = step; i < n; i += step) for (let i = step; i < n; i += step)
if (frames[i] > time) return i - step; if (frames[i] > time) return i - step;
@ -206,25 +206,25 @@ export interface SlotTimeline {
export abstract class CurveTimeline extends Timeline { export abstract class CurveTimeline extends Timeline {
protected curves: NumberArrayLike; // type, x, y, ... protected curves: NumberArrayLike; // type, x, y, ...
constructor(frameCount: number, bezierCount: number, propertyIds: string[]) { constructor (frameCount: number, bezierCount: number, propertyIds: string[]) {
super(frameCount, propertyIds); super(frameCount, propertyIds);
this.curves = Utils.newFloatArray(frameCount + bezierCount * 18/*BEZIER_SIZE*/); this.curves = Utils.newFloatArray(frameCount + bezierCount * 18/*BEZIER_SIZE*/);
this.curves[frameCount - 1] = 1/*STEPPED*/; this.curves[frameCount - 1] = 1/*STEPPED*/;
} }
/** Sets the specified key frame to linear interpolation. */ /** Sets the specified key frame to linear interpolation. */
setLinear(frame: number) { setLinear (frame: number) {
this.curves[frame] = 0/*LINEAR*/; this.curves[frame] = 0/*LINEAR*/;
} }
/** Sets the specified key frame to stepped interpolation. */ /** Sets the specified key frame to stepped interpolation. */
setStepped(frame: number) { setStepped (frame: number) {
this.curves[frame] = 1/*STEPPED*/; this.curves[frame] = 1/*STEPPED*/;
} }
/** Shrinks the storage for Bezier curves, for use when <code>bezierCount</code> (specified in the constructor) was larger /** Shrinks the storage for Bezier curves, for use when <code>bezierCount</code> (specified in the constructor) was larger
* than the actual number of Bezier curves. */ * than the actual number of Bezier curves. */
shrink(bezierCount: number) { shrink (bezierCount: number) {
let size = this.getFrameCount() + bezierCount * 18/*BEZIER_SIZE*/; let size = this.getFrameCount() + bezierCount * 18/*BEZIER_SIZE*/;
if (this.curves.length > size) { if (this.curves.length > size) {
let newCurves = Utils.newFloatArray(size); let newCurves = Utils.newFloatArray(size);
@ -247,7 +247,7 @@ export abstract class CurveTimeline extends Timeline {
* @param cy2 The value for the second Bezier handle. * @param cy2 The value for the second Bezier handle.
* @param time2 The time for the second key. * @param time2 The time for the second key.
* @param value2 The value for the second key. */ * @param value2 The value for the second key. */
setBezier(bezier: number, frame: number, value: number, time1: number, value1: number, cx1: number, cy1: number, cx2: number, setBezier (bezier: number, frame: number, value: number, time1: number, value1: number, cx1: number, cy1: number, cx2: number,
cy2: number, time2: number, value2: number) { cy2: number, time2: number, value2: number) {
let curves = this.curves; let curves = this.curves;
let i = this.getFrameCount() + bezier * 18/*BEZIER_SIZE*/; let i = this.getFrameCount() + bezier * 18/*BEZIER_SIZE*/;
@ -273,7 +273,7 @@ export abstract class CurveTimeline extends Timeline {
* @param frameIndex The index into {@link #getFrames()} for the values of the frame before <code>time</code>. * @param frameIndex The index into {@link #getFrames()} for the values of the frame before <code>time</code>.
* @param valueOffset The offset from <code>frameIndex</code> to the value this curve is used for. * @param valueOffset The offset from <code>frameIndex</code> to the value this curve is used for.
* @param i The index of the Bezier segments. See {@link #getCurveType(int)}. */ * @param i The index of the Bezier segments. See {@link #getCurveType(int)}. */
getBezierValue(time: number, frameIndex: number, valueOffset: number, i: number) { getBezierValue (time: number, frameIndex: number, valueOffset: number, i: number) {
let curves = this.curves; let curves = this.curves;
if (curves[i] > time) { if (curves[i] > time) {
let x = this.frames[frameIndex], y = this.frames[frameIndex + valueOffset]; let x = this.frames[frameIndex], y = this.frames[frameIndex + valueOffset];
@ -293,25 +293,25 @@ export abstract class CurveTimeline extends Timeline {
} }
export abstract class CurveTimeline1 extends CurveTimeline { export abstract class CurveTimeline1 extends CurveTimeline {
constructor(frameCount: number, bezierCount: number, propertyId: string) { constructor (frameCount: number, bezierCount: number, propertyId: string) {
super(frameCount, bezierCount, [propertyId]); super(frameCount, bezierCount, [propertyId]);
} }
getFrameEntries() { getFrameEntries () {
return 2/*ENTRIES*/; return 2/*ENTRIES*/;
} }
/** Sets the time and value for the specified frame. /** Sets the time and value for the specified frame.
* @param frame Between 0 and <code>frameCount</code>, inclusive. * @param frame Between 0 and <code>frameCount</code>, inclusive.
* @param time The frame time in seconds. */ * @param time The frame time in seconds. */
setFrame(frame: number, time: number, value: number) { setFrame (frame: number, time: number, value: number) {
frame <<= 1; frame <<= 1;
this.frames[frame] = time; this.frames[frame] = time;
this.frames[frame + 1/*VALUE*/] = value; this.frames[frame + 1/*VALUE*/] = value;
} }
/** Returns the interpolated value for the specified time. */ /** Returns the interpolated value for the specified time. */
getCurveValue(time: number) { getCurveValue (time: number) {
let frames = this.frames; let frames = this.frames;
let i = frames.length - 2; let i = frames.length - 2;
for (let ii = 2; ii <= i; ii += 2) { for (let ii = 2; ii <= i; ii += 2) {
@ -337,18 +337,18 @@ export abstract class CurveTimeline1 extends CurveTimeline {
export abstract class CurveTimeline2 extends CurveTimeline { export abstract class CurveTimeline2 extends CurveTimeline {
/** @param bezierCount The maximum number of Bezier curves. See {@link #shrink(int)}. /** @param bezierCount The maximum number of Bezier curves. See {@link #shrink(int)}.
* @param propertyIds Unique identifiers for the properties the timeline modifies. */ * @param propertyIds Unique identifiers for the properties the timeline modifies. */
constructor(frameCount: number, bezierCount: number, propertyId1: string, propertyId2: string) { constructor (frameCount: number, bezierCount: number, propertyId1: string, propertyId2: string) {
super(frameCount, bezierCount, [propertyId1, propertyId2]); super(frameCount, bezierCount, [propertyId1, propertyId2]);
} }
getFrameEntries() { getFrameEntries () {
return 3/*ENTRIES*/; return 3/*ENTRIES*/;
} }
/** Sets the time and values for the specified frame. /** Sets the time and values for the specified frame.
* @param frame Between 0 and <code>frameCount</code>, inclusive. * @param frame Between 0 and <code>frameCount</code>, inclusive.
* @param time The frame time in seconds. */ * @param time The frame time in seconds. */
setFrame(frame: number, time: number, value1: number, value2: number) { setFrame (frame: number, time: number, value1: number, value2: number) {
frame *= 3/*ENTRIES*/; frame *= 3/*ENTRIES*/;
this.frames[frame] = time; this.frames[frame] = time;
this.frames[frame + 1/*VALUE1*/] = value1; this.frames[frame + 1/*VALUE1*/] = value1;
@ -360,12 +360,12 @@ export abstract class CurveTimeline2 extends CurveTimeline {
export class RotateTimeline extends CurveTimeline1 implements BoneTimeline { export class RotateTimeline extends CurveTimeline1 implements BoneTimeline {
boneIndex = 0; boneIndex = 0;
constructor(frameCount: number, bezierCount: number, boneIndex: number) { constructor (frameCount: number, bezierCount: number, boneIndex: number) {
super(frameCount, bezierCount, Property.rotate + "|" + boneIndex); super(frameCount, bezierCount, Property.rotate + "|" + boneIndex);
this.boneIndex = boneIndex; this.boneIndex = boneIndex;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let bone = skeleton.bones[this.boneIndex]; let bone = skeleton.bones[this.boneIndex];
if (!bone.active) return; if (!bone.active) return;
@ -399,7 +399,7 @@ export class RotateTimeline extends CurveTimeline1 implements BoneTimeline {
export class TranslateTimeline extends CurveTimeline2 implements BoneTimeline { export class TranslateTimeline extends CurveTimeline2 implements BoneTimeline {
boneIndex = 0; boneIndex = 0;
constructor(frameCount: number, bezierCount: number, boneIndex: number) { constructor (frameCount: number, bezierCount: number, boneIndex: number) {
super(frameCount, bezierCount, super(frameCount, bezierCount,
Property.x + "|" + boneIndex, Property.x + "|" + boneIndex,
Property.y + "|" + boneIndex, Property.y + "|" + boneIndex,
@ -407,7 +407,7 @@ export class TranslateTimeline extends CurveTimeline2 implements BoneTimeline {
this.boneIndex = boneIndex; this.boneIndex = boneIndex;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let bone = skeleton.bones[this.boneIndex]; let bone = skeleton.bones[this.boneIndex];
if (!bone.active) return; if (!bone.active) return;
@ -467,12 +467,12 @@ export class TranslateTimeline extends CurveTimeline2 implements BoneTimeline {
export class TranslateXTimeline extends CurveTimeline1 implements BoneTimeline { export class TranslateXTimeline extends CurveTimeline1 implements BoneTimeline {
boneIndex = 0; boneIndex = 0;
constructor(frameCount: number, bezierCount: number, boneIndex: number) { constructor (frameCount: number, bezierCount: number, boneIndex: number) {
super(frameCount, bezierCount, Property.x + "|" + boneIndex); super(frameCount, bezierCount, Property.x + "|" + boneIndex);
this.boneIndex = boneIndex; this.boneIndex = boneIndex;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let bone = skeleton.bones[this.boneIndex]; let bone = skeleton.bones[this.boneIndex];
if (!bone.active) return; if (!bone.active) return;
@ -507,12 +507,12 @@ export class TranslateXTimeline extends CurveTimeline1 implements BoneTimeline {
export class TranslateYTimeline extends CurveTimeline1 implements BoneTimeline { export class TranslateYTimeline extends CurveTimeline1 implements BoneTimeline {
boneIndex = 0; boneIndex = 0;
constructor(frameCount: number, bezierCount: number, boneIndex: number) { constructor (frameCount: number, bezierCount: number, boneIndex: number) {
super(frameCount, bezierCount, Property.y + "|" + boneIndex); super(frameCount, bezierCount, Property.y + "|" + boneIndex);
this.boneIndex = boneIndex; this.boneIndex = boneIndex;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let bone = skeleton.bones[this.boneIndex]; let bone = skeleton.bones[this.boneIndex];
if (!bone.active) return; if (!bone.active) return;
@ -547,7 +547,7 @@ export class TranslateYTimeline extends CurveTimeline1 implements BoneTimeline {
export class ScaleTimeline extends CurveTimeline2 implements BoneTimeline { export class ScaleTimeline extends CurveTimeline2 implements BoneTimeline {
boneIndex = 0; boneIndex = 0;
constructor(frameCount: number, bezierCount: number, boneIndex: number) { constructor (frameCount: number, bezierCount: number, boneIndex: number) {
super(frameCount, bezierCount, super(frameCount, bezierCount,
Property.scaleX + "|" + boneIndex, Property.scaleX + "|" + boneIndex,
Property.scaleY + "|" + boneIndex Property.scaleY + "|" + boneIndex
@ -555,7 +555,7 @@ export class ScaleTimeline extends CurveTimeline2 implements BoneTimeline {
this.boneIndex = boneIndex; this.boneIndex = boneIndex;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let bone = skeleton.bones[this.boneIndex]; let bone = skeleton.bones[this.boneIndex];
if (!bone.active) return; if (!bone.active) return;
@ -657,12 +657,12 @@ export class ScaleTimeline extends CurveTimeline2 implements BoneTimeline {
export class ScaleXTimeline extends CurveTimeline1 implements BoneTimeline { export class ScaleXTimeline extends CurveTimeline1 implements BoneTimeline {
boneIndex = 0; boneIndex = 0;
constructor(frameCount: number, bezierCount: number, boneIndex: number) { constructor (frameCount: number, bezierCount: number, boneIndex: number) {
super(frameCount, bezierCount, Property.scaleX + "|" + boneIndex); super(frameCount, bezierCount, Property.scaleX + "|" + boneIndex);
this.boneIndex = boneIndex; this.boneIndex = boneIndex;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let bone = skeleton.bones[this.boneIndex]; let bone = skeleton.bones[this.boneIndex];
if (!bone.active) return; if (!bone.active) return;
@ -726,12 +726,12 @@ export class ScaleXTimeline extends CurveTimeline1 implements BoneTimeline {
export class ScaleYTimeline extends CurveTimeline1 implements BoneTimeline { export class ScaleYTimeline extends CurveTimeline1 implements BoneTimeline {
boneIndex = 0; boneIndex = 0;
constructor(frameCount: number, bezierCount: number, boneIndex: number) { constructor (frameCount: number, bezierCount: number, boneIndex: number) {
super(frameCount, bezierCount, Property.scaleY + "|" + boneIndex); super(frameCount, bezierCount, Property.scaleY + "|" + boneIndex);
this.boneIndex = boneIndex; this.boneIndex = boneIndex;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let bone = skeleton.bones[this.boneIndex]; let bone = skeleton.bones[this.boneIndex];
if (!bone.active) return; if (!bone.active) return;
@ -795,7 +795,7 @@ export class ScaleYTimeline extends CurveTimeline1 implements BoneTimeline {
export class ShearTimeline extends CurveTimeline2 implements BoneTimeline { export class ShearTimeline extends CurveTimeline2 implements BoneTimeline {
boneIndex = 0; boneIndex = 0;
constructor(frameCount: number, bezierCount: number, boneIndex: number) { constructor (frameCount: number, bezierCount: number, boneIndex: number) {
super(frameCount, bezierCount, super(frameCount, bezierCount,
Property.shearX + "|" + boneIndex, Property.shearX + "|" + boneIndex,
Property.shearY + "|" + boneIndex Property.shearY + "|" + boneIndex
@ -803,7 +803,7 @@ export class ShearTimeline extends CurveTimeline2 implements BoneTimeline {
this.boneIndex = boneIndex; this.boneIndex = boneIndex;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let bone = skeleton.bones[this.boneIndex]; let bone = skeleton.bones[this.boneIndex];
if (!bone.active) return; if (!bone.active) return;
@ -863,12 +863,12 @@ export class ShearTimeline extends CurveTimeline2 implements BoneTimeline {
export class ShearXTimeline extends CurveTimeline1 implements BoneTimeline { export class ShearXTimeline extends CurveTimeline1 implements BoneTimeline {
boneIndex = 0; boneIndex = 0;
constructor(frameCount: number, bezierCount: number, boneIndex: number) { constructor (frameCount: number, bezierCount: number, boneIndex: number) {
super(frameCount, bezierCount, Property.shearX + "|" + boneIndex); super(frameCount, bezierCount, Property.shearX + "|" + boneIndex);
this.boneIndex = boneIndex; this.boneIndex = boneIndex;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let bone = skeleton.bones[this.boneIndex]; let bone = skeleton.bones[this.boneIndex];
if (!bone.active) return; if (!bone.active) return;
@ -903,12 +903,12 @@ export class ShearXTimeline extends CurveTimeline1 implements BoneTimeline {
export class ShearYTimeline extends CurveTimeline1 implements BoneTimeline { export class ShearYTimeline extends CurveTimeline1 implements BoneTimeline {
boneIndex = 0; boneIndex = 0;
constructor(frameCount: number, bezierCount: number, boneIndex: number) { constructor (frameCount: number, bezierCount: number, boneIndex: number) {
super(frameCount, bezierCount, Property.shearY + "|" + boneIndex); super(frameCount, bezierCount, Property.shearY + "|" + boneIndex);
this.boneIndex = boneIndex; this.boneIndex = boneIndex;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let bone = skeleton.bones[this.boneIndex]; let bone = skeleton.bones[this.boneIndex];
if (!bone.active) return; if (!bone.active) return;
@ -943,7 +943,7 @@ export class ShearYTimeline extends CurveTimeline1 implements BoneTimeline {
export class RGBATimeline extends CurveTimeline implements SlotTimeline { export class RGBATimeline extends CurveTimeline implements SlotTimeline {
slotIndex = 0; slotIndex = 0;
constructor(frameCount: number, bezierCount: number, slotIndex: number) { constructor (frameCount: number, bezierCount: number, slotIndex: number) {
super(frameCount, bezierCount, [ super(frameCount, bezierCount, [
Property.rgb + "|" + slotIndex, Property.rgb + "|" + slotIndex,
Property.alpha + "|" + slotIndex Property.alpha + "|" + slotIndex
@ -951,12 +951,12 @@ export class RGBATimeline extends CurveTimeline implements SlotTimeline {
this.slotIndex = slotIndex; this.slotIndex = slotIndex;
} }
getFrameEntries() { getFrameEntries () {
return 5/*ENTRIES*/; return 5/*ENTRIES*/;
} }
/** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */ /** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */
setFrame(frame: number, time: number, r: number, g: number, b: number, a: number) { setFrame (frame: number, time: number, r: number, g: number, b: number, a: number) {
frame *= 5/*ENTRIES*/; frame *= 5/*ENTRIES*/;
this.frames[frame] = time; this.frames[frame] = time;
this.frames[frame + 1/*R*/] = r; this.frames[frame + 1/*R*/] = r;
@ -965,7 +965,7 @@ export class RGBATimeline extends CurveTimeline implements SlotTimeline {
this.frames[frame + 4/*A*/] = a; this.frames[frame + 4/*A*/] = a;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, 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 (!slot.bone.active) return; if (!slot.bone.active) return;
@ -1025,19 +1025,19 @@ export class RGBATimeline extends CurveTimeline implements SlotTimeline {
export class RGBTimeline extends CurveTimeline implements SlotTimeline { export class RGBTimeline extends CurveTimeline implements SlotTimeline {
slotIndex = 0; slotIndex = 0;
constructor(frameCount: number, bezierCount: number, slotIndex: number) { constructor (frameCount: number, bezierCount: number, slotIndex: number) {
super(frameCount, bezierCount, [ super(frameCount, bezierCount, [
Property.rgb + "|" + slotIndex Property.rgb + "|" + slotIndex
]); ]);
this.slotIndex = slotIndex; this.slotIndex = slotIndex;
} }
getFrameEntries() { getFrameEntries () {
return 4/*ENTRIES*/; return 4/*ENTRIES*/;
} }
/** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */ /** Sets the time in seconds, red, green, blue, and alpha for the specified key frame. */
setFrame(frame: number, time: number, r: number, g: number, b: number) { setFrame (frame: number, time: number, r: number, g: number, b: number) {
frame <<= 2; frame <<= 2;
this.frames[frame] = time; this.frames[frame] = time;
this.frames[frame + 1/*R*/] = r; this.frames[frame + 1/*R*/] = r;
@ -1045,7 +1045,7 @@ export class RGBTimeline extends CurveTimeline implements SlotTimeline {
this.frames[frame + 3/*B*/] = b; this.frames[frame + 3/*B*/] = b;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, 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 (!slot.bone.active) return; if (!slot.bone.active) return;
@ -1113,12 +1113,12 @@ export class RGBTimeline extends CurveTimeline implements SlotTimeline {
export class AlphaTimeline extends CurveTimeline1 implements SlotTimeline { export class AlphaTimeline extends CurveTimeline1 implements SlotTimeline {
slotIndex = 0; slotIndex = 0;
constructor(frameCount: number, bezierCount: number, slotIndex: number) { constructor (frameCount: number, bezierCount: number, slotIndex: number) {
super(frameCount, bezierCount, Property.alpha + "|" + slotIndex); super(frameCount, bezierCount, Property.alpha + "|" + slotIndex);
this.slotIndex = slotIndex; this.slotIndex = slotIndex;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, 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 (!slot.bone.active) return; if (!slot.bone.active) return;
@ -1149,7 +1149,7 @@ export class AlphaTimeline extends CurveTimeline1 implements SlotTimeline {
export class RGBA2Timeline extends CurveTimeline implements SlotTimeline { export class RGBA2Timeline extends CurveTimeline implements SlotTimeline {
slotIndex = 0; slotIndex = 0;
constructor(frameCount: number, bezierCount: number, slotIndex: number) { constructor (frameCount: number, bezierCount: number, slotIndex: number) {
super(frameCount, bezierCount, [ super(frameCount, bezierCount, [
Property.rgb + "|" + slotIndex, Property.rgb + "|" + slotIndex,
Property.alpha + "|" + slotIndex, Property.alpha + "|" + slotIndex,
@ -1158,12 +1158,12 @@ export class RGBA2Timeline extends CurveTimeline implements SlotTimeline {
this.slotIndex = slotIndex; this.slotIndex = slotIndex;
} }
getFrameEntries() { getFrameEntries () {
return 8/*ENTRIES*/; return 8/*ENTRIES*/;
} }
/** Sets the time in seconds, light, and dark colors for the specified key frame. */ /** Sets the time in seconds, light, and dark colors for the specified key frame. */
setFrame(frame: number, time: number, r: number, g: number, b: number, a: number, r2: number, g2: number, b2: number) { setFrame (frame: number, time: number, r: number, g: number, b: number, a: number, r2: number, g2: number, b2: number) {
frame <<= 3; frame <<= 3;
this.frames[frame] = time; this.frames[frame] = time;
this.frames[frame + 1/*R*/] = r; this.frames[frame + 1/*R*/] = r;
@ -1175,7 +1175,7 @@ export class RGBA2Timeline extends CurveTimeline implements SlotTimeline {
this.frames[frame + 7/*B2*/] = b2; this.frames[frame + 7/*B2*/] = b2;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, 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 (!slot.bone.active) return; if (!slot.bone.active) return;
@ -1266,7 +1266,7 @@ export class RGBA2Timeline extends CurveTimeline implements SlotTimeline {
export class RGB2Timeline extends CurveTimeline implements SlotTimeline { export class RGB2Timeline extends CurveTimeline implements SlotTimeline {
slotIndex = 0; slotIndex = 0;
constructor(frameCount: number, bezierCount: number, slotIndex: number) { constructor (frameCount: number, bezierCount: number, slotIndex: number) {
super(frameCount, bezierCount, [ super(frameCount, bezierCount, [
Property.rgb + "|" + slotIndex, Property.rgb + "|" + slotIndex,
Property.rgb2 + "|" + slotIndex Property.rgb2 + "|" + slotIndex
@ -1274,12 +1274,12 @@ export class RGB2Timeline extends CurveTimeline implements SlotTimeline {
this.slotIndex = slotIndex; this.slotIndex = slotIndex;
} }
getFrameEntries() { getFrameEntries () {
return 7/*ENTRIES*/; return 7/*ENTRIES*/;
} }
/** Sets the time in seconds, light, and dark colors for the specified key frame. */ /** Sets the time in seconds, light, and dark colors for the specified key frame. */
setFrame(frame: number, time: number, r: number, g: number, b: number, r2: number, g2: number, b2: number) { setFrame (frame: number, time: number, r: number, g: number, b: number, r2: number, g2: number, b2: number) {
frame *= 7/*ENTRIES*/; frame *= 7/*ENTRIES*/;
this.frames[frame] = time; this.frames[frame] = time;
this.frames[frame + 1/*R*/] = r; this.frames[frame + 1/*R*/] = r;
@ -1290,7 +1290,7 @@ export class RGB2Timeline extends CurveTimeline implements SlotTimeline {
this.frames[frame + 6/*B2*/] = b2; this.frames[frame + 6/*B2*/] = b2;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, 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 (!slot.bone.active) return; if (!slot.bone.active) return;
@ -1389,7 +1389,7 @@ export class AttachmentTimeline extends Timeline implements SlotTimeline {
/** The attachment name for each key frame. May contain null values to clear the attachment. */ /** The attachment name for each key frame. May contain null values to clear the attachment. */
attachmentNames: Array<string>; attachmentNames: Array<string>;
constructor(frameCount: number, slotIndex: number) { constructor (frameCount: number, slotIndex: number) {
super(frameCount, [ super(frameCount, [
Property.attachment + "|" + slotIndex Property.attachment + "|" + slotIndex
]); ]);
@ -1397,17 +1397,17 @@ export class AttachmentTimeline extends Timeline implements SlotTimeline {
this.attachmentNames = new Array<string>(frameCount); this.attachmentNames = new Array<string>(frameCount);
} }
getFrameCount() { getFrameCount () {
return this.frames.length; return this.frames.length;
} }
/** Sets the time in seconds and the attachment name for the specified key frame. */ /** Sets the time in seconds and the attachment name for the specified key frame. */
setFrame(frame: number, time: number, attachmentName: string) { setFrame (frame: number, time: number, attachmentName: string) {
this.frames[frame] = time; this.frames[frame] = time;
this.attachmentNames[frame] = attachmentName; this.attachmentNames[frame] = attachmentName;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, 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 (!slot.bone.active) return; if (!slot.bone.active) return;
@ -1424,7 +1424,7 @@ export class AttachmentTimeline extends Timeline implements SlotTimeline {
this.setAttachment(skeleton, slot, this.attachmentNames[Timeline.search1(this.frames, time)]); this.setAttachment(skeleton, slot, this.attachmentNames[Timeline.search1(this.frames, time)]);
} }
setAttachment(skeleton: Skeleton, slot: Slot, attachmentName: string) { setAttachment (skeleton: Skeleton, slot: Slot, attachmentName: string) {
slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(this.slotIndex, attachmentName)); slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(this.slotIndex, attachmentName));
} }
} }
@ -1439,7 +1439,7 @@ export class DeformTimeline extends CurveTimeline implements SlotTimeline {
/** The vertices for each key frame. */ /** The vertices for each key frame. */
vertices: Array<NumberArrayLike>; vertices: Array<NumberArrayLike>;
constructor(frameCount: number, bezierCount: number, slotIndex: number, attachment: VertexAttachment) { constructor (frameCount: number, bezierCount: number, slotIndex: number, attachment: VertexAttachment) {
super(frameCount, bezierCount, [ super(frameCount, bezierCount, [
Property.deform + "|" + slotIndex + "|" + attachment.id Property.deform + "|" + slotIndex + "|" + attachment.id
]); ]);
@ -1448,20 +1448,20 @@ export class DeformTimeline extends CurveTimeline implements SlotTimeline {
this.vertices = new Array<NumberArrayLike>(frameCount); this.vertices = new Array<NumberArrayLike>(frameCount);
} }
getFrameCount() { getFrameCount () {
return this.frames.length; return this.frames.length;
} }
/** Sets the time in seconds and the vertices for the specified key frame. /** Sets the time in seconds and the vertices for the specified key frame.
* @param vertices Vertex positions for an unweighted VertexAttachment, or deform offsets if it has weights. */ * @param vertices Vertex positions for an unweighted VertexAttachment, or deform offsets if it has weights. */
setFrame(frame: number, time: number, vertices: NumberArrayLike) { setFrame (frame: number, time: number, vertices: NumberArrayLike) {
this.frames[frame] = time; this.frames[frame] = time;
this.vertices[frame] = vertices; this.vertices[frame] = vertices;
} }
/** @param value1 Ignored (0 is used for a deform timeline). /** @param value1 Ignored (0 is used for a deform timeline).
* @param value2 Ignored (1 is used for a deform timeline). */ * @param value2 Ignored (1 is used for a deform timeline). */
setBezier(bezier: number, frame: number, value: number, time1: number, value1: number, cx1: number, cy1: number, cx2: number, setBezier (bezier: number, frame: number, value: number, time1: number, value1: number, cx1: number, cy1: number, cx2: number,
cy2: number, time2: number, value2: number) { cy2: number, time2: number, value2: number) {
let curves = this.curves; let curves = this.curves;
let i = this.getFrameCount() + bezier * 18/*BEZIER_SIZE*/; let i = this.getFrameCount() + bezier * 18/*BEZIER_SIZE*/;
@ -1483,7 +1483,7 @@ export class DeformTimeline extends CurveTimeline implements SlotTimeline {
} }
} }
getCurvePercent(time: number, frame: number) { getCurvePercent (time: number, frame: number) {
let curves = this.curves; let curves = this.curves;
let i = curves[frame]; let i = curves[frame];
switch (i) { switch (i) {
@ -1509,7 +1509,7 @@ export class DeformTimeline extends CurveTimeline implements SlotTimeline {
return y + (1 - y) * (time - x) / (this.frames[frame + this.getFrameEntries()] - x); return y + (1 - y) * (time - x) / (this.frames[frame + this.getFrameEntries()] - x);
} }
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, 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];
if (!slot.bone.active) return; if (!slot.bone.active) return;
let slotAttachment: Attachment = slot.getAttachment(); let slotAttachment: Attachment = slot.getAttachment();
@ -1691,24 +1691,24 @@ export class EventTimeline extends Timeline {
/** The event for each key frame. */ /** The event for each key frame. */
events: Array<Event>; events: Array<Event>;
constructor(frameCount: number) { constructor (frameCount: number) {
super(frameCount, EventTimeline.propertyIds); super(frameCount, EventTimeline.propertyIds);
this.events = new Array<Event>(frameCount); this.events = new Array<Event>(frameCount);
} }
getFrameCount() { getFrameCount () {
return this.frames.length; return this.frames.length;
} }
/** Sets the time in seconds and the event for the specified key frame. */ /** Sets the time in seconds and the event for the specified key frame. */
setFrame(frame: number, event: Event) { setFrame (frame: number, event: Event) {
this.frames[frame] = event.time; this.frames[frame] = event.time;
this.events[frame] = event; this.events[frame] = event;
} }
/** 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, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
if (!firedEvents) return; if (!firedEvents) return;
let frames = this.frames; let frames = this.frames;
@ -1744,24 +1744,24 @@ export class DrawOrderTimeline extends Timeline {
/** The draw order for each key frame. See {@link #setFrame(int, float, int[])}. */ /** The draw order for each key frame. See {@link #setFrame(int, float, int[])}. */
drawOrders: Array<Array<number>>; drawOrders: Array<Array<number>>;
constructor(frameCount: number) { constructor (frameCount: number) {
super(frameCount, DrawOrderTimeline.propertyIds); super(frameCount, DrawOrderTimeline.propertyIds);
this.drawOrders = new Array<Array<number>>(frameCount); this.drawOrders = new Array<Array<number>>(frameCount);
} }
getFrameCount() { getFrameCount () {
return this.frames.length; return this.frames.length;
} }
/** Sets the time in seconds and the draw order for the specified key frame. /** Sets the time in seconds and the draw order for the specified key frame.
* @param drawOrder For each slot in {@link Skeleton#slots}, the index of the new draw order. May be null to use setup pose * @param drawOrder For each slot in {@link Skeleton#slots}, the index of the new draw order. May be null to use setup pose
* draw order. */ * draw order. */
setFrame(frame: number, time: number, drawOrder: Array<number>) { setFrame (frame: number, time: number, drawOrder: Array<number>) {
this.frames[frame] = time; this.frames[frame] = time;
this.drawOrders[frame] = drawOrder; this.drawOrders[frame] = drawOrder;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
if (direction == MixDirection.mixOut) { if (direction == MixDirection.mixOut) {
if (blend == MixBlend.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;
@ -1790,19 +1790,19 @@ export class IkConstraintTimeline extends CurveTimeline {
/** The index of the IK constraint slot in {@link Skeleton#ikConstraints} that will be changed. */ /** The index of the IK constraint slot in {@link Skeleton#ikConstraints} that will be changed. */
ikConstraintIndex: number; ikConstraintIndex: number;
constructor(frameCount: number, bezierCount: number, ikConstraintIndex: number) { constructor (frameCount: number, bezierCount: number, ikConstraintIndex: number) {
super(frameCount, bezierCount, [ super(frameCount, bezierCount, [
Property.ikConstraint + "|" + ikConstraintIndex Property.ikConstraint + "|" + ikConstraintIndex
]); ]);
this.ikConstraintIndex = ikConstraintIndex; this.ikConstraintIndex = ikConstraintIndex;
} }
getFrameEntries() { getFrameEntries () {
return 6/*ENTRIES*/; return 6/*ENTRIES*/;
} }
/** Sets the time in seconds, mix, softness, bend direction, compress, and stretch for the specified key frame. */ /** Sets the time in seconds, mix, softness, bend direction, compress, and stretch for the specified key frame. */
setFrame(frame: number, time: number, mix: number, softness: number, bendDirection: number, compress: boolean, stretch: boolean) { setFrame (frame: number, time: number, mix: number, softness: number, bendDirection: number, compress: boolean, stretch: boolean) {
frame *= 6/*ENTRIES*/; frame *= 6/*ENTRIES*/;
this.frames[frame] = time; this.frames[frame] = time;
this.frames[frame + 1/*MIX*/] = mix; this.frames[frame + 1/*MIX*/] = mix;
@ -1812,7 +1812,7 @@ export class IkConstraintTimeline extends CurveTimeline {
this.frames[frame + 5/*STRETCH*/] = stretch ? 1 : 0; this.frames[frame + 5/*STRETCH*/] = stretch ? 1 : 0;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let constraint: IkConstraint = skeleton.ikConstraints[this.ikConstraintIndex]; let constraint: IkConstraint = skeleton.ikConstraints[this.ikConstraintIndex];
if (!constraint.active) return; if (!constraint.active) return;
@ -1888,19 +1888,19 @@ export class TransformConstraintTimeline extends CurveTimeline {
/** The index of the transform constraint slot in {@link Skeleton#transformConstraints} that will be changed. */ /** The index of the transform constraint slot in {@link Skeleton#transformConstraints} that will be changed. */
transformConstraintIndex: number; transformConstraintIndex: number;
constructor(frameCount: number, bezierCount: number, transformConstraintIndex: number) { constructor (frameCount: number, bezierCount: number, transformConstraintIndex: number) {
super(frameCount, bezierCount, [ super(frameCount, bezierCount, [
Property.transformConstraint + "|" + transformConstraintIndex Property.transformConstraint + "|" + transformConstraintIndex
]); ]);
this.transformConstraintIndex = transformConstraintIndex; this.transformConstraintIndex = transformConstraintIndex;
} }
getFrameEntries() { getFrameEntries () {
return 7/*ENTRIES*/; return 7/*ENTRIES*/;
} }
/** The time in seconds, rotate mix, translate mix, scale mix, and shear mix for the specified key frame. */ /** The time in seconds, rotate mix, translate mix, scale mix, and shear mix for the specified key frame. */
setFrame(frame: number, time: number, mixRotate: number, mixX: number, mixY: number, mixScaleX: number, mixScaleY: number, setFrame (frame: number, time: number, mixRotate: number, mixX: number, mixY: number, mixScaleX: number, mixScaleY: number,
mixShearY: number) { mixShearY: number) {
let frames = this.frames; let frames = this.frames;
frame *= 7/*ENTRIES*/; frame *= 7/*ENTRIES*/;
@ -1913,7 +1913,7 @@ export class TransformConstraintTimeline extends CurveTimeline {
frames[frame + 6/*SHEARY*/] = mixShearY; frames[frame + 6/*SHEARY*/] = mixShearY;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let constraint: TransformConstraint = skeleton.transformConstraints[this.transformConstraintIndex]; let constraint: TransformConstraint = skeleton.transformConstraints[this.transformConstraintIndex];
if (!constraint.active) return; if (!constraint.active) return;
@ -2001,12 +2001,12 @@ export class PathConstraintPositionTimeline extends CurveTimeline1 {
/** The index of the path constraint slot in {@link Skeleton#pathConstraints} that will be changed. */ /** The index of the path constraint slot in {@link Skeleton#pathConstraints} that will be changed. */
pathConstraintIndex: number; pathConstraintIndex: number;
constructor(frameCount: number, bezierCount: number, pathConstraintIndex: number) { constructor (frameCount: number, bezierCount: number, pathConstraintIndex: number) {
super(frameCount, bezierCount, Property.pathConstraintPosition + "|" + pathConstraintIndex); super(frameCount, bezierCount, Property.pathConstraintPosition + "|" + pathConstraintIndex);
this.pathConstraintIndex = pathConstraintIndex; this.pathConstraintIndex = pathConstraintIndex;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex]; let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex];
if (!constraint.active) return; if (!constraint.active) return;
@ -2036,12 +2036,12 @@ export class PathConstraintSpacingTimeline extends CurveTimeline1 {
/** The index of the path constraint slot in {@link Skeleton#getPathConstraints()} that will be changed. */ /** The index of the path constraint slot in {@link Skeleton#getPathConstraints()} that will be changed. */
pathConstraintIndex = 0; pathConstraintIndex = 0;
constructor(frameCount: number, bezierCount: number, pathConstraintIndex: number) { constructor (frameCount: number, bezierCount: number, pathConstraintIndex: number) {
super(frameCount, bezierCount, Property.pathConstraintSpacing + "|" + pathConstraintIndex); super(frameCount, bezierCount, Property.pathConstraintSpacing + "|" + pathConstraintIndex);
this.pathConstraintIndex = pathConstraintIndex; this.pathConstraintIndex = pathConstraintIndex;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex]; let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex];
if (!constraint.active) return; if (!constraint.active) return;
@ -2072,18 +2072,18 @@ export class PathConstraintMixTimeline extends CurveTimeline {
/** The index of the path constraint slot in {@link Skeleton#getPathConstraints()} that will be changed. */ /** The index of the path constraint slot in {@link Skeleton#getPathConstraints()} that will be changed. */
pathConstraintIndex = 0; pathConstraintIndex = 0;
constructor(frameCount: number, bezierCount: number, pathConstraintIndex: number) { constructor (frameCount: number, bezierCount: number, pathConstraintIndex: number) {
super(frameCount, bezierCount, [ super(frameCount, bezierCount, [
Property.pathConstraintMix + "|" + pathConstraintIndex Property.pathConstraintMix + "|" + pathConstraintIndex
]); ]);
this.pathConstraintIndex = pathConstraintIndex; this.pathConstraintIndex = pathConstraintIndex;
} }
getFrameEntries() { getFrameEntries () {
return 4/*ENTRIES*/; return 4/*ENTRIES*/;
} }
setFrame(frame: number, time: number, mixRotate: number, mixX: number, mixY: number) { setFrame (frame: number, time: number, mixRotate: number, mixX: number, mixY: number) {
let frames = this.frames; let frames = this.frames;
frame <<= 2; frame <<= 2;
frames[frame] = time; frames[frame] = time;
@ -2092,7 +2092,7 @@ export class PathConstraintMixTimeline extends CurveTimeline {
frames[frame + 3/*Y*/] = mixY; frames[frame + 3/*Y*/] = mixY;
} }
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex]; let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex];
if (!constraint.active) return; if (!constraint.active) return;

View File

@ -40,7 +40,7 @@ import { Event } from "./Event";
* *
* See [Applying Animations](http://esotericsoftware.com/spine-applying-animations/) in the Spine Runtimes Guide. */ * See [Applying Animations](http://esotericsoftware.com/spine-applying-animations/) in the Spine Runtimes Guide. */
export class AnimationState { export class AnimationState {
private static emptyAnimation(): Animation { private static emptyAnimation (): Animation {
if (!_emptyAnimation) _emptyAnimation = new Animation("<empty>", [], 0); if (!_emptyAnimation) _emptyAnimation = new Animation("<empty>", [], 0);
return _emptyAnimation; return _emptyAnimation;
} }
@ -66,12 +66,12 @@ export class AnimationState {
trackEntryPool = new Pool<TrackEntry>(() => new TrackEntry()); trackEntryPool = new Pool<TrackEntry>(() => new TrackEntry());
constructor(data: AnimationStateData) { constructor (data: AnimationStateData) {
this.data = data; this.data = data;
} }
/** Increments each track entry {@link TrackEntry#trackTime()}, setting queued animations as current if needed. */ /** Increments each track entry {@link TrackEntry#trackTime()}, setting queued animations as current if needed. */
update(delta: number) { update (delta: number) {
delta *= this.timeScale; delta *= this.timeScale;
let tracks = this.tracks; let tracks = this.tracks;
for (let i = 0, n = tracks.length; i < n; i++) { for (let i = 0, n = tracks.length; i < n; i++) {
@ -129,7 +129,7 @@ export class AnimationState {
} }
/** Returns true when all mixing from entries are complete. */ /** Returns true when all mixing from entries are complete. */
updateMixingFrom(to: TrackEntry, delta: number): boolean { updateMixingFrom (to: TrackEntry, delta: number): boolean {
let from = to.mixingFrom; let from = to.mixingFrom;
if (!from) return true; if (!from) return true;
@ -158,7 +158,7 @@ export class AnimationState {
/** Poses the skeleton using the track entry animations. There are no side effects other than invoking listeners, so the /** Poses the skeleton using the track entry animations. There are no side effects other than invoking listeners, so the
* animation state can be applied to multiple skeletons to pose them identically. * animation state can be applied to multiple skeletons to pose them identically.
* @returns True if any animations were applied. */ * @returns True if any animations were applied. */
apply(skeleton: Skeleton): boolean { apply (skeleton: Skeleton): boolean {
if (!skeleton) throw new Error("skeleton cannot be null."); if (!skeleton) throw new Error("skeleton cannot be null.");
if (this.animationsChanged) this._animationsChanged(); if (this.animationsChanged) this._animationsChanged();
@ -244,7 +244,7 @@ export class AnimationState {
return applied; return applied;
} }
applyMixingFrom(to: TrackEntry, skeleton: Skeleton, blend: MixBlend) { applyMixingFrom (to: TrackEntry, skeleton: Skeleton, blend: MixBlend) {
let from = to.mixingFrom; let from = to.mixingFrom;
if (from.mixingFrom) this.applyMixingFrom(from, skeleton, blend); if (from.mixingFrom) this.applyMixingFrom(from, skeleton, blend);
@ -333,7 +333,7 @@ export class AnimationState {
return mix; return mix;
} }
applyAttachmentTimeline(timeline: AttachmentTimeline, skeleton: Skeleton, time: number, blend: MixBlend, attachments: boolean) { applyAttachmentTimeline (timeline: AttachmentTimeline, skeleton: Skeleton, time: number, blend: MixBlend, attachments: boolean) {
var slot = skeleton.slots[timeline.slotIndex]; var slot = skeleton.slots[timeline.slotIndex];
if (!slot.bone.active) return; if (!slot.bone.active) return;
@ -347,12 +347,12 @@ export class AnimationState {
if (slot.attachmentState <= this.unkeyedState) slot.attachmentState = this.unkeyedState + SETUP; if (slot.attachmentState <= this.unkeyedState) slot.attachmentState = this.unkeyedState + SETUP;
} }
setAttachment(skeleton: Skeleton, slot: Slot, attachmentName: string, attachments: boolean) { setAttachment (skeleton: Skeleton, slot: Slot, attachmentName: string, attachments: boolean) {
slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(slot.data.index, attachmentName)); slot.setAttachment(!attachmentName ? null : skeleton.getAttachment(slot.data.index, attachmentName));
if (attachments) slot.attachmentState = this.unkeyedState + CURRENT; if (attachments) slot.attachmentState = this.unkeyedState + CURRENT;
} }
applyRotateTimeline(timeline: RotateTimeline, skeleton: Skeleton, time: number, alpha: number, blend: MixBlend, applyRotateTimeline (timeline: RotateTimeline, 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;
@ -410,7 +410,7 @@ export class AnimationState {
bone.rotation = r1 + total * alpha; bone.rotation = r1 + total * alpha;
} }
queueEvents(entry: TrackEntry, animationTime: number) { queueEvents (entry: TrackEntry, animationTime: number) {
let animationStart = entry.animationStart, animationEnd = entry.animationEnd; let animationStart = entry.animationStart, animationEnd = entry.animationEnd;
let duration = animationEnd - animationStart; let duration = animationEnd - animationStart;
let trackLastWrapped = entry.trackLast % duration; let trackLastWrapped = entry.trackLast % duration;
@ -445,7 +445,7 @@ export class AnimationState {
* *
* It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose, * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose,
* rather than leaving them in their current pose. */ * rather than leaving them in their current pose. */
clearTracks() { clearTracks () {
let oldDrainDisabled = this.queue.drainDisabled; let oldDrainDisabled = this.queue.drainDisabled;
this.queue.drainDisabled = true; this.queue.drainDisabled = true;
for (let i = 0, n = this.tracks.length; i < n; i++) for (let i = 0, n = this.tracks.length; i < n; i++)
@ -459,7 +459,7 @@ export class AnimationState {
* *
* It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose, * It may be desired to use {@link AnimationState#setEmptyAnimation()} to mix the skeletons back to the setup pose,
* rather than leaving them in their current pose. */ * rather than leaving them in their current pose. */
clearTrack(trackIndex: number) { clearTrack (trackIndex: number) {
if (trackIndex >= this.tracks.length) return; if (trackIndex >= this.tracks.length) return;
let current = this.tracks[trackIndex]; let current = this.tracks[trackIndex];
if (!current) return; if (!current) return;
@ -483,7 +483,7 @@ export class AnimationState {
this.queue.drain(); this.queue.drain();
} }
setCurrent(index: number, current: TrackEntry, interrupt: boolean) { setCurrent (index: number, current: TrackEntry, interrupt: boolean) {
let from = this.expandToIndex(index); let from = this.expandToIndex(index);
this.tracks[index] = current; this.tracks[index] = current;
current.previous = null; current.previous = null;
@ -507,7 +507,7 @@ export class AnimationState {
/** Sets an animation by name. /** Sets an animation by name.
* *
* See {@link #setAnimationWith()}. */ * See {@link #setAnimationWith()}. */
setAnimation(trackIndex: number, animationName: string, loop: boolean = false) { setAnimation (trackIndex: number, animationName: string, loop: boolean = false) {
let animation = this.data.skeletonData.findAnimation(animationName); let animation = this.data.skeletonData.findAnimation(animationName);
if (!animation) throw new Error("Animation not found: " + animationName); if (!animation) throw new Error("Animation not found: " + animationName);
return this.setAnimationWith(trackIndex, animation, loop); return this.setAnimationWith(trackIndex, animation, loop);
@ -519,7 +519,7 @@ export class AnimationState {
* duration. In either case {@link TrackEntry#trackEnd} determines when the track is cleared. * duration. In either case {@link TrackEntry#trackEnd} determines when the track is cleared.
* @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept
* after the {@link AnimationStateListener#dispose()} event occurs. */ * after the {@link AnimationStateListener#dispose()} event occurs. */
setAnimationWith(trackIndex: number, animation: Animation, loop: boolean = false) { setAnimationWith (trackIndex: number, animation: Animation, loop: boolean = false) {
if (!animation) throw new Error("animation cannot be null."); if (!animation) throw new Error("animation cannot be null.");
let interrupt = true; let interrupt = true;
let current = this.expandToIndex(trackIndex); let current = this.expandToIndex(trackIndex);
@ -544,7 +544,7 @@ export class AnimationState {
/** Queues an animation by name. /** Queues an animation by name.
* *
* See {@link #addAnimationWith()}. */ * See {@link #addAnimationWith()}. */
addAnimation(trackIndex: number, animationName: string, loop: boolean = false, delay: number = 0) { addAnimation (trackIndex: number, animationName: string, loop: boolean = false, delay: number = 0) {
let animation = this.data.skeletonData.findAnimation(animationName); let animation = this.data.skeletonData.findAnimation(animationName);
if (!animation) throw new Error("Animation not found: " + animationName); if (!animation) throw new Error("Animation not found: " + animationName);
return this.addAnimationWith(trackIndex, animation, loop, delay); return this.addAnimationWith(trackIndex, animation, loop, delay);
@ -558,7 +558,7 @@ export class AnimationState {
* previous entry is looping, its next loop completion is used instead of its duration. * previous entry is looping, its next loop completion is used instead of its duration.
* @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept * @returns A track entry to allow further customization of animation playback. References to the track entry must not be kept
* after the {@link AnimationStateListener#dispose()} event occurs. */ * after the {@link AnimationStateListener#dispose()} event occurs. */
addAnimationWith(trackIndex: number, animation: Animation, loop: boolean = false, delay: number = 0) { addAnimationWith (trackIndex: number, animation: Animation, loop: boolean = false, delay: number = 0) {
if (!animation) throw new Error("animation cannot be null."); if (!animation) throw new Error("animation cannot be null.");
let last = this.expandToIndex(trackIndex); let last = this.expandToIndex(trackIndex);
@ -596,7 +596,7 @@ export class AnimationState {
* {@link TrackEntry#setMixDuration()}. Mixing from an empty animation causes the new animation to be applied more and * {@link TrackEntry#setMixDuration()}. Mixing from an empty animation causes the new animation to be applied more and
* more over the mix duration. Properties keyed in the new animation transition from the value from lower tracks or from the * more over the mix duration. Properties keyed in the new animation transition from the value from lower tracks or from the
* setup pose value if no lower tracks key the property to the value keyed in the new animation. */ * setup pose value if no lower tracks key the property to the value keyed in the new animation. */
setEmptyAnimation(trackIndex: number, mixDuration: number = 0) { setEmptyAnimation (trackIndex: number, mixDuration: number = 0) {
let entry = this.setAnimationWith(trackIndex, AnimationState.emptyAnimation(), false); let entry = this.setAnimationWith(trackIndex, AnimationState.emptyAnimation(), false);
entry.mixDuration = mixDuration; entry.mixDuration = mixDuration;
entry.trackEnd = mixDuration; entry.trackEnd = mixDuration;
@ -614,7 +614,7 @@ export class AnimationState {
* loop completion is used instead of its duration. * loop completion is used instead of its duration.
* @return A track entry to allow further customization of animation playback. References to the track entry must not be kept * @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
* after the {@link AnimationStateListener#dispose()} event occurs. */ * after the {@link AnimationStateListener#dispose()} event occurs. */
addEmptyAnimation(trackIndex: number, mixDuration: number = 0, delay: number = 0) { addEmptyAnimation (trackIndex: number, mixDuration: number = 0, delay: number = 0) {
let entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation(), false, delay); let entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation(), false, delay);
if (delay <= 0) entry.delay += entry.mixDuration - mixDuration; if (delay <= 0) entry.delay += entry.mixDuration - mixDuration;
entry.mixDuration = mixDuration; entry.mixDuration = mixDuration;
@ -624,7 +624,7 @@ export class AnimationState {
/** Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix /** Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix
* duration. */ * duration. */
setEmptyAnimations(mixDuration: number = 0) { setEmptyAnimations (mixDuration: number = 0) {
let oldDrainDisabled = this.queue.drainDisabled; let oldDrainDisabled = this.queue.drainDisabled;
this.queue.drainDisabled = true; this.queue.drainDisabled = true;
for (let i = 0, n = this.tracks.length; i < n; i++) { for (let i = 0, n = this.tracks.length; i < n; i++) {
@ -635,7 +635,7 @@ export class AnimationState {
this.queue.drain(); this.queue.drain();
} }
expandToIndex(index: number) { expandToIndex (index: number) {
if (index < this.tracks.length) return this.tracks[index]; if (index < this.tracks.length) return this.tracks[index];
Utils.ensureArrayCapacity(this.tracks, index + 1, null); Utils.ensureArrayCapacity(this.tracks, index + 1, null);
this.tracks.length = index + 1; this.tracks.length = index + 1;
@ -643,7 +643,7 @@ export class AnimationState {
} }
/** @param last May be null. */ /** @param last May be null. */
trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry) { trackEntry (trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry) {
let entry = this.trackEntryPool.obtain(); let entry = this.trackEntryPool.obtain();
entry.trackIndex = trackIndex; entry.trackIndex = trackIndex;
entry.animation = animation; entry.animation = animation;
@ -675,7 +675,7 @@ export class AnimationState {
} }
/** Removes the {@link TrackEntry#getNext() next entry} and all entries after it for the specified entry. */ /** Removes the {@link TrackEntry#getNext() next entry} and all entries after it for the specified entry. */
clearNext(entry: TrackEntry) { clearNext (entry: TrackEntry) {
let next = entry.next; let next = entry.next;
while (next) { while (next) {
this.queue.dispose(next); this.queue.dispose(next);
@ -684,7 +684,7 @@ export class AnimationState {
entry.next = null; entry.next = null;
} }
_animationsChanged() { _animationsChanged () {
this.animationsChanged = false; this.animationsChanged = false;
this.propertyIDs.clear(); this.propertyIDs.clear();
@ -701,7 +701,7 @@ export class AnimationState {
} }
} }
computeHold(entry: TrackEntry) { computeHold (entry: TrackEntry) {
let to = entry.mixingTo; let to = entry.mixingTo;
let timelines = entry.animation.timelines; let timelines = entry.animation.timelines;
let timelinesCount = entry.animation.timelines.length; let timelinesCount = entry.animation.timelines.length;
@ -742,32 +742,32 @@ export class AnimationState {
} }
/** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */ /** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */
getCurrent(trackIndex: number) { getCurrent (trackIndex: number) {
if (trackIndex >= this.tracks.length) return null; if (trackIndex >= this.tracks.length) return null;
return this.tracks[trackIndex]; return this.tracks[trackIndex];
} }
/** Adds a listener to receive events for all track entries. */ /** Adds a listener to receive events for all track entries. */
addListener(listener: AnimationStateListener) { addListener (listener: AnimationStateListener) {
if (!listener) throw new Error("listener cannot be null."); if (!listener) throw new Error("listener cannot be null.");
this.listeners.push(listener); this.listeners.push(listener);
} }
/** Removes the listener added with {@link #addListener()}. */ /** Removes the listener added with {@link #addListener()}. */
removeListener(listener: AnimationStateListener) { removeListener (listener: AnimationStateListener) {
let index = this.listeners.indexOf(listener); let index = this.listeners.indexOf(listener);
if (index >= 0) this.listeners.splice(index, 1); if (index >= 0) this.listeners.splice(index, 1);
} }
/** Removes all listeners added with {@link #addListener()}. */ /** Removes all listeners added with {@link #addListener()}. */
clearListeners() { clearListeners () {
this.listeners.length = 0; this.listeners.length = 0;
} }
/** Discards all listener notifications that have not yet been delivered. This can be useful to call from an /** Discards all listener notifications that have not yet been delivered. This can be useful to call from an
* {@link AnimationStateListener} when it is known that further notifications that may have been already queued for delivery * {@link AnimationStateListener} when it is known that further notifications that may have been already queued for delivery
* are not wanted because new animations are being set. */ * are not wanted because new animations are being set. */
clearListenerNotifications() { clearListenerNotifications () {
this.queue.clear(); this.queue.clear();
} }
} }
@ -930,7 +930,7 @@ export class TrackEntry {
timelineHoldMix = new Array<TrackEntry>(); timelineHoldMix = new Array<TrackEntry>();
timelinesRotation = new Array<number>(); timelinesRotation = new Array<number>();
reset() { reset () {
this.next = null; this.next = null;
this.previous = null; this.previous = null;
this.mixingFrom = null; this.mixingFrom = null;
@ -945,7 +945,7 @@ export class TrackEntry {
/** Uses {@link #trackTime} to compute the `animationTime`, which is between {@link #animationStart} /** Uses {@link #trackTime} to compute the `animationTime`, which is between {@link #animationStart}
* and {@link #animationEnd}. When the `trackTime` is 0, the `animationTime` is equal to the * and {@link #animationEnd}. When the `trackTime` is 0, the `animationTime` is equal to the
* `animationStart` time. */ * `animationStart` time. */
getAnimationTime() { getAnimationTime () {
if (this.loop) { if (this.loop) {
let duration = this.animationEnd - this.animationStart; let duration = this.animationEnd - this.animationStart;
if (duration == 0) return this.animationStart; if (duration == 0) return this.animationStart;
@ -954,7 +954,7 @@ export class TrackEntry {
return Math.min(this.trackTime + this.animationStart, this.animationEnd); return Math.min(this.trackTime + this.animationStart, this.animationEnd);
} }
setAnimationLast(animationLast: number) { setAnimationLast (animationLast: number) {
this.animationLast = animationLast; this.animationLast = animationLast;
this.nextAnimationLast = animationLast; this.nextAnimationLast = animationLast;
} }
@ -962,7 +962,7 @@ export class TrackEntry {
/** Returns true if at least one loop has been completed. /** Returns true if at least one loop has been completed.
* *
* See {@link AnimationStateListener#complete()}. */ * See {@link AnimationStateListener#complete()}. */
isComplete() { isComplete () {
return this.trackTime >= this.animationEnd - this.animationStart; return this.trackTime >= this.animationEnd - this.animationStart;
} }
@ -973,11 +973,11 @@ export class TrackEntry {
* the short way or the long way around. The two rotations likely change over time, so which direction is the short or long * the short way or the long way around. The two rotations likely change over time, so which direction is the short or long
* way also changes. If the short way was always chosen, bones would flip to the other side when that direction became the * way also changes. If the short way was always chosen, bones would flip to the other side when that direction became the
* long way. TrackEntry chooses the short way the first time it is applied and remembers that direction. */ * long way. TrackEntry chooses the short way the first time it is applied and remembers that direction. */
resetRotationDirections() { resetRotationDirections () {
this.timelinesRotation.length = 0; this.timelinesRotation.length = 0;
} }
getTrackComplete() { getTrackComplete () {
let duration = this.animationEnd - this.animationStart; let duration = this.animationEnd - this.animationStart;
if (duration != 0) { if (duration != 0) {
if (this.loop) return duration * (1 + ((this.trackTime / duration) | 0)); // Completion of next loop. if (this.loop) return duration * (1 + ((this.trackTime / duration) | 0)); // Completion of next loop.
@ -992,44 +992,44 @@ export class EventQueue {
drainDisabled = false; drainDisabled = false;
animState: AnimationState; animState: AnimationState;
constructor(animState: AnimationState) { constructor (animState: AnimationState) {
this.animState = animState; this.animState = animState;
} }
start(entry: TrackEntry) { start (entry: TrackEntry) {
this.objects.push(EventType.start); this.objects.push(EventType.start);
this.objects.push(entry); this.objects.push(entry);
this.animState.animationsChanged = true; this.animState.animationsChanged = true;
} }
interrupt(entry: TrackEntry) { interrupt (entry: TrackEntry) {
this.objects.push(EventType.interrupt); this.objects.push(EventType.interrupt);
this.objects.push(entry); this.objects.push(entry);
} }
end(entry: TrackEntry) { end (entry: TrackEntry) {
this.objects.push(EventType.end); this.objects.push(EventType.end);
this.objects.push(entry); this.objects.push(entry);
this.animState.animationsChanged = true; this.animState.animationsChanged = true;
} }
dispose(entry: TrackEntry) { dispose (entry: TrackEntry) {
this.objects.push(EventType.dispose); this.objects.push(EventType.dispose);
this.objects.push(entry); this.objects.push(entry);
} }
complete(entry: TrackEntry) { complete (entry: TrackEntry) {
this.objects.push(EventType.complete); this.objects.push(EventType.complete);
this.objects.push(entry); this.objects.push(entry);
} }
event(entry: TrackEntry, event: Event) { event (entry: TrackEntry, event: Event) {
this.objects.push(EventType.event); this.objects.push(EventType.event);
this.objects.push(entry); this.objects.push(entry);
this.objects.push(event); this.objects.push(event);
} }
drain() { drain () {
if (this.drainDisabled) return; if (this.drainDisabled) return;
this.drainDisabled = true; this.drainDisabled = true;
@ -1079,7 +1079,7 @@ export class EventQueue {
this.drainDisabled = false; this.drainDisabled = false;
} }
clear() { clear () {
this.objects.length = 0; this.objects.length = 0;
} }
} }
@ -1095,43 +1095,43 @@ export enum EventType {
* {@link AnimationState#addListener()}. */ * {@link AnimationState#addListener()}. */
export interface AnimationStateListener { export interface AnimationStateListener {
/** Invoked when this entry has been set as the current entry. */ /** Invoked when this entry has been set as the current entry. */
start(entry: TrackEntry): void; start (entry: TrackEntry): void;
/** Invoked when another entry has replaced this entry as the current entry. This entry may continue being applied for /** Invoked when another entry has replaced this entry as the current entry. This entry may continue being applied for
* mixing. */ * mixing. */
interrupt(entry: TrackEntry): void; interrupt (entry: TrackEntry): void;
/** Invoked when this entry is no longer the current entry and will never be applied again. */ /** Invoked when this entry is no longer the current entry and will never be applied again. */
end(entry: TrackEntry): void; end (entry: TrackEntry): void;
/** Invoked when this entry will be disposed. This may occur without the entry ever being set as the current entry. /** 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. */ * References to the entry should not be kept after dispose is called, as it may be destroyed or reused. */
dispose(entry: TrackEntry): void; dispose (entry: TrackEntry): void;
/** Invoked every time this entry's animation completes a loop. */ /** Invoked every time this entry's animation completes a loop. */
complete(entry: TrackEntry): void; complete (entry: TrackEntry): void;
/** Invoked when this entry's animation triggers an event. */ /** Invoked when this entry's animation triggers an event. */
event(entry: TrackEntry, event: Event): void; event (entry: TrackEntry, event: Event): void;
} }
export abstract class AnimationStateAdapter implements AnimationStateListener { export abstract class AnimationStateAdapter implements AnimationStateListener {
start(entry: TrackEntry) { start (entry: TrackEntry) {
} }
interrupt(entry: TrackEntry) { interrupt (entry: TrackEntry) {
} }
end(entry: TrackEntry) { end (entry: TrackEntry) {
} }
dispose(entry: TrackEntry) { dispose (entry: TrackEntry) {
} }
complete(entry: TrackEntry) { complete (entry: TrackEntry) {
} }
event(entry: TrackEntry, event: Event) { event (entry: TrackEntry, event: Event) {
} }
} }

View File

@ -42,7 +42,7 @@ export class AnimationStateData {
/** The mix duration to use when no mix duration has been defined between two animations. */ /** The mix duration to use when no mix duration has been defined between two animations. */
defaultMix = 0; defaultMix = 0;
constructor(skeletonData: SkeletonData) { constructor (skeletonData: SkeletonData) {
if (!skeletonData) throw new Error("skeletonData cannot be null."); if (!skeletonData) throw new Error("skeletonData cannot be null.");
this.skeletonData = skeletonData; this.skeletonData = skeletonData;
} }
@ -50,7 +50,7 @@ export class AnimationStateData {
/** Sets a mix duration by animation name. /** Sets a mix duration by animation name.
* *
* See {@link #setMixWith()}. */ * See {@link #setMixWith()}. */
setMix(fromName: string, toName: string, duration: number) { setMix (fromName: string, toName: string, duration: number) {
let from = this.skeletonData.findAnimation(fromName); let from = this.skeletonData.findAnimation(fromName);
if (!from) throw new Error("Animation not found: " + fromName); if (!from) throw new Error("Animation not found: " + fromName);
let to = this.skeletonData.findAnimation(toName); let to = this.skeletonData.findAnimation(toName);
@ -61,7 +61,7 @@ export class AnimationStateData {
/** Sets the mix duration when changing from the specified animation to the other. /** Sets the mix duration when changing from the specified animation to the other.
* *
* See {@link TrackEntry#mixDuration}. */ * See {@link TrackEntry#mixDuration}. */
setMixWith(from: Animation, to: Animation, duration: number) { setMixWith (from: Animation, to: Animation, duration: number) {
if (!from) throw new Error("from cannot be null."); if (!from) throw new Error("from cannot be null.");
if (!to) throw new Error("to cannot be null."); if (!to) throw new Error("to cannot be null.");
let key = from.name + "." + to.name; let key = from.name + "." + to.name;
@ -70,7 +70,7 @@ export class AnimationStateData {
/** Returns the mix duration to use when changing from the specified animation to the other, or the {@link #defaultMix} if /** Returns the mix duration to use when changing from the specified animation to the other, or the {@link #defaultMix} if
* no mix duration has been set. */ * no mix duration has been set. */
getMix(from: Animation, to: Animation) { getMix (from: Animation, to: Animation) {
let key = from.name + "." + to.name; let key = from.name + "." + to.name;
let value = this.animationToMixTime[key]; let value = this.animationToMixTime[key];
return value === undefined ? this.defaultMix : value; return value === undefined ? this.defaultMix : value;

View File

@ -40,36 +40,36 @@ export class AssetManagerBase implements Disposable {
private toLoad = 0; private toLoad = 0;
private loaded = 0; private loaded = 0;
constructor(textureLoader: (image: HTMLImageElement | ImageBitmap) => Texture, pathPrefix: string = "", downloader: Downloader = null) { constructor (textureLoader: (image: HTMLImageElement | ImageBitmap) => Texture, pathPrefix: string = "", downloader: Downloader = null) {
this.textureLoader = textureLoader; this.textureLoader = textureLoader;
this.pathPrefix = pathPrefix; this.pathPrefix = pathPrefix;
this.downloader = downloader || new Downloader(); this.downloader = downloader || new Downloader();
} }
private start(path: string): string { private start (path: string): string {
this.toLoad++; this.toLoad++;
return this.pathPrefix + path; return this.pathPrefix + path;
} }
private success(callback: (path: string, data: any) => void, path: string, asset: any) { private success (callback: (path: string, data: any) => void, path: string, asset: any) {
this.toLoad--; this.toLoad--;
this.loaded++; this.loaded++;
this.assets[path] = asset; this.assets[path] = asset;
if (callback) callback(path, asset); if (callback) callback(path, asset);
} }
private error(callback: (path: string, message: string) => void, path: string, message: string) { private error (callback: (path: string, message: string) => void, path: string, message: string) {
this.toLoad--; this.toLoad--;
this.loaded++; this.loaded++;
this.errors[path] = message; this.errors[path] = message;
if (callback) callback(path, message); if (callback) callback(path, message);
} }
setRawDataURI(path: string, data: string) { setRawDataURI (path: string, data: string) {
this.downloader.rawDataUris[this.pathPrefix + path] = data; this.downloader.rawDataUris[this.pathPrefix + path] = data;
} }
loadBinary(path: string, loadBinary (path: string,
success: (path: string, binary: Uint8Array) => void = null, success: (path: string, binary: Uint8Array) => void = null,
error: (path: string, message: string) => void = null) { error: (path: string, message: string) => void = null) {
path = this.start(path); path = this.start(path);
@ -81,7 +81,7 @@ export class AssetManagerBase implements Disposable {
}); });
} }
loadText(path: string, loadText (path: string,
success: (path: string, text: string) => void = null, success: (path: string, text: string) => void = null,
error: (path: string, message: string) => void = null) { error: (path: string, message: string) => void = null) {
path = this.start(path); path = this.start(path);
@ -93,7 +93,7 @@ export class AssetManagerBase implements Disposable {
}); });
} }
loadJson(path: string, loadJson (path: string,
success: (path: string, object: object) => void = null, success: (path: string, object: object) => void = null,
error: (path: string, message: string) => void = null) { error: (path: string, message: string) => void = null) {
path = this.start(path); path = this.start(path);
@ -105,7 +105,7 @@ export class AssetManagerBase implements Disposable {
}); });
} }
loadTexture(path: string, loadTexture (path: string,
success: (path: string, texture: Texture) => void = null, success: (path: string, texture: Texture) => void = null,
error: (path: string, message: string) => void = null) { error: (path: string, message: string) => void = null) {
path = this.start(path); path = this.start(path);
@ -136,7 +136,7 @@ export class AssetManagerBase implements Disposable {
} }
} }
loadTextureAtlas(path: string, loadTextureAtlas (path: string,
success: (path: string, atlas: TextureAtlas) => void = null, success: (path: string, atlas: TextureAtlas) => void = null,
error: (path: string, message: string) => void = null error: (path: string, message: string) => void = null
) { ) {
@ -170,11 +170,11 @@ export class AssetManagerBase implements Disposable {
}); });
} }
get(path: string) { get (path: string) {
return this.assets[this.pathPrefix + path]; return this.assets[this.pathPrefix + path];
} }
require(path: string) { require (path: string) {
path = this.pathPrefix + path; path = this.pathPrefix + path;
let asset = this.assets[path]; let asset = this.assets[path];
if (asset) return asset; if (asset) return asset;
@ -182,7 +182,7 @@ export class AssetManagerBase implements Disposable {
throw Error("Asset not found: " + path + (error ? "\n" + error : "")); throw Error("Asset not found: " + path + (error ? "\n" + error : ""));
} }
remove(path: string) { remove (path: string) {
path = this.pathPrefix + path; path = this.pathPrefix + path;
let asset = this.assets[path]; let asset = this.assets[path];
if ((<any>asset).dispose) (<any>asset).dispose(); if ((<any>asset).dispose) (<any>asset).dispose();
@ -190,7 +190,7 @@ export class AssetManagerBase implements Disposable {
return asset; return asset;
} }
removeAll() { removeAll () {
for (let key in this.assets) { for (let key in this.assets) {
let asset = this.assets[key]; let asset = this.assets[key];
if ((<any>asset).dispose) (<any>asset).dispose(); if ((<any>asset).dispose) (<any>asset).dispose();
@ -198,27 +198,27 @@ export class AssetManagerBase implements Disposable {
this.assets = {}; this.assets = {};
} }
isLoadingComplete(): boolean { isLoadingComplete (): boolean {
return this.toLoad == 0; return this.toLoad == 0;
} }
getToLoad(): number { getToLoad (): number {
return this.toLoad; return this.toLoad;
} }
getLoaded(): number { getLoaded (): number {
return this.loaded; return this.loaded;
} }
dispose() { dispose () {
this.removeAll(); this.removeAll();
} }
hasErrors() { hasErrors () {
return Object.keys(this.errors).length > 0; return Object.keys(this.errors).length > 0;
} }
getErrors() { getErrors () {
return this.errors; return this.errors;
} }
} }
@ -227,7 +227,7 @@ export class Downloader {
private callbacks: StringMap<Array<Function>> = {}; private callbacks: StringMap<Array<Function>> = {};
rawDataUris: StringMap<string> = {}; rawDataUris: StringMap<string> = {};
downloadText(url: string, success: (data: string) => void, error: (status: number, responseText: string) => void) { downloadText (url: string, success: (data: string) => void, error: (status: number, responseText: string) => void) {
if (this.rawDataUris[url]) url = this.rawDataUris[url]; if (this.rawDataUris[url]) url = this.rawDataUris[url];
if (this.start(url, success, error)) return; if (this.start(url, success, error)) return;
let request = new XMLHttpRequest(); let request = new XMLHttpRequest();
@ -241,13 +241,13 @@ export class Downloader {
request.send(); request.send();
} }
downloadJson(url: string, success: (data: object) => void, error: (status: number, responseText: string) => void) { downloadJson (url: string, success: (data: object) => void, error: (status: number, responseText: string) => void) {
this.downloadText(url, (data: string): void => { this.downloadText(url, (data: string): void => {
success(JSON.parse(data)); success(JSON.parse(data));
}, error); }, error);
} }
downloadBinary(url: string, success: (data: Uint8Array) => void, error: (status: number, responseText: string) => void) { downloadBinary (url: string, success: (data: Uint8Array) => void, error: (status: number, responseText: string) => void) {
if (this.rawDataUris[url]) url = this.rawDataUris[url]; if (this.rawDataUris[url]) url = this.rawDataUris[url];
if (this.start(url, success, error)) return; if (this.start(url, success, error)) return;
let request = new XMLHttpRequest(); let request = new XMLHttpRequest();
@ -266,7 +266,7 @@ export class Downloader {
request.send(); request.send();
} }
private start(url: string, success: any, error: any) { private start (url: string, success: any, error: any) {
let callbacks = this.callbacks[url]; let callbacks = this.callbacks[url];
try { try {
if (callbacks) return true; if (callbacks) return true;
@ -276,7 +276,7 @@ export class Downloader {
} }
} }
private finish(url: string, status: number, data: any) { private finish (url: string, status: number, data: any) {
let callbacks = this.callbacks[url]; let callbacks = this.callbacks[url];
delete this.callbacks[url]; delete this.callbacks[url];
let args = status == 200 ? [data] : [status, data]; let args = status == 200 ? [data] : [status, data];

View File

@ -44,11 +44,11 @@ import { TextureAtlas } from "./TextureAtlas";
export class AtlasAttachmentLoader implements AttachmentLoader { export class AtlasAttachmentLoader implements AttachmentLoader {
atlas: TextureAtlas; atlas: TextureAtlas;
constructor(atlas: TextureAtlas) { constructor (atlas: TextureAtlas) {
this.atlas = atlas; this.atlas = atlas;
} }
newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment { newRegionAttachment (skin: Skin, name: string, path: string): RegionAttachment {
let region = this.atlas.findRegion(path); let region = this.atlas.findRegion(path);
if (!region) throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")"); if (!region) throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")");
region.renderObject = region; region.renderObject = region;
@ -57,7 +57,7 @@ export class AtlasAttachmentLoader implements AttachmentLoader {
return attachment; return attachment;
} }
newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment { newMeshAttachment (skin: Skin, name: string, path: string): MeshAttachment {
let region = this.atlas.findRegion(path); let region = this.atlas.findRegion(path);
if (!region) throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")"); if (!region) throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")");
region.renderObject = region; region.renderObject = region;
@ -66,19 +66,19 @@ export class AtlasAttachmentLoader implements AttachmentLoader {
return attachment; return attachment;
} }
newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment { newBoundingBoxAttachment (skin: Skin, name: string): BoundingBoxAttachment {
return new BoundingBoxAttachment(name); return new BoundingBoxAttachment(name);
} }
newPathAttachment(skin: Skin, name: string): PathAttachment { newPathAttachment (skin: Skin, name: string): PathAttachment {
return new PathAttachment(name); return new PathAttachment(name);
} }
newPointAttachment(skin: Skin, name: string): PointAttachment { newPointAttachment (skin: Skin, name: string): PointAttachment {
return new PointAttachment(name); return new PointAttachment(name);
} }
newClippingAttachment(skin: Skin, name: string): ClippingAttachment { newClippingAttachment (skin: Skin, name: string): ClippingAttachment {
return new ClippingAttachment(name); return new ClippingAttachment(name);
} }
} }

View File

@ -114,7 +114,7 @@ export class Bone implements Updatable {
active = false; active = false;
/** @param parent May be null. */ /** @param parent May be null. */
constructor(data: BoneData, skeleton: Skeleton, parent: Bone) { constructor (data: BoneData, skeleton: Skeleton, parent: Bone) {
if (!data) throw new Error("data cannot be null."); if (!data) throw new Error("data cannot be null.");
if (!skeleton) throw new Error("skeleton cannot be null."); if (!skeleton) throw new Error("skeleton cannot be null.");
this.data = data; this.data = data;
@ -125,19 +125,19 @@ export class Bone implements Updatable {
/** Returns false when the bone has not been computed because {@link BoneData#skinRequired} is true and the /** Returns false when the bone has not been computed because {@link BoneData#skinRequired} is true and the
* {@link Skeleton#skin active skin} does not {@link Skin#bones contain} this bone. */ * {@link Skeleton#skin active skin} does not {@link Skin#bones contain} this bone. */
isActive() { isActive () {
return this.active; return this.active;
} }
/** Computes the world transform using the parent bone and this bone's local applied transform. */ /** Computes the world transform using the parent bone and this bone's local applied transform. */
update() { update () {
this.updateWorldTransformWith(this.ax, this.ay, this.arotation, this.ascaleX, this.ascaleY, this.ashearX, this.ashearY); this.updateWorldTransformWith(this.ax, this.ay, this.arotation, this.ascaleX, this.ascaleY, this.ashearX, this.ashearY);
} }
/** Computes the world transform using the parent bone and this bone's local transform. /** Computes the world transform using the parent bone and this bone's local transform.
* *
* See {@link #updateWorldTransformWith()}. */ * See {@link #updateWorldTransformWith()}. */
updateWorldTransform() { updateWorldTransform () {
this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY);
} }
@ -146,7 +146,7 @@ export class Bone implements Updatable {
* *
* See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine * See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine
* Runtimes Guide. */ * Runtimes Guide. */
updateWorldTransformWith(x: number, y: number, rotation: number, scaleX: number, scaleY: number, shearX: number, shearY: number) { updateWorldTransformWith (x: number, y: number, rotation: number, scaleX: number, scaleY: number, shearX: number, shearY: number) {
this.ax = x; this.ax = x;
this.ay = y; this.ay = y;
this.arotation = rotation; this.arotation = rotation;
@ -256,7 +256,7 @@ export class Bone implements Updatable {
} }
/** Sets this bone's local transform to the setup pose. */ /** Sets this bone's local transform to the setup pose. */
setToSetupPose() { setToSetupPose () {
let data = this.data; let data = this.data;
this.x = data.x; this.x = data.x;
this.y = data.y; this.y = data.y;
@ -268,22 +268,22 @@ export class Bone implements Updatable {
} }
/** The world rotation for the X axis, calculated using {@link #a} and {@link #c}. */ /** The world rotation for the X axis, calculated using {@link #a} and {@link #c}. */
getWorldRotationX() { getWorldRotationX () {
return Math.atan2(this.c, this.a) * MathUtils.radDeg; return Math.atan2(this.c, this.a) * MathUtils.radDeg;
} }
/** The world rotation for the Y axis, calculated using {@link #b} and {@link #d}. */ /** The world rotation for the Y axis, calculated using {@link #b} and {@link #d}. */
getWorldRotationY() { getWorldRotationY () {
return Math.atan2(this.d, this.b) * MathUtils.radDeg; return Math.atan2(this.d, this.b) * MathUtils.radDeg;
} }
/** The magnitude (always positive) of the world scale X, calculated using {@link #a} and {@link #c}. */ /** The magnitude (always positive) of the world scale X, calculated using {@link #a} and {@link #c}. */
getWorldScaleX() { getWorldScaleX () {
return Math.sqrt(this.a * this.a + this.c * this.c); return Math.sqrt(this.a * this.a + this.c * this.c);
} }
/** The magnitude (always positive) of the world scale Y, calculated using {@link #b} and {@link #d}. */ /** The magnitude (always positive) of the world scale Y, calculated using {@link #b} and {@link #d}. */
getWorldScaleY() { getWorldScaleY () {
return Math.sqrt(this.b * this.b + this.d * this.d); return Math.sqrt(this.b * this.b + this.d * this.d);
} }
@ -295,7 +295,7 @@ export class Bone implements Updatable {
* *
* Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. The applied transform after * Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. The applied transform after
* calling this method is equivalent to the local transform used to compute the world transform, but may not be identical. */ * calling this method is equivalent to the local transform used to compute the world transform, but may not be identical. */
updateAppliedTransform() { updateAppliedTransform () {
let parent = this.parent; let parent = this.parent;
if (!parent) { if (!parent) {
this.ax = this.worldX; this.ax = this.worldX;
@ -336,7 +336,7 @@ export class Bone implements Updatable {
} }
/** Transforms a point from world coordinates to the bone's local coordinates. */ /** Transforms a point from world coordinates to the bone's local coordinates. */
worldToLocal(world: Vector2) { worldToLocal (world: Vector2) {
let invDet = 1 / (this.a * this.d - this.b * this.c); let invDet = 1 / (this.a * this.d - this.b * this.c);
let x = world.x - this.worldX, y = world.y - this.worldY; let x = world.x - this.worldX, y = world.y - this.worldY;
world.x = x * this.d * invDet - y * this.b * invDet; world.x = x * this.d * invDet - y * this.b * invDet;
@ -345,7 +345,7 @@ export class Bone implements Updatable {
} }
/** Transforms a point from the bone's local coordinates to world coordinates. */ /** Transforms a point from the bone's local coordinates to world coordinates. */
localToWorld(local: Vector2) { localToWorld (local: Vector2) {
let x = local.x, y = local.y; let x = local.x, y = local.y;
local.x = x * this.a + y * this.b + this.worldX; local.x = x * this.a + y * this.b + this.worldX;
local.y = x * this.c + y * this.d + this.worldY; local.y = x * this.c + y * this.d + this.worldY;
@ -353,13 +353,13 @@ export class Bone implements Updatable {
} }
/** Transforms a world rotation to a local rotation. */ /** Transforms a world rotation to a local rotation. */
worldToLocalRotation(worldRotation: number) { worldToLocalRotation (worldRotation: number) {
let sin = MathUtils.sinDeg(worldRotation), cos = MathUtils.cosDeg(worldRotation); let sin = MathUtils.sinDeg(worldRotation), cos = MathUtils.cosDeg(worldRotation);
return Math.atan2(this.a * sin - this.c * cos, this.d * cos - this.b * sin) * MathUtils.radDeg + this.rotation - this.shearX; return Math.atan2(this.a * sin - this.c * cos, this.d * cos - this.b * sin) * MathUtils.radDeg + this.rotation - this.shearX;
} }
/** Transforms a local rotation to a world rotation. */ /** Transforms a local rotation to a world rotation. */
localToWorldRotation(localRotation: number) { localToWorldRotation (localRotation: number) {
localRotation -= this.rotation - this.shearX; localRotation -= this.rotation - this.shearX;
let sin = MathUtils.sinDeg(localRotation), cos = MathUtils.cosDeg(localRotation); let sin = MathUtils.sinDeg(localRotation), cos = MathUtils.cosDeg(localRotation);
return Math.atan2(cos * this.c + sin * this.d, cos * this.a + sin * this.b) * MathUtils.radDeg; return Math.atan2(cos * this.c + sin * this.d, cos * this.a + sin * this.b) * MathUtils.radDeg;
@ -369,7 +369,7 @@ export class Bone implements Updatable {
* <p> * <p>
* After changes are made to the world transform, {@link #updateAppliedTransform()} should be called and {@link #update()} will * After changes are made to the world transform, {@link #updateAppliedTransform()} should be called and {@link #update()} will
* need to be called on any child bones, recursively. */ * need to be called on any child bones, recursively. */
rotateWorld(degrees: number) { rotateWorld (degrees: number) {
let a = this.a, b = this.b, c = this.c, d = this.d; let a = this.a, b = this.b, c = this.c, d = this.d;
let cos = MathUtils.cosDeg(degrees), sin = MathUtils.sinDeg(degrees); let cos = MathUtils.cosDeg(degrees), sin = MathUtils.sinDeg(degrees);
this.a = cos * a - sin * c; this.a = cos * a - sin * c;

View File

@ -76,7 +76,7 @@ export class BoneData {
* rendered at runtime. */ * rendered at runtime. */
color = new Color(); color = new Color();
constructor(index: number, name: string, parent: BoneData) { constructor (index: number, name: string, parent: BoneData) {
if (index < 0) throw new Error("index must be >= 0."); if (index < 0) throw new Error("index must be >= 0.");
if (!name) throw new Error("name cannot be null."); if (!name) throw new Error("name cannot be null.");
this.index = index; this.index = index;

View File

@ -29,5 +29,5 @@
/** The base class for all constraint datas. */ /** The base class for all constraint datas. */
export abstract class ConstraintData { export abstract class ConstraintData {
constructor(public name: string, public order: number, public skinRequired: boolean) { } constructor (public name: string, public order: number, public skinRequired: boolean) { }
} }

View File

@ -43,7 +43,7 @@ export class Event {
volume: number; volume: number;
balance: number; balance: number;
constructor(time: number, data: EventData) { constructor (time: number, data: EventData) {
if (!data) throw new Error("data cannot be null."); if (!data) throw new Error("data cannot be null.");
this.time = time; this.time = time;
this.data = data; this.data = data;

View File

@ -39,7 +39,7 @@ export class EventData {
volume: number; volume: number;
balance: number; balance: number;
constructor(name: string) { constructor (name: string) {
this.name = name; this.name = name;
} }
} }

View File

@ -65,7 +65,7 @@ export class IkConstraint implements Updatable {
softness = 0; softness = 0;
active = false; active = false;
constructor(data: IkConstraintData, skeleton: Skeleton) { constructor (data: IkConstraintData, skeleton: Skeleton) {
if (!data) throw new Error("data cannot be null."); if (!data) throw new Error("data cannot be null.");
if (!skeleton) throw new Error("skeleton cannot be null."); if (!skeleton) throw new Error("skeleton cannot be null.");
this.data = data; this.data = data;
@ -81,11 +81,11 @@ export class IkConstraint implements Updatable {
this.target = skeleton.findBone(data.target.name); this.target = skeleton.findBone(data.target.name);
} }
isActive() { isActive () {
return this.active; return this.active;
} }
update() { update () {
if (this.mix == 0) return; if (this.mix == 0) return;
let target = this.target; let target = this.target;
let bones = this.bones; let bones = this.bones;
@ -100,7 +100,7 @@ export class IkConstraint implements Updatable {
} }
/** Applies 1 bone IK. The target is specified in the world coordinate system. */ /** Applies 1 bone IK. The target is specified in the world coordinate system. */
apply1(bone: Bone, targetX: number, targetY: number, compress: boolean, stretch: boolean, uniform: boolean, alpha: number) { apply1 (bone: Bone, targetX: number, targetY: number, compress: boolean, stretch: boolean, uniform: boolean, alpha: number) {
let p = bone.parent; let p = bone.parent;
let pa = p.a, pb = p.b, pc = p.c, pd = p.d; let pa = p.a, pb = p.b, pc = p.c, pd = p.d;
let rotationIK = -bone.ashearX - bone.arotation, tx = 0, ty = 0; let rotationIK = -bone.ashearX - bone.arotation, tx = 0, ty = 0;
@ -151,7 +151,7 @@ export class IkConstraint implements Updatable {
/** Applies 2 bone IK. The target is specified in the world coordinate system. /** Applies 2 bone IK. The target is specified in the world coordinate system.
* @param child A direct descendant of the parent bone. */ * @param child A direct descendant of the parent bone. */
apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, stretch: boolean, uniform: boolean, softness: number, alpha: number) { apply2 (parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, stretch: boolean, uniform: boolean, softness: number, alpha: number) {
let px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, sx = psx, sy = psy, csx = child.ascaleX; let px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, sx = psx, sy = psy, csx = child.ascaleX;
let os1 = 0, os2 = 0, s2 = 0; let os1 = 0, os2 = 0, s2 = 0;
if (psx < 0) { if (psx < 0) {

View File

@ -61,7 +61,7 @@ export class IkConstraintData extends ConstraintData {
/** For two bone IK, the distance from the maximum reach of the bones that rotation will slow. */ /** For two bone IK, the distance from the maximum reach of the bones that rotation will slow. */
softness = 0; softness = 0;
constructor(name: string) { constructor (name: string) {
super(name, 0, false); super(name, 0, false);
} }
} }

View File

@ -71,7 +71,7 @@ export class PathConstraint implements Updatable {
active = false; active = false;
constructor(data: PathConstraintData, skeleton: Skeleton) { constructor (data: PathConstraintData, skeleton: Skeleton) {
if (!data) throw new Error("data cannot be null."); if (!data) throw new Error("data cannot be null.");
if (!skeleton) throw new Error("skeleton cannot be null."); if (!skeleton) throw new Error("skeleton cannot be null.");
this.data = data; this.data = data;
@ -86,11 +86,11 @@ export class PathConstraint implements Updatable {
this.mixY = data.mixY; this.mixY = data.mixY;
} }
isActive() { isActive () {
return this.active; return this.active;
} }
update() { update () {
let attachment = this.target.getAttachment(); let attachment = this.target.getAttachment();
if (!(attachment instanceof PathAttachment)) return; if (!(attachment instanceof PathAttachment)) return;
@ -219,7 +219,7 @@ export class PathConstraint implements Updatable {
} }
} }
computeWorldPositions(path: PathAttachment, spacesCount: number, tangents: boolean) { computeWorldPositions (path: PathAttachment, spacesCount: number, tangents: boolean) {
let target = this.target; let target = this.target;
let position = this.position; let position = this.position;
let spaces = this.spaces, out = Utils.setArraySize(this.positions, spacesCount * 3 + 2), world: Array<number> = null; let spaces = this.spaces, out = Utils.setArraySize(this.positions, spacesCount * 3 + 2), world: Array<number> = null;
@ -452,21 +452,21 @@ export class PathConstraint implements Updatable {
return out; return out;
} }
addBeforePosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number) { addBeforePosition (p: number, temp: Array<number>, i: number, out: Array<number>, o: number) {
let x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx); let x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx);
out[o] = x1 + p * Math.cos(r); out[o] = x1 + p * Math.cos(r);
out[o + 1] = y1 + p * Math.sin(r); out[o + 1] = y1 + p * Math.sin(r);
out[o + 2] = r; out[o + 2] = r;
} }
addAfterPosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number) { addAfterPosition (p: number, temp: Array<number>, i: number, out: Array<number>, o: number) {
let x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx); let x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx);
out[o] = x1 + p * Math.cos(r); out[o] = x1 + p * Math.cos(r);
out[o + 1] = y1 + p * Math.sin(r); out[o + 1] = y1 + p * Math.sin(r);
out[o + 2] = r; out[o + 2] = r;
} }
addCurvePosition(p: number, x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, addCurvePosition (p: number, x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number,
out: Array<number>, o: number, tangents: boolean) { out: Array<number>, o: number, tangents: boolean) {
if (p == 0 || isNaN(p)) { if (p == 0 || isNaN(p)) {
out[o] = x1; out[o] = x1;

View File

@ -65,7 +65,7 @@ export class PathConstraintData extends ConstraintData {
mixX = 0; mixX = 0;
mixY = 0; mixY = 0;
constructor(name: string) { constructor (name: string) {
super(name, 0, false); super(name, 0, false);
} }
} }

View File

@ -94,7 +94,7 @@ export class Skeleton {
/** Sets the skeleton Y position, which is added to the root bone worldY position. */ /** Sets the skeleton Y position, which is added to the root bone worldY position. */
y = 0; y = 0;
constructor(data: SkeletonData) { constructor (data: SkeletonData) {
if (!data) throw new Error("data cannot be null."); if (!data) throw new Error("data cannot be null.");
this.data = data; this.data = data;
@ -146,7 +146,7 @@ export class Skeleton {
/** Caches information about bones and constraints. Must be called if the {@link #getSkin()} is modified or if bones, /** Caches information about bones and constraints. Must be called if the {@link #getSkin()} is modified or if bones,
* constraints, or weighted path attachments are added or removed. */ * constraints, or weighted path attachments are added or removed. */
updateCache() { updateCache () {
let updateCache = this._updateCache; let updateCache = this._updateCache;
updateCache.length = 0; updateCache.length = 0;
@ -205,7 +205,7 @@ export class Skeleton {
this.sortBone(bones[i]); this.sortBone(bones[i]);
} }
sortIkConstraint(constraint: IkConstraint) { sortIkConstraint (constraint: IkConstraint) {
constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true))); constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true)));
if (!constraint.active) return; if (!constraint.active) return;
@ -230,7 +230,7 @@ export class Skeleton {
} }
} }
sortPathConstraint(constraint: PathConstraint) { sortPathConstraint (constraint: PathConstraint) {
constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true))); constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true)));
if (!constraint.active) return; if (!constraint.active) return;
@ -259,7 +259,7 @@ export class Skeleton {
constrained[i].sorted = true; constrained[i].sorted = true;
} }
sortTransformConstraint(constraint: TransformConstraint) { sortTransformConstraint (constraint: TransformConstraint) {
constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true))); constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin && Utils.contains(this.skin.constraints, constraint.data, true)));
if (!constraint.active) return; if (!constraint.active) return;
@ -287,7 +287,7 @@ export class Skeleton {
constrained[i].sorted = true; constrained[i].sorted = true;
} }
sortPathConstraintAttachment(skin: Skin, slotIndex: number, slotBone: Bone) { sortPathConstraintAttachment (skin: Skin, slotIndex: number, slotBone: Bone) {
let attachments = skin.attachments[slotIndex]; let attachments = skin.attachments[slotIndex];
if (!attachments) return; if (!attachments) return;
for (let key in attachments) { for (let key in attachments) {
@ -295,7 +295,7 @@ export class Skeleton {
} }
} }
sortPathConstraintAttachmentWith(attachment: Attachment, slotBone: Bone) { sortPathConstraintAttachmentWith (attachment: Attachment, slotBone: Bone) {
if (!(attachment instanceof PathAttachment)) return; if (!(attachment instanceof PathAttachment)) return;
let pathBones = (<PathAttachment>attachment).bones; let pathBones = (<PathAttachment>attachment).bones;
if (!pathBones) if (!pathBones)
@ -311,7 +311,7 @@ export class Skeleton {
} }
} }
sortBone(bone: Bone) { sortBone (bone: Bone) {
if (bone.sorted) return; if (bone.sorted) return;
let parent = bone.parent; let parent = bone.parent;
if (parent) this.sortBone(parent); if (parent) this.sortBone(parent);
@ -319,7 +319,7 @@ export class Skeleton {
this._updateCache.push(bone); this._updateCache.push(bone);
} }
sortReset(bones: Array<Bone>) { sortReset (bones: Array<Bone>) {
for (let i = 0, n = bones.length; i < n; i++) { for (let i = 0, n = bones.length; i < n; i++) {
let bone = bones[i]; let bone = bones[i];
if (!bone.active) continue; if (!bone.active) continue;
@ -332,7 +332,7 @@ export class Skeleton {
* *
* See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine * See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine
* Runtimes Guide. */ * Runtimes Guide. */
updateWorldTransform() { updateWorldTransform () {
let bones = this.bones; let bones = this.bones;
for (let i = 0, n = bones.length; i < n; i++) { for (let i = 0, n = bones.length; i < n; i++) {
let bone = bones[i]; let bone = bones[i];
@ -350,7 +350,7 @@ export class Skeleton {
updateCache[i].update(); updateCache[i].update();
} }
updateWorldTransformWith(parent: Bone) { updateWorldTransformWith (parent: Bone) {
// Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection. // Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection.
let rootBone = this.getRootBone(); let rootBone = this.getRootBone();
let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d; let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d;
@ -376,13 +376,13 @@ export class Skeleton {
} }
/** Sets the bones, constraints, and slots to their setup pose values. */ /** Sets the bones, constraints, and slots to their setup pose values. */
setToSetupPose() { setToSetupPose () {
this.setBonesToSetupPose(); this.setBonesToSetupPose();
this.setSlotsToSetupPose(); this.setSlotsToSetupPose();
} }
/** Sets the bones and constraints to their setup pose values. */ /** Sets the bones and constraints to their setup pose values. */
setBonesToSetupPose() { setBonesToSetupPose () {
let bones = this.bones; let bones = this.bones;
for (let i = 0, n = bones.length; i < n; i++) for (let i = 0, n = bones.length; i < n; i++)
bones[i].setToSetupPose(); bones[i].setToSetupPose();
@ -422,7 +422,7 @@ export class Skeleton {
} }
/** Sets the slots and draw order to their setup pose values. */ /** Sets the slots and draw order to their setup pose values. */
setSlotsToSetupPose() { setSlotsToSetupPose () {
let slots = this.slots; let slots = this.slots;
Utils.arrayCopy(slots, 0, this.drawOrder, 0, slots.length); Utils.arrayCopy(slots, 0, this.drawOrder, 0, slots.length);
for (let i = 0, n = slots.length; i < n; i++) for (let i = 0, n = slots.length; i < n; i++)
@ -430,13 +430,13 @@ export class Skeleton {
} }
/** @returns May return null. */ /** @returns May return null. */
getRootBone() { getRootBone () {
if (this.bones.length == 0) return null; if (this.bones.length == 0) return null;
return this.bones[0]; return this.bones[0];
} }
/** @returns May be null. */ /** @returns May be null. */
findBone(boneName: string) { findBone (boneName: string) {
if (!boneName) throw new Error("boneName cannot be null."); if (!boneName) throw new Error("boneName cannot be null.");
let bones = this.bones; let bones = this.bones;
for (let i = 0, n = bones.length; i < n; i++) { for (let i = 0, n = bones.length; i < n; i++) {
@ -447,7 +447,7 @@ export class Skeleton {
} }
/** @returns -1 if the bone was not found. */ /** @returns -1 if the bone was not found. */
findBoneIndex(boneName: string) { findBoneIndex (boneName: string) {
if (!boneName) throw new Error("boneName cannot be null."); if (!boneName) throw new Error("boneName cannot be null.");
let bones = this.bones; let bones = this.bones;
for (let i = 0, n = bones.length; i < n; i++) for (let i = 0, n = bones.length; i < n; i++)
@ -458,7 +458,7 @@ export class Skeleton {
/** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it /** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it
* repeatedly. * repeatedly.
* @returns May be null. */ * @returns May be null. */
findSlot(slotName: string) { findSlot (slotName: string) {
if (!slotName) throw new Error("slotName cannot be null."); if (!slotName) throw new Error("slotName cannot be null.");
let slots = this.slots; let slots = this.slots;
for (let i = 0, n = slots.length; i < n; i++) { for (let i = 0, n = slots.length; i < n; i++) {
@ -469,7 +469,7 @@ export class Skeleton {
} }
/** @returns -1 if the bone was not found. */ /** @returns -1 if the bone was not found. */
findSlotIndex(slotName: string) { findSlotIndex (slotName: string) {
if (!slotName) throw new Error("slotName cannot be null."); if (!slotName) throw new Error("slotName cannot be null.");
let slots = this.slots; let slots = this.slots;
for (let i = 0, n = slots.length; i < n; i++) for (let i = 0, n = slots.length; i < n; i++)
@ -480,7 +480,7 @@ export class Skeleton {
/** Sets a skin by name. /** Sets a skin by name.
* *
* See {@link #setSkin()}. */ * See {@link #setSkin()}. */
setSkinByName(skinName: string) { setSkinByName (skinName: string) {
let skin = this.data.findSkin(skinName); let skin = this.data.findSkin(skinName);
if (!skin) throw new Error("Skin not found: " + skinName); if (!skin) throw new Error("Skin not found: " + skinName);
this.setSkin(skin); this.setSkin(skin);
@ -496,7 +496,7 @@ export class Skeleton {
* {@link #setSlotsToSetupPose()}. Also, often {@link AnimationState#apply()} is called before the next time the * {@link #setSlotsToSetupPose()}. Also, often {@link AnimationState#apply()} is called before the next time the
* skeleton is rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new skin. * skeleton is rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new skin.
* @param newSkin May be null. */ * @param newSkin May be null. */
setSkin(newSkin: Skin) { setSkin (newSkin: Skin) {
if (newSkin == this.skin) return; if (newSkin == this.skin) return;
if (newSkin) { if (newSkin) {
if (this.skin) if (this.skin)
@ -523,7 +523,7 @@ export class Skeleton {
* *
* See {@link #getAttachment()}. * See {@link #getAttachment()}.
* @returns May be null. */ * @returns May be null. */
getAttachmentByName(slotName: string, attachmentName: string): Attachment { getAttachmentByName (slotName: string, attachmentName: string): Attachment {
return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName); return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName);
} }
@ -532,7 +532,7 @@ export class Skeleton {
* *
* See [Runtime skins](http://esotericsoftware.com/spine-runtime-skins) in the Spine Runtimes Guide. * See [Runtime skins](http://esotericsoftware.com/spine-runtime-skins) in the Spine Runtimes Guide.
* @returns May be null. */ * @returns May be null. */
getAttachment(slotIndex: number, attachmentName: string): Attachment { getAttachment (slotIndex: number, attachmentName: string): Attachment {
if (!attachmentName) throw new Error("attachmentName cannot be null."); if (!attachmentName) throw new Error("attachmentName cannot be null.");
if (this.skin) { if (this.skin) {
let attachment: Attachment = this.skin.getAttachment(slotIndex, attachmentName); let attachment: Attachment = this.skin.getAttachment(slotIndex, attachmentName);
@ -545,7 +545,7 @@ export class Skeleton {
/** A convenience method to set an attachment by finding the slot with {@link #findSlot()}, finding the attachment with /** A convenience method to set an attachment by finding the slot with {@link #findSlot()}, finding the attachment with
* {@link #getAttachment()}, then setting the slot's {@link Slot#attachment}. * {@link #getAttachment()}, then setting the slot's {@link Slot#attachment}.
* @param attachmentName May be null to clear the slot's attachment. */ * @param attachmentName May be null to clear the slot's attachment. */
setAttachment(slotName: string, attachmentName: string) { setAttachment (slotName: string, attachmentName: string) {
if (!slotName) throw new Error("slotName cannot be null."); if (!slotName) throw new Error("slotName cannot be null.");
let slots = this.slots; let slots = this.slots;
for (let i = 0, n = slots.length; i < n; i++) { for (let i = 0, n = slots.length; i < n; i++) {
@ -567,7 +567,7 @@ export class Skeleton {
/** Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results of this method /** Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results of this method
* than to call it repeatedly. * than to call it repeatedly.
* @return May be null. */ * @return May be null. */
findIkConstraint(constraintName: string) { findIkConstraint (constraintName: string) {
if (!constraintName) throw new Error("constraintName cannot be null."); if (!constraintName) throw new Error("constraintName cannot be null.");
let ikConstraints = this.ikConstraints; let ikConstraints = this.ikConstraints;
for (let i = 0, n = ikConstraints.length; i < n; i++) { for (let i = 0, n = ikConstraints.length; i < n; i++) {
@ -580,7 +580,7 @@ export class Skeleton {
/** Finds a transform constraint by comparing each transform constraint's name. It is more efficient to cache the results of /** Finds a transform constraint by comparing each transform constraint's name. It is more efficient to cache the results of
* this method than to call it repeatedly. * this method than to call it repeatedly.
* @return May be null. */ * @return May be null. */
findTransformConstraint(constraintName: string) { findTransformConstraint (constraintName: string) {
if (!constraintName) throw new Error("constraintName cannot be null."); if (!constraintName) throw new Error("constraintName cannot be null.");
let transformConstraints = this.transformConstraints; let transformConstraints = this.transformConstraints;
for (let i = 0, n = transformConstraints.length; i < n; i++) { for (let i = 0, n = transformConstraints.length; i < n; i++) {
@ -593,7 +593,7 @@ export class Skeleton {
/** Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method /** Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method
* than to call it repeatedly. * than to call it repeatedly.
* @return May be null. */ * @return May be null. */
findPathConstraint(constraintName: string) { findPathConstraint (constraintName: string) {
if (!constraintName) throw new Error("constraintName cannot be null."); if (!constraintName) throw new Error("constraintName cannot be null.");
let pathConstraints = this.pathConstraints; let pathConstraints = this.pathConstraints;
for (let i = 0, n = pathConstraints.length; i < n; i++) { for (let i = 0, n = pathConstraints.length; i < n; i++) {
@ -607,7 +607,7 @@ export class Skeleton {
* @param offset An output value, the distance from the skeleton origin to the bottom left corner of the AABB. * @param offset An output value, the distance from the skeleton origin to the bottom left corner of the AABB.
* @param size An output value, the width and height of the AABB. * @param size An output value, the width and height of the AABB.
* @param temp Working memory to temporarily store attachments' computed world vertices. */ * @param temp Working memory to temporarily store attachments' computed world vertices. */
getBounds(offset: Vector2, size: Vector2, temp: Array<number> = new Array<number>(2)) { getBounds (offset: Vector2, size: Vector2, temp: Array<number> = new Array<number>(2)) {
if (!offset) throw new Error("offset cannot be null."); if (!offset) throw new Error("offset cannot be null.");
if (!size) throw new Error("size cannot be null."); if (!size) throw new Error("size cannot be null.");
let drawOrder = this.drawOrder; let drawOrder = this.drawOrder;
@ -643,7 +643,7 @@ export class Skeleton {
} }
/** Increments the skeleton's {@link #time}. */ /** Increments the skeleton's {@link #time}. */
update(delta: number) { update (delta: number) {
this.time += delta; this.time += delta;
} }
} }

View File

@ -57,11 +57,11 @@ export class SkeletonBinary {
attachmentLoader: AttachmentLoader; attachmentLoader: AttachmentLoader;
private linkedMeshes = new Array<LinkedMesh>(); private linkedMeshes = new Array<LinkedMesh>();
constructor(attachmentLoader: AttachmentLoader) { constructor (attachmentLoader: AttachmentLoader) {
this.attachmentLoader = attachmentLoader; this.attachmentLoader = attachmentLoader;
} }
readSkeletonData(binary: Uint8Array): SkeletonData { readSkeletonData (binary: Uint8Array): SkeletonData {
let scale = this.scale; let scale = this.scale;
let skeletonData = new SkeletonData(); let skeletonData = new SkeletonData();
@ -247,7 +247,7 @@ export class SkeletonBinary {
return skeletonData; return skeletonData;
} }
private readSkin(input: BinaryInput, skeletonData: SkeletonData, defaultSkin: boolean, nonessential: boolean): Skin { private readSkin (input: BinaryInput, skeletonData: SkeletonData, defaultSkin: boolean, nonessential: boolean): Skin {
let skin = null; let skin = null;
let slotCount = 0; let slotCount = 0;
@ -282,7 +282,7 @@ export class SkeletonBinary {
return skin; return skin;
} }
private readAttachment(input: BinaryInput, skeletonData: SkeletonData, skin: Skin, slotIndex: number, attachmentName: string, nonessential: boolean): Attachment { private readAttachment (input: BinaryInput, skeletonData: SkeletonData, skin: Skin, slotIndex: number, attachmentName: string, nonessential: boolean): Attachment {
let scale = this.scale; let scale = this.scale;
let name = input.readStringRef(); let name = input.readStringRef();
@ -441,7 +441,7 @@ export class SkeletonBinary {
return null; return null;
} }
private readVertices(input: BinaryInput, vertexCount: number): Vertices { private readVertices (input: BinaryInput, vertexCount: number): Vertices {
let scale = this.scale; let scale = this.scale;
let verticesLength = vertexCount << 1; let verticesLength = vertexCount << 1;
let vertices = new Vertices(); let vertices = new Vertices();
@ -466,7 +466,7 @@ export class SkeletonBinary {
return vertices; return vertices;
} }
private readFloatArray(input: BinaryInput, n: number, scale: number): number[] { private readFloatArray (input: BinaryInput, n: number, scale: number): number[] {
let array = new Array<number>(n); let array = new Array<number>(n);
if (scale == 1) { if (scale == 1) {
for (let i = 0; i < n; i++) for (let i = 0; i < n; i++)
@ -478,7 +478,7 @@ export class SkeletonBinary {
return array; return array;
} }
private readShortArray(input: BinaryInput): number[] { private readShortArray (input: BinaryInput): number[] {
let n = input.readInt(true); let n = input.readInt(true);
let array = new Array<number>(n); let array = new Array<number>(n);
for (let i = 0; i < n; i++) for (let i = 0; i < n; i++)
@ -486,7 +486,7 @@ export class SkeletonBinary {
return array; return array;
} }
private readAnimation(input: BinaryInput, name: string, skeletonData: SkeletonData): Animation { private readAnimation (input: BinaryInput, name: string, skeletonData: SkeletonData): Animation {
input.readInt(true); // Number of timelines. input.readInt(true); // Number of timelines.
let timelines = new Array<Timeline>(); let timelines = new Array<Timeline>();
let scale = this.scale; let scale = this.scale;
@ -960,30 +960,30 @@ export class SkeletonBinary {
} }
export class BinaryInput { export class BinaryInput {
constructor(data: Uint8Array, public strings = new Array<string>(), private index: number = 0, private buffer = new DataView(data.buffer)) { constructor (data: Uint8Array, public strings = new Array<string>(), private index: number = 0, private buffer = new DataView(data.buffer)) {
} }
readByte(): number { readByte (): number {
return this.buffer.getInt8(this.index++); return this.buffer.getInt8(this.index++);
} }
readUnsignedByte(): number { readUnsignedByte (): number {
return this.buffer.getUint8(this.index++); return this.buffer.getUint8(this.index++);
} }
readShort(): number { readShort (): number {
let value = this.buffer.getInt16(this.index); let value = this.buffer.getInt16(this.index);
this.index += 2; this.index += 2;
return value; return value;
} }
readInt32(): number { readInt32 (): number {
let value = this.buffer.getInt32(this.index) let value = this.buffer.getInt32(this.index)
this.index += 4; this.index += 4;
return value; return value;
} }
readInt(optimizePositive: boolean) { readInt (optimizePositive: boolean) {
let b = this.readByte(); let b = this.readByte();
let result = b & 0x7F; let result = b & 0x7F;
if ((b & 0x80) != 0) { if ((b & 0x80) != 0) {
@ -1005,12 +1005,12 @@ export class BinaryInput {
return optimizePositive ? result : ((result >>> 1) ^ -(result & 1)); return optimizePositive ? result : ((result >>> 1) ^ -(result & 1));
} }
readStringRef(): string { readStringRef (): string {
let index = this.readInt(true); let index = this.readInt(true);
return index == 0 ? null : this.strings[index - 1]; return index == 0 ? null : this.strings[index - 1];
} }
readString(): string { readString (): string {
let byteCount = this.readInt(true); let byteCount = this.readInt(true);
switch (byteCount) { switch (byteCount) {
case 0: case 0:
@ -1041,13 +1041,13 @@ export class BinaryInput {
return chars; return chars;
} }
readFloat(): number { readFloat (): number {
let value = this.buffer.getFloat32(this.index); let value = this.buffer.getFloat32(this.index);
this.index += 4; this.index += 4;
return value; return value;
} }
readBoolean(): boolean { readBoolean (): boolean {
return this.readByte() != 0; return this.readByte() != 0;
} }
} }
@ -1058,7 +1058,7 @@ class LinkedMesh {
mesh: MeshAttachment; mesh: MeshAttachment;
inheritDeform: boolean; inheritDeform: boolean;
constructor(mesh: MeshAttachment, skin: string, slotIndex: number, parent: string, inheritDeform: boolean) { constructor (mesh: MeshAttachment, skin: string, slotIndex: number, parent: string, inheritDeform: boolean) {
this.mesh = mesh; this.mesh = mesh;
this.skin = skin; this.skin = skin;
this.slotIndex = slotIndex; this.slotIndex = slotIndex;
@ -1068,12 +1068,12 @@ class LinkedMesh {
} }
class Vertices { class Vertices {
constructor(public bones: Array<number> = null, public vertices: Array<number> | Float32Array = null) { } constructor (public bones: Array<number> = null, public vertices: Array<number> | Float32Array = null) { }
} }
enum AttachmentType { Region, BoundingBox, Mesh, LinkedMesh, Path, Point, Clipping } enum AttachmentType { Region, BoundingBox, Mesh, LinkedMesh, Path, Point, Clipping }
function readTimeline1(input: BinaryInput, timeline: CurveTimeline1, scale: number): CurveTimeline1 { function readTimeline1 (input: BinaryInput, timeline: CurveTimeline1, scale: number): CurveTimeline1 {
let time = input.readFloat(), value = input.readFloat() * scale; let time = input.readFloat(), value = input.readFloat() * scale;
for (let frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1; ; frame++) { for (let frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1; ; frame++) {
timeline.setFrame(frame, time, value); timeline.setFrame(frame, time, value);
@ -1092,7 +1092,7 @@ function readTimeline1(input: BinaryInput, timeline: CurveTimeline1, scale: numb
return timeline; return timeline;
} }
function readTimeline2(input: BinaryInput, timeline: CurveTimeline2, scale: number): CurveTimeline2 { function readTimeline2 (input: BinaryInput, timeline: CurveTimeline2, scale: number): CurveTimeline2 {
let time = input.readFloat(), value1 = input.readFloat() * scale, value2 = input.readFloat() * scale; let time = input.readFloat(), value1 = input.readFloat() * scale, value2 = input.readFloat() * scale;
for (let frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1; ; frame++) { for (let frame = 0, bezier = 0, frameLast = timeline.getFrameCount() - 1; ; frame++) {
timeline.setFrame(frame, time, value1, value2); timeline.setFrame(frame, time, value1, value2);
@ -1113,7 +1113,7 @@ function readTimeline2(input: BinaryInput, timeline: CurveTimeline2, scale: numb
return timeline; return timeline;
} }
function setBezier(input: BinaryInput, timeline: CurveTimeline, bezier: number, frame: number, value: number, function setBezier (input: BinaryInput, timeline: CurveTimeline, bezier: number, frame: number, value: number,
time1: number, time2: number, value1: number, value2: number, scale: number) { time1: number, time2: number, value1: number, value2: number, scale: number) {
timeline.setBezier(bezier, frame, value, time1, value1, input.readFloat(), input.readFloat() * scale, input.readFloat(), input.readFloat() * scale, time2, value2); timeline.setBezier(bezier, frame, value, time1, value1, input.readFloat(), input.readFloat() * scale, input.readFloat(), input.readFloat() * scale, time2, value2);
} }

View File

@ -61,7 +61,7 @@ export class SkeletonBounds {
* box's polygon. * box's polygon.
* @param updateAabb If true, the axis aligned bounding box containing all the polygons is computed. If false, the * @param updateAabb If true, the axis aligned bounding box containing all the polygons is computed. If false, the
* SkeletonBounds AABB methods will always return true. */ * SkeletonBounds AABB methods will always return true. */
update(skeleton: Skeleton, updateAabb: boolean) { update (skeleton: Skeleton, updateAabb: boolean) {
if (!skeleton) throw new Error("skeleton cannot be null."); if (!skeleton) throw new Error("skeleton cannot be null.");
let boundingBoxes = this.boundingBoxes; let boundingBoxes = this.boundingBoxes;
let polygons = this.polygons; let polygons = this.polygons;
@ -100,7 +100,7 @@ export class SkeletonBounds {
} }
} }
aabbCompute() { aabbCompute () {
let minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; let minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY;
let polygons = this.polygons; let polygons = this.polygons;
for (let i = 0, n = polygons.length; i < n; i++) { for (let i = 0, n = polygons.length; i < n; i++) {
@ -122,12 +122,12 @@ export class SkeletonBounds {
} }
/** Returns true if the axis aligned bounding box contains the point. */ /** Returns true if the axis aligned bounding box contains the point. */
aabbContainsPoint(x: number, y: number) { aabbContainsPoint (x: number, y: number) {
return x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY; return x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY;
} }
/** Returns true if the axis aligned bounding box intersects the line segment. */ /** Returns true if the axis aligned bounding box intersects the line segment. */
aabbIntersectsSegment(x1: number, y1: number, x2: number, y2: number) { aabbIntersectsSegment (x1: number, y1: number, x2: number, y2: number) {
let minX = this.minX; let minX = this.minX;
let minY = this.minY; let minY = this.minY;
let maxX = this.maxX; let maxX = this.maxX;
@ -147,13 +147,13 @@ export class SkeletonBounds {
} }
/** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */ /** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */
aabbIntersectsSkeleton(bounds: SkeletonBounds) { aabbIntersectsSkeleton (bounds: SkeletonBounds) {
return this.minX < bounds.maxX && this.maxX > bounds.minX && this.minY < bounds.maxY && this.maxY > bounds.minY; return this.minX < bounds.maxX && this.maxX > bounds.minX && this.minY < bounds.maxY && this.maxY > bounds.minY;
} }
/** Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more /** Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more
* efficient to only call this method if {@link #aabbContainsPoint(float, float)} returns true. */ * efficient to only call this method if {@link #aabbContainsPoint(float, float)} returns true. */
containsPoint(x: number, y: number): BoundingBoxAttachment { containsPoint (x: number, y: number): BoundingBoxAttachment {
let polygons = this.polygons; let polygons = this.polygons;
for (let i = 0, n = polygons.length; i < n; i++) for (let i = 0, n = polygons.length; i < n; i++)
if (this.containsPointPolygon(polygons[i], x, y)) return this.boundingBoxes[i]; if (this.containsPointPolygon(polygons[i], x, y)) return this.boundingBoxes[i];
@ -161,7 +161,7 @@ export class SkeletonBounds {
} }
/** Returns true if the polygon contains the point. */ /** Returns true if the polygon contains the point. */
containsPointPolygon(polygon: NumberArrayLike, x: number, y: number) { containsPointPolygon (polygon: NumberArrayLike, x: number, y: number) {
let vertices = polygon; let vertices = polygon;
let nn = polygon.length; let nn = polygon.length;
@ -182,7 +182,7 @@ export class SkeletonBounds {
/** Returns the first bounding box attachment that contains any part of the line segment, or null. When doing many checks, it /** Returns the first bounding box attachment that contains any part of the line segment, or null. When doing many checks, it
* is usually more efficient to only call this method if {@link #aabbIntersectsSegment()} returns * is usually more efficient to only call this method if {@link #aabbIntersectsSegment()} returns
* true. */ * true. */
intersectsSegment(x1: number, y1: number, x2: number, y2: number) { intersectsSegment (x1: number, y1: number, x2: number, y2: number) {
let polygons = this.polygons; let polygons = this.polygons;
for (let i = 0, n = polygons.length; i < n; i++) for (let i = 0, n = polygons.length; i < n; i++)
if (this.intersectsSegmentPolygon(polygons[i], x1, y1, x2, y2)) return this.boundingBoxes[i]; if (this.intersectsSegmentPolygon(polygons[i], x1, y1, x2, y2)) return this.boundingBoxes[i];
@ -190,7 +190,7 @@ export class SkeletonBounds {
} }
/** Returns true if the polygon contains any part of the line segment. */ /** Returns true if the polygon contains any part of the line segment. */
intersectsSegmentPolygon(polygon: NumberArrayLike, x1: number, y1: number, x2: number, y2: number) { intersectsSegmentPolygon (polygon: NumberArrayLike, x1: number, y1: number, x2: number, y2: number) {
let vertices = polygon; let vertices = polygon;
let nn = polygon.length; let nn = polygon.length;
@ -214,19 +214,19 @@ export class SkeletonBounds {
} }
/** Returns the polygon for the specified bounding box, or null. */ /** Returns the polygon for the specified bounding box, or null. */
getPolygon(boundingBox: BoundingBoxAttachment) { getPolygon (boundingBox: BoundingBoxAttachment) {
if (!boundingBox) throw new Error("boundingBox cannot be null."); if (!boundingBox) throw new Error("boundingBox cannot be null.");
let index = this.boundingBoxes.indexOf(boundingBox); let index = this.boundingBoxes.indexOf(boundingBox);
return index == -1 ? null : this.polygons[index]; return index == -1 ? null : this.polygons[index];
} }
/** The width of the axis aligned bounding box. */ /** The width of the axis aligned bounding box. */
getWidth() { getWidth () {
return this.maxX - this.minX; return this.maxX - this.minX;
} }
/** The height of the axis aligned bounding box. */ /** The height of the axis aligned bounding box. */
getHeight() { getHeight () {
return this.maxY - this.minY; return this.maxY - this.minY;
} }
} }

View File

@ -43,7 +43,7 @@ export class SkeletonClipping {
private clipAttachment: ClippingAttachment; private clipAttachment: ClippingAttachment;
private clippingPolygons: Array<Array<number>>; private clippingPolygons: Array<Array<number>>;
clipStart(slot: Slot, clip: ClippingAttachment): number { clipStart (slot: Slot, clip: ClippingAttachment): number {
if (this.clipAttachment) return 0; if (this.clipAttachment) return 0;
this.clipAttachment = clip; this.clipAttachment = clip;
@ -63,11 +63,11 @@ export class SkeletonClipping {
return clippingPolygons.length; return clippingPolygons.length;
} }
clipEndWithSlot(slot: Slot) { clipEndWithSlot (slot: Slot) {
if (this.clipAttachment && this.clipAttachment.endSlot == slot.data) this.clipEnd(); if (this.clipAttachment && this.clipAttachment.endSlot == slot.data) this.clipEnd();
} }
clipEnd() { clipEnd () {
if (!this.clipAttachment) return; if (!this.clipAttachment) return;
this.clipAttachment = null; this.clipAttachment = null;
this.clippingPolygons = null; this.clippingPolygons = null;
@ -76,11 +76,11 @@ export class SkeletonClipping {
this.clippingPolygon.length = 0; this.clippingPolygon.length = 0;
} }
isClipping(): boolean { isClipping (): boolean {
return this.clipAttachment != null; return this.clipAttachment != null;
} }
clipTriangles(vertices: NumberArrayLike, verticesLength: number, triangles: NumberArrayLike, trianglesLength: number, uvs: NumberArrayLike, clipTriangles (vertices: NumberArrayLike, verticesLength: number, triangles: NumberArrayLike, trianglesLength: number, uvs: NumberArrayLike,
light: Color, dark: Color, twoColor: boolean) { light: Color, dark: Color, twoColor: boolean) {
let clipOutput = this.clipOutput, clippedVertices = this.clippedVertices; let clipOutput = this.clipOutput, clippedVertices = this.clippedVertices;
@ -229,7 +229,7 @@ export class SkeletonClipping {
/** Clips the input triangle against the convex, clockwise clipping area. If the triangle lies entirely within the clipping /** Clips the input triangle against the convex, clockwise clipping area. If the triangle lies entirely within the clipping
* area, false is returned. The clipping area must duplicate the first vertex at the end of the vertices list. */ * area, false is returned. The clipping area must duplicate the first vertex at the end of the vertices list. */
clip(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, clippingArea: Array<number>, output: Array<number>) { clip (x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, clippingArea: Array<number>, output: Array<number>) {
let originalOutput = output; let originalOutput = output;
let clipped = false; let clipped = false;
@ -324,7 +324,7 @@ export class SkeletonClipping {
return clipped; return clipped;
} }
public static makeClockwise(polygon: NumberArrayLike) { public static makeClockwise (polygon: NumberArrayLike) {
let vertices = polygon; let vertices = polygon;
let verticeslength = polygon.length; let verticeslength = polygon.length;

View File

@ -104,7 +104,7 @@ export class SkeletonData {
/** Finds a bone by comparing each bone's name. It is more efficient to cache the results of this method than to call it /** Finds a bone by comparing each bone's name. It is more efficient to cache the results of this method than to call it
* multiple times. * multiple times.
* @returns May be null. */ * @returns May be null. */
findBone(boneName: string) { findBone (boneName: string) {
if (!boneName) throw new Error("boneName cannot be null."); if (!boneName) throw new Error("boneName cannot be null.");
let bones = this.bones; let bones = this.bones;
for (let i = 0, n = bones.length; i < n; i++) { for (let i = 0, n = bones.length; i < n; i++) {
@ -114,7 +114,7 @@ export class SkeletonData {
return null; return null;
} }
findBoneIndex(boneName: string) { findBoneIndex (boneName: string) {
if (!boneName) throw new Error("boneName cannot be null."); if (!boneName) throw new Error("boneName cannot be null.");
let bones = this.bones; let bones = this.bones;
for (let i = 0, n = bones.length; i < n; i++) for (let i = 0, n = bones.length; i < n; i++)
@ -125,7 +125,7 @@ export class SkeletonData {
/** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it /** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it
* multiple times. * multiple times.
* @returns May be null. */ * @returns May be null. */
findSlot(slotName: string) { findSlot (slotName: string) {
if (!slotName) throw new Error("slotName cannot be null."); if (!slotName) throw new Error("slotName cannot be null.");
let slots = this.slots; let slots = this.slots;
for (let i = 0, n = slots.length; i < n; i++) { for (let i = 0, n = slots.length; i < n; i++) {
@ -135,7 +135,7 @@ export class SkeletonData {
return null; return null;
} }
findSlotIndex(slotName: string) { findSlotIndex (slotName: string) {
if (!slotName) throw new Error("slotName cannot be null."); if (!slotName) throw new Error("slotName cannot be null.");
let slots = this.slots; let slots = this.slots;
for (let i = 0, n = slots.length; i < n; i++) for (let i = 0, n = slots.length; i < n; i++)
@ -146,7 +146,7 @@ export class SkeletonData {
/** Finds a skin by comparing each skin's name. It is more efficient to cache the results of this method than to call it /** Finds a skin by comparing each skin's name. It is more efficient to cache the results of this method than to call it
* multiple times. * multiple times.
* @returns May be null. */ * @returns May be null. */
findSkin(skinName: string) { findSkin (skinName: string) {
if (!skinName) throw new Error("skinName cannot be null."); if (!skinName) throw new Error("skinName cannot be null.");
let skins = this.skins; let skins = this.skins;
for (let i = 0, n = skins.length; i < n; i++) { for (let i = 0, n = skins.length; i < n; i++) {
@ -159,7 +159,7 @@ export class SkeletonData {
/** Finds an event by comparing each events's name. It is more efficient to cache the results of this method than to call it /** Finds an event by comparing each events's name. It is more efficient to cache the results of this method than to call it
* multiple times. * multiple times.
* @returns May be null. */ * @returns May be null. */
findEvent(eventDataName: string) { findEvent (eventDataName: string) {
if (!eventDataName) throw new Error("eventDataName cannot be null."); if (!eventDataName) throw new Error("eventDataName cannot be null.");
let events = this.events; let events = this.events;
for (let i = 0, n = events.length; i < n; i++) { for (let i = 0, n = events.length; i < n; i++) {
@ -172,7 +172,7 @@ export class SkeletonData {
/** Finds an animation by comparing each animation's name. It is more efficient to cache the results of this method than to /** Finds an animation by comparing each animation's name. It is more efficient to cache the results of this method than to
* call it multiple times. * call it multiple times.
* @returns May be null. */ * @returns May be null. */
findAnimation(animationName: string) { findAnimation (animationName: string) {
if (!animationName) throw new Error("animationName cannot be null."); if (!animationName) throw new Error("animationName cannot be null.");
let animations = this.animations; let animations = this.animations;
for (let i = 0, n = animations.length; i < n; i++) { for (let i = 0, n = animations.length; i < n; i++) {
@ -185,7 +185,7 @@ export class SkeletonData {
/** Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results of this method /** Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results of this method
* than to call it multiple times. * than to call it multiple times.
* @return May be null. */ * @return May be null. */
findIkConstraint(constraintName: string) { findIkConstraint (constraintName: string) {
if (!constraintName) throw new Error("constraintName cannot be null."); if (!constraintName) throw new Error("constraintName cannot be null.");
let ikConstraints = this.ikConstraints; let ikConstraints = this.ikConstraints;
for (let i = 0, n = ikConstraints.length; i < n; i++) { for (let i = 0, n = ikConstraints.length; i < n; i++) {
@ -198,7 +198,7 @@ export class SkeletonData {
/** Finds a transform constraint by comparing each transform constraint's name. It is more efficient to cache the results of /** Finds a transform constraint by comparing each transform constraint's name. It is more efficient to cache the results of
* this method than to call it multiple times. * this method than to call it multiple times.
* @return May be null. */ * @return May be null. */
findTransformConstraint(constraintName: string) { findTransformConstraint (constraintName: string) {
if (!constraintName) throw new Error("constraintName cannot be null."); if (!constraintName) throw new Error("constraintName cannot be null.");
let transformConstraints = this.transformConstraints; let transformConstraints = this.transformConstraints;
for (let i = 0, n = transformConstraints.length; i < n; i++) { for (let i = 0, n = transformConstraints.length; i < n; i++) {
@ -211,7 +211,7 @@ export class SkeletonData {
/** Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method /** Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method
* than to call it multiple times. * than to call it multiple times.
* @return May be null. */ * @return May be null. */
findPathConstraint(constraintName: string) { findPathConstraint (constraintName: string) {
if (!constraintName) throw new Error("constraintName cannot be null."); if (!constraintName) throw new Error("constraintName cannot be null.");
let pathConstraints = this.pathConstraints; let pathConstraints = this.pathConstraints;
for (let i = 0, n = pathConstraints.length; i < n; i++) { for (let i = 0, n = pathConstraints.length; i < n; i++) {

View File

@ -57,11 +57,11 @@ export class SkeletonJson {
scale = 1; scale = 1;
private linkedMeshes = new Array<LinkedMesh>(); private linkedMeshes = new Array<LinkedMesh>();
constructor(attachmentLoader: AttachmentLoader) { constructor (attachmentLoader: AttachmentLoader) {
this.attachmentLoader = attachmentLoader; this.attachmentLoader = attachmentLoader;
} }
readSkeletonData(json: string | any): SkeletonData { readSkeletonData (json: string | any): SkeletonData {
let scale = this.scale; let scale = this.scale;
let skeletonData = new SkeletonData(); let skeletonData = new SkeletonData();
let root = typeof (json) === "string" ? JSON.parse(json) : json; let root = typeof (json) === "string" ? JSON.parse(json) : json;
@ -291,7 +291,7 @@ export class SkeletonJson {
return skeletonData; return skeletonData;
} }
readAttachment(map: any, skin: Skin, slotIndex: number, name: string, skeletonData: SkeletonData): Attachment { readAttachment (map: any, skin: Skin, slotIndex: number, name: string, skeletonData: SkeletonData): Attachment {
let scale = this.scale; let scale = this.scale;
name = getValue(map, "name", name); name = getValue(map, "name", name);
@ -399,7 +399,7 @@ export class SkeletonJson {
return null; return null;
} }
readVertices(map: any, attachment: VertexAttachment, verticesLength: number) { readVertices (map: any, attachment: VertexAttachment, verticesLength: number) {
let scale = this.scale; let scale = this.scale;
attachment.worldVerticesLength = verticesLength; attachment.worldVerticesLength = verticesLength;
let vertices: Array<number> = map.vertices; let vertices: Array<number> = map.vertices;
@ -428,7 +428,7 @@ export class SkeletonJson {
attachment.vertices = Utils.toFloatArray(weights); attachment.vertices = Utils.toFloatArray(weights);
} }
readAnimation(map: any, name: string, skeletonData: SkeletonData) { readAnimation (map: any, name: string, skeletonData: SkeletonData) {
let scale = this.scale; let scale = this.scale;
let timelines = new Array<Timeline>(); let timelines = new Array<Timeline>();
@ -899,7 +899,7 @@ class LinkedMesh {
mesh: MeshAttachment; mesh: MeshAttachment;
inheritDeform: boolean; inheritDeform: boolean;
constructor(mesh: MeshAttachment, skin: string, slotIndex: number, parent: string, inheritDeform: boolean) { constructor (mesh: MeshAttachment, skin: string, slotIndex: number, parent: string, inheritDeform: boolean) {
this.mesh = mesh; this.mesh = mesh;
this.skin = skin; this.skin = skin;
this.slotIndex = slotIndex; this.slotIndex = slotIndex;
@ -908,7 +908,7 @@ class LinkedMesh {
} }
} }
function readTimeline1(keys: any[], timeline: CurveTimeline1, defaultValue: number, scale: number) { function readTimeline1 (keys: any[], timeline: CurveTimeline1, defaultValue: number, scale: number) {
let keyMap = keys[0]; let keyMap = keys[0];
let time = getValue(keyMap, "time", 0); let time = getValue(keyMap, "time", 0);
let value = getValue(keyMap, "value", defaultValue) * scale; let value = getValue(keyMap, "value", defaultValue) * scale;
@ -929,7 +929,7 @@ function readTimeline1(keys: any[], timeline: CurveTimeline1, defaultValue: numb
} }
} }
function readTimeline2(keys: any[], timeline: CurveTimeline2, name1: string, name2: string, defaultValue: number, scale: number) { function readTimeline2 (keys: any[], timeline: CurveTimeline2, name1: string, name2: string, defaultValue: number, scale: number) {
let keyMap = keys[0]; let keyMap = keys[0];
let time = getValue(keyMap, "time", 0); let time = getValue(keyMap, "time", 0);
let value1 = getValue(keyMap, name1, defaultValue) * scale; let value1 = getValue(keyMap, name1, defaultValue) * scale;
@ -957,7 +957,7 @@ function readTimeline2(keys: any[], timeline: CurveTimeline2, name1: string, nam
} }
} }
function readCurve(curve: any, timeline: CurveTimeline, bezier: number, frame: number, value: number, time1: number, time2: number, function readCurve (curve: any, timeline: CurveTimeline, bezier: number, frame: number, value: number, time1: number, time2: number,
value1: number, value2: number, scale: number) { value1: number, value2: number, scale: number) {
if (curve == "stepped") { if (curve == "stepped") {
timeline.setStepped(frame); timeline.setStepped(frame);
@ -972,6 +972,6 @@ function readCurve(curve: any, timeline: CurveTimeline, bezier: number, frame: n
return bezier + 1; return bezier + 1;
} }
function getValue(map: any, property: string, defaultValue: any) { function getValue (map: any, property: string, defaultValue: any) {
return map[property] !== undefined ? map[property] : defaultValue; return map[property] !== undefined ? map[property] : defaultValue;
} }

View File

@ -36,7 +36,7 @@ import { StringMap } from "./Utils";
/** Stores an entry in the skin consisting of the slot index, name, and attachment **/ /** Stores an entry in the skin consisting of the slot index, name, and attachment **/
export class SkinEntry { export class SkinEntry {
constructor(public slotIndex: number, public name: string, public attachment: Attachment) { } constructor (public slotIndex: number, public name: string, public attachment: Attachment) { }
} }
/** Stores attachments by slot index and attachment name. /** Stores attachments by slot index and attachment name.
@ -51,13 +51,13 @@ export class Skin {
bones = Array<BoneData>(); bones = Array<BoneData>();
constraints = new Array<ConstraintData>(); constraints = new Array<ConstraintData>();
constructor(name: string) { constructor (name: string) {
if (!name) throw new Error("name cannot be null."); if (!name) throw new Error("name cannot be null.");
this.name = name; this.name = name;
} }
/** Adds an attachment to the skin for the specified slot index and name. */ /** Adds an attachment to the skin for the specified slot index and name. */
setAttachment(slotIndex: number, name: string, attachment: Attachment) { setAttachment (slotIndex: number, name: string, attachment: Attachment) {
if (!attachment) throw new Error("attachment cannot be null."); if (!attachment) throw new Error("attachment cannot be null.");
let attachments = this.attachments; let attachments = this.attachments;
if (slotIndex >= attachments.length) attachments.length = slotIndex + 1; if (slotIndex >= attachments.length) attachments.length = slotIndex + 1;
@ -66,7 +66,7 @@ export class Skin {
} }
/** Adds all attachments, bones, and constraints from the specified skin to this skin. */ /** Adds all attachments, bones, and constraints from the specified skin to this skin. */
addSkin(skin: Skin) { addSkin (skin: Skin) {
for (let i = 0; i < skin.bones.length; i++) { for (let i = 0; i < skin.bones.length; i++) {
let bone = skin.bones[i]; let bone = skin.bones[i];
let contained = false; let contained = false;
@ -100,7 +100,7 @@ export class Skin {
/** Adds all bones and constraints and copies of all attachments from the specified skin to this skin. Mesh attachments are not /** Adds all bones and constraints and copies of all attachments from the specified skin to this skin. Mesh attachments are not
* copied, instead a new linked mesh is created. The attachment copies can be modified without affecting the originals. */ * copied, instead a new linked mesh is created. The attachment copies can be modified without affecting the originals. */
copySkin(skin: Skin) { copySkin (skin: Skin) {
for (let i = 0; i < skin.bones.length; i++) { for (let i = 0; i < skin.bones.length; i++) {
let bone = skin.bones[i]; let bone = skin.bones[i];
let contained = false; let contained = false;
@ -140,19 +140,19 @@ export class Skin {
} }
/** Returns the attachment for the specified slot index and name, or null. */ /** Returns the attachment for the specified slot index and name, or null. */
getAttachment(slotIndex: number, name: string): Attachment { getAttachment (slotIndex: number, name: string): Attachment {
let dictionary = this.attachments[slotIndex]; let dictionary = this.attachments[slotIndex];
return dictionary ? dictionary[name] : null; return dictionary ? dictionary[name] : null;
} }
/** Removes the attachment in the skin for the specified slot index and name, if any. */ /** Removes the attachment in the skin for the specified slot index and name, if any. */
removeAttachment(slotIndex: number, name: string) { removeAttachment (slotIndex: number, name: string) {
let dictionary = this.attachments[slotIndex]; let dictionary = this.attachments[slotIndex];
if (dictionary) dictionary[name] = null; if (dictionary) dictionary[name] = null;
} }
/** Returns all attachments in this skin. */ /** Returns all attachments in this skin. */
getAttachments(): Array<SkinEntry> { getAttachments (): Array<SkinEntry> {
let entries = new Array<SkinEntry>(); let entries = new Array<SkinEntry>();
for (var i = 0; i < this.attachments.length; i++) { for (var i = 0; i < this.attachments.length; i++) {
let slotAttachments = this.attachments[i]; let slotAttachments = this.attachments[i];
@ -167,7 +167,7 @@ export class Skin {
} }
/** Returns all attachments in this skin for the specified slot index. */ /** Returns all attachments in this skin for the specified slot index. */
getAttachmentsForSlot(slotIndex: number, attachments: Array<SkinEntry>) { getAttachmentsForSlot (slotIndex: number, attachments: Array<SkinEntry>) {
let slotAttachments = this.attachments[slotIndex]; let slotAttachments = this.attachments[slotIndex];
if (slotAttachments) { if (slotAttachments) {
for (let name in slotAttachments) { for (let name in slotAttachments) {
@ -178,14 +178,14 @@ export class Skin {
} }
/** Clears all attachments, bones, and constraints. */ /** Clears all attachments, bones, and constraints. */
clear() { clear () {
this.attachments.length = 0; this.attachments.length = 0;
this.bones.length = 0; this.bones.length = 0;
this.constraints.length = 0; this.constraints.length = 0;
} }
/** Attach each attachment in this skin if the corresponding attachment in the old skin is currently attached. */ /** Attach each attachment in this skin if the corresponding attachment in the old skin is currently attached. */
attachAll(skeleton: Skeleton, oldSkin: Skin) { attachAll (skeleton: Skeleton, oldSkin: Skin) {
let slotIndex = 0; let slotIndex = 0;
for (let i = 0; i < skeleton.slots.length; i++) { for (let i = 0; i < skeleton.slots.length; i++) {
let slot = skeleton.slots[i]; let slot = skeleton.slots[i];

View File

@ -63,7 +63,7 @@ export class Slot {
* See {@link VertexAttachment#computeWorldVertices()} and {@link DeformTimeline}. */ * See {@link VertexAttachment#computeWorldVertices()} and {@link DeformTimeline}. */
deform = new Array<number>(); deform = new Array<number>();
constructor(data: SlotData, bone: Bone) { constructor (data: SlotData, bone: Bone) {
if (!data) throw new Error("data cannot be null."); if (!data) throw new Error("data cannot be null.");
if (!bone) throw new Error("bone cannot be null."); if (!bone) throw new Error("bone cannot be null.");
this.data = data; this.data = data;
@ -74,12 +74,12 @@ export class Slot {
} }
/** The skeleton this slot belongs to. */ /** The skeleton this slot belongs to. */
getSkeleton(): Skeleton { getSkeleton (): Skeleton {
return this.bone.skeleton; return this.bone.skeleton;
} }
/** The current attachment for the slot, or null if the slot has no attachment. */ /** The current attachment for the slot, or null if the slot has no attachment. */
getAttachment(): Attachment { getAttachment (): Attachment {
return this.attachment; return this.attachment;
} }
@ -87,7 +87,7 @@ export class Slot {
* The deform is not cleared if the old attachment has the same {@link VertexAttachment#getDeformAttachment()} as the specified * The deform is not cleared if the old attachment has the same {@link VertexAttachment#getDeformAttachment()} as the specified
* attachment. * attachment.
* @param attachment May be null. */ * @param attachment May be null. */
setAttachment(attachment: Attachment) { setAttachment (attachment: Attachment) {
if (this.attachment == attachment) return; if (this.attachment == attachment) return;
if (!(attachment instanceof VertexAttachment) || !(this.attachment instanceof VertexAttachment) if (!(attachment instanceof VertexAttachment) || !(this.attachment instanceof VertexAttachment)
|| (<VertexAttachment>attachment).deformAttachment != (<VertexAttachment>this.attachment).deformAttachment) { || (<VertexAttachment>attachment).deformAttachment != (<VertexAttachment>this.attachment).deformAttachment) {
@ -97,18 +97,18 @@ export class Slot {
this.attachmentTime = this.bone.skeleton.time; this.attachmentTime = this.bone.skeleton.time;
} }
setAttachmentTime(time: number) { setAttachmentTime (time: number) {
this.attachmentTime = this.bone.skeleton.time - time; this.attachmentTime = this.bone.skeleton.time - time;
} }
/** The time that has elapsed since the last time the attachment was set or cleared. Relies on Skeleton /** The time that has elapsed since the last time the attachment was set or cleared. Relies on Skeleton
* {@link Skeleton#time}. */ * {@link Skeleton#time}. */
getAttachmentTime(): number { getAttachmentTime (): number {
return this.bone.skeleton.time - this.attachmentTime; return this.bone.skeleton.time - this.attachmentTime;
} }
/** Sets this slot to the setup pose. */ /** Sets this slot to the setup pose. */
setToSetupPose() { setToSetupPose () {
this.color.setFromColor(this.data.color); this.color.setFromColor(this.data.color);
if (this.darkColor) this.darkColor.setFromColor(this.data.darkColor); if (this.darkColor) this.darkColor.setFromColor(this.data.darkColor);
if (!this.data.attachmentName) if (!this.data.attachmentName)

View File

@ -55,7 +55,7 @@ export class SlotData {
/** The blend mode for drawing the slot's attachment. */ /** The blend mode for drawing the slot's attachment. */
blendMode: BlendMode; blendMode: BlendMode;
constructor(index: number, name: string, boneData: BoneData) { constructor (index: number, name: string, boneData: BoneData) {
if (index < 0) throw new Error("index must be >= 0."); if (index < 0) throw new Error("index must be >= 0.");
if (!name) throw new Error("name cannot be null."); if (!name) throw new Error("name cannot be null.");
if (!boneData) throw new Error("boneData cannot be null."); if (!boneData) throw new Error("boneData cannot be null.");

View File

@ -30,17 +30,17 @@
export abstract class Texture { export abstract class Texture {
protected _image: HTMLImageElement | ImageBitmap; protected _image: HTMLImageElement | ImageBitmap;
constructor(image: HTMLImageElement | ImageBitmap) { constructor (image: HTMLImageElement | ImageBitmap) {
this._image = image; this._image = image;
} }
getImage(): HTMLImageElement | ImageBitmap { getImage (): HTMLImageElement | ImageBitmap {
return this._image; return this._image;
} }
abstract setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void; abstract setFilters (minFilter: TextureFilter, magFilter: TextureFilter): void;
abstract setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void; abstract setWraps (uWrap: TextureWrap, vWrap: TextureWrap): void;
abstract dispose(): void; abstract dispose (): void;
} }
export enum TextureFilter { export enum TextureFilter {
@ -70,7 +70,7 @@ export class TextureRegion {
} }
export class FakeTexture extends Texture { export class FakeTexture extends Texture {
setFilters(minFilter: TextureFilter, magFilter: TextureFilter) { } setFilters (minFilter: TextureFilter, magFilter: TextureFilter) { }
setWraps(uWrap: TextureWrap, vWrap: TextureWrap) { } setWraps (uWrap: TextureWrap, vWrap: TextureWrap) { }
dispose() { } dispose () { }
} }

View File

@ -35,7 +35,7 @@ export class TextureAtlas implements Disposable {
pages = new Array<TextureAtlasPage>(); pages = new Array<TextureAtlasPage>();
regions = new Array<TextureAtlasRegion>(); regions = new Array<TextureAtlasRegion>();
constructor(atlasText: string) { constructor (atlasText: string) {
let reader = new TextureAtlasReader(atlasText); let reader = new TextureAtlasReader(atlasText);
let entry = new Array<string>(4); let entry = new Array<string>(4);
let page: TextureAtlasPage = null; let page: TextureAtlasPage = null;
@ -176,7 +176,7 @@ export class TextureAtlas implements Disposable {
} }
} }
findRegion(name: string): TextureAtlasRegion { findRegion (name: string): TextureAtlasRegion {
for (let i = 0; i < this.regions.length; i++) { for (let i = 0; i < this.regions.length; i++) {
if (this.regions[i].name == name) { if (this.regions[i].name == name) {
return this.regions[i]; return this.regions[i];
@ -185,12 +185,12 @@ export class TextureAtlas implements Disposable {
return null; return null;
} }
setTextures(assetManager: AssetManagerBase, pathPrefix: string = "") { setTextures (assetManager: AssetManagerBase, pathPrefix: string = "") {
for (let page of this.pages) for (let page of this.pages)
page.setTexture(assetManager.get(pathPrefix + page.name)); page.setTexture(assetManager.get(pathPrefix + page.name));
} }
dispose() { dispose () {
for (let i = 0; i < this.pages.length; i++) { for (let i = 0; i < this.pages.length; i++) {
this.pages[i].texture.dispose(); this.pages[i].texture.dispose();
} }
@ -201,17 +201,17 @@ class TextureAtlasReader {
lines: Array<string>; lines: Array<string>;
index: number = 0; index: number = 0;
constructor(text: string) { constructor (text: string) {
this.lines = text.split(/\r\n|\r|\n/); this.lines = text.split(/\r\n|\r|\n/);
} }
readLine(): string { readLine (): string {
if (this.index >= this.lines.length) if (this.index >= this.lines.length)
return null; return null;
return this.lines[this.index++]; return this.lines[this.index++];
} }
readEntry(entry: string[], line: string): number { readEntry (entry: string[], line: string): number {
if (!line) return 0; if (!line) return 0;
line = line.trim(); line = line.trim();
if (line.length == 0) return 0; if (line.length == 0) return 0;
@ -243,7 +243,7 @@ export class TextureAtlasPage {
height: number; height: number;
pma: boolean; pma: boolean;
setTexture(texture: Texture) { setTexture (texture: Texture) {
this.texture = texture; this.texture = texture;
texture.setFilters(this.minFilter, this.magFilter); texture.setFilters(this.minFilter, this.magFilter);
texture.setWraps(this.uWrap, this.vWrap); texture.setWraps(this.uWrap, this.vWrap);

View File

@ -54,7 +54,7 @@ export class TransformConstraint implements Updatable {
temp = new Vector2(); temp = new Vector2();
active = false; active = false;
constructor(data: TransformConstraintData, skeleton: Skeleton) { constructor (data: TransformConstraintData, skeleton: Skeleton) {
if (!data) throw new Error("data cannot be null."); if (!data) throw new Error("data cannot be null.");
if (!skeleton) throw new Error("skeleton cannot be null."); if (!skeleton) throw new Error("skeleton cannot be null.");
this.data = data; this.data = data;
@ -70,11 +70,11 @@ export class TransformConstraint implements Updatable {
this.target = skeleton.findBone(data.target.name); this.target = skeleton.findBone(data.target.name);
} }
isActive() { isActive () {
return this.active; return this.active;
} }
update() { update () {
if (this.mixRotate == 0 && this.mixX == 0 && this.mixY == 0 && this.mixScaleX == 0 && this.mixScaleX == 0 && this.mixShearY == 0) return; if (this.mixRotate == 0 && this.mixX == 0 && this.mixY == 0 && this.mixScaleX == 0 && this.mixScaleX == 0 && this.mixShearY == 0) return;
if (this.data.local) { if (this.data.local) {
@ -90,7 +90,7 @@ export class TransformConstraint implements Updatable {
} }
} }
applyAbsoluteWorld() { applyAbsoluteWorld () {
let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX,
mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; mixScaleY = this.mixScaleY, mixShearY = this.mixShearY;
let translate = mixX != 0 || mixY != 0; let translate = mixX != 0 || mixY != 0;
@ -158,7 +158,7 @@ export class TransformConstraint implements Updatable {
} }
} }
applyRelativeWorld() { applyRelativeWorld () {
let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX,
mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; mixScaleY = this.mixScaleY, mixShearY = this.mixShearY;
let translate = mixX != 0 || mixY != 0; let translate = mixX != 0 || mixY != 0;
@ -222,7 +222,7 @@ export class TransformConstraint implements Updatable {
} }
} }
applyAbsoluteLocal() { applyAbsoluteLocal () {
let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX,
mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; mixScaleY = this.mixScaleY, mixShearY = this.mixShearY;
@ -260,7 +260,7 @@ export class TransformConstraint implements Updatable {
} }
} }
applyRelativeLocal() { applyRelativeLocal () {
let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX, let mixRotate = this.mixRotate, mixX = this.mixX, mixY = this.mixY, mixScaleX = this.mixScaleX,
mixScaleY = this.mixScaleY, mixShearY = this.mixShearY; mixScaleY = this.mixScaleY, mixShearY = this.mixShearY;

View File

@ -69,7 +69,7 @@ export class TransformConstraintData extends ConstraintData {
relative = false; relative = false;
local = false; local = false;
constructor(name: string) { constructor (name: string) {
super(name, 0, false); super(name, 0, false);
} }
} }

View File

@ -45,7 +45,7 @@ export class Triangulator {
return new Array<number>(); return new Array<number>();
}); });
public triangulate(verticesArray: NumberArrayLike): Array<number> { public triangulate (verticesArray: NumberArrayLike): Array<number> {
let vertices = verticesArray; let vertices = verticesArray;
let vertexCount = verticesArray.length >> 1; let vertexCount = verticesArray.length >> 1;
@ -121,7 +121,7 @@ export class Triangulator {
return triangles; return triangles;
} }
decompose(verticesArray: Array<number>, triangles: Array<number>): Array<Array<number>> { decompose (verticesArray: Array<number>, triangles: Array<number>): Array<Array<number>> {
let vertices = verticesArray; let vertices = verticesArray;
let convexPolygons = this.convexPolygons; let convexPolygons = this.convexPolygons;
this.polygonPool.freeAll(convexPolygons); this.polygonPool.freeAll(convexPolygons);
@ -250,7 +250,7 @@ export class Triangulator {
return convexPolygons; return convexPolygons;
} }
private static isConcave(index: number, vertexCount: number, vertices: NumberArrayLike, indices: NumberArrayLike): boolean { private static isConcave (index: number, vertexCount: number, vertices: NumberArrayLike, indices: NumberArrayLike): boolean {
let previous = indices[(vertexCount + index - 1) % vertexCount] << 1; let previous = indices[(vertexCount + index - 1) % vertexCount] << 1;
let current = indices[index] << 1; let current = indices[index] << 1;
let next = indices[(index + 1) % vertexCount] << 1; let next = indices[(index + 1) % vertexCount] << 1;
@ -258,11 +258,11 @@ export class Triangulator {
vertices[next + 1]); vertices[next + 1]);
} }
private static positiveArea(p1x: number, p1y: number, p2x: number, p2y: number, p3x: number, p3y: number): boolean { private static positiveArea (p1x: number, p1y: number, p2x: number, p2y: number, p3x: number, p3y: number): boolean {
return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0; return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0;
} }
private static winding(p1x: number, p1y: number, p2x: number, p2y: number, p3x: number, p3y: number): number { private static winding (p1x: number, p1y: number, p2x: number, p2y: number, p3x: number, p3y: number): number {
let px = p2x - p1x, py = p2y - p1y; let px = p2x - p1x, py = p2y - p1y;
return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1; return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1;
} }

View File

@ -29,11 +29,11 @@
/** The interface for items updated by {@link Skeleton#updateWorldTransform()}. */ /** The interface for items updated by {@link Skeleton#updateWorldTransform()}. */
export interface Updatable { export interface Updatable {
update(): void; update (): void;
/** Returns false when this item has not been updated because a skin is required and the {@link Skeleton#skin active skin} /** Returns false when this item has not been updated because a skin is required and the {@link Skeleton#skin active skin}
* does not contain this item. * does not contain this item.
* @see Skin#getBones() * @see Skin#getBones()
* @see Skin#getConstraints() */ * @see Skin#getConstraints() */
isActive(): boolean; isActive (): boolean;
} }

View File

@ -37,21 +37,21 @@ export interface StringMap<T> {
export class IntSet { export class IntSet {
array = new Array<number>(); array = new Array<number>();
add(value: number): boolean { add (value: number): boolean {
let contains = this.contains(value); let contains = this.contains(value);
this.array[value | 0] = value | 0; this.array[value | 0] = value | 0;
return !contains; return !contains;
} }
contains(value: number) { contains (value: number) {
return this.array[value | 0] != undefined; return this.array[value | 0] != undefined;
} }
remove(value: number) { remove (value: number) {
this.array[value | 0] = undefined; this.array[value | 0] = undefined;
} }
clear() { clear () {
this.array.length = 0; this.array.length = 0;
} }
} }
@ -60,7 +60,7 @@ export class StringSet {
entries: StringMap<boolean> = {}; entries: StringMap<boolean> = {};
size = 0; size = 0;
add(value: string): boolean { add (value: string): boolean {
let contains = this.entries[value]; let contains = this.entries[value];
this.entries[value] = true; this.entries[value] = true;
if (!contains) { if (!contains) {
@ -70,18 +70,18 @@ export class StringSet {
return false; return false;
} }
addAll(values: string[]): boolean { addAll (values: string[]): boolean {
let oldSize = this.size; let oldSize = this.size;
for (var i = 0, n = values.length; i < n; i++) for (var i = 0, n = values.length; i < n; i++)
this.add(values[i]); this.add(values[i]);
return oldSize != this.size; return oldSize != this.size;
} }
contains(value: string) { contains (value: string) {
return this.entries[value]; return this.entries[value];
} }
clear() { clear () {
this.entries = {}; this.entries = {};
this.size = 0; this.size = 0;
} }
@ -93,11 +93,11 @@ export interface NumberArrayLike {
} }
export interface Disposable { export interface Disposable {
dispose(): void; dispose (): void;
} }
export interface Restorable { export interface Restorable {
restore(): void; restore (): void;
} }
export class Color { export class Color {
@ -107,10 +107,10 @@ export class Color {
public static BLUE = new Color(0, 0, 1, 1); public static BLUE = new Color(0, 0, 1, 1);
public static MAGENTA = new Color(1, 0, 1, 1); public static MAGENTA = new Color(1, 0, 1, 1);
constructor(public r: number = 0, public g: number = 0, public b: number = 0, public a: number = 0) { constructor (public r: number = 0, public g: number = 0, public b: number = 0, public a: number = 0) {
} }
set(r: number, g: number, b: number, a: number) { set (r: number, g: number, b: number, a: number) {
this.r = r; this.r = r;
this.g = g; this.g = g;
this.b = b; this.b = b;
@ -118,7 +118,7 @@ export class Color {
return this.clamp(); return this.clamp();
} }
setFromColor(c: Color) { setFromColor (c: Color) {
this.r = c.r; this.r = c.r;
this.g = c.g; this.g = c.g;
this.b = c.b; this.b = c.b;
@ -126,7 +126,7 @@ export class Color {
return this; return this;
} }
setFromString(hex: string) { setFromString (hex: string) {
hex = hex.charAt(0) == '#' ? hex.substr(1) : hex; hex = hex.charAt(0) == '#' ? hex.substr(1) : hex;
this.r = parseInt(hex.substr(0, 2), 16) / 255; this.r = parseInt(hex.substr(0, 2), 16) / 255;
this.g = parseInt(hex.substr(2, 2), 16) / 255; this.g = parseInt(hex.substr(2, 2), 16) / 255;
@ -135,7 +135,7 @@ export class Color {
return this; return this;
} }
add(r: number, g: number, b: number, a: number) { add (r: number, g: number, b: number, a: number) {
this.r += r; this.r += r;
this.g += g; this.g += g;
this.b += b; this.b += b;
@ -143,7 +143,7 @@ export class Color {
return this.clamp(); return this.clamp();
} }
clamp() { clamp () {
if (this.r < 0) this.r = 0; if (this.r < 0) this.r = 0;
else if (this.r > 1) this.r = 1; else if (this.r > 1) this.r = 1;
@ -158,20 +158,20 @@ export class Color {
return this; return this;
} }
static rgba8888ToColor(color: Color, value: number) { static rgba8888ToColor (color: Color, value: number) {
color.r = ((value & 0xff000000) >>> 24) / 255; color.r = ((value & 0xff000000) >>> 24) / 255;
color.g = ((value & 0x00ff0000) >>> 16) / 255; color.g = ((value & 0x00ff0000) >>> 16) / 255;
color.b = ((value & 0x0000ff00) >>> 8) / 255; color.b = ((value & 0x0000ff00) >>> 8) / 255;
color.a = ((value & 0x000000ff)) / 255; color.a = ((value & 0x000000ff)) / 255;
} }
static rgb888ToColor(color: Color, value: number) { static rgb888ToColor (color: Color, value: number) {
color.r = ((value & 0x00ff0000) >>> 16) / 255; color.r = ((value & 0x00ff0000) >>> 16) / 255;
color.g = ((value & 0x0000ff00) >>> 8) / 255; color.g = ((value & 0x0000ff00) >>> 8) / 255;
color.b = ((value & 0x000000ff)) / 255; color.b = ((value & 0x000000ff)) / 255;
} }
static fromString(hex: string): Color { static fromString (hex: string): Color {
return new Color().setFromString(hex); return new Color().setFromString(hex);
} }
} }
@ -184,52 +184,52 @@ export class MathUtils {
static degreesToRadians = MathUtils.PI / 180; static degreesToRadians = MathUtils.PI / 180;
static degRad = MathUtils.degreesToRadians; static degRad = MathUtils.degreesToRadians;
static clamp(value: number, min: number, max: number) { static clamp (value: number, min: number, max: number) {
if (value < min) return min; if (value < min) return min;
if (value > max) return max; if (value > max) return max;
return value; return value;
} }
static cosDeg(degrees: number) { static cosDeg (degrees: number) {
return Math.cos(degrees * MathUtils.degRad); return Math.cos(degrees * MathUtils.degRad);
} }
static sinDeg(degrees: number) { static sinDeg (degrees: number) {
return Math.sin(degrees * MathUtils.degRad); return Math.sin(degrees * MathUtils.degRad);
} }
static signum(value: number): number { static signum (value: number): number {
return value > 0 ? 1 : value < 0 ? -1 : 0; return value > 0 ? 1 : value < 0 ? -1 : 0;
} }
static toInt(x: number) { static toInt (x: number) {
return x > 0 ? Math.floor(x) : Math.ceil(x); return x > 0 ? Math.floor(x) : Math.ceil(x);
} }
static cbrt(x: number) { static cbrt (x: number) {
let y = Math.pow(Math.abs(x), 1 / 3); let y = Math.pow(Math.abs(x), 1 / 3);
return x < 0 ? -y : y; return x < 0 ? -y : y;
} }
static randomTriangular(min: number, max: number): number { static randomTriangular (min: number, max: number): number {
return MathUtils.randomTriangularWith(min, max, (min + max) * 0.5); return MathUtils.randomTriangularWith(min, max, (min + max) * 0.5);
} }
static randomTriangularWith(min: number, max: number, mode: number): number { static randomTriangularWith (min: number, max: number, mode: number): number {
let u = Math.random(); let u = Math.random();
let d = max - min; let d = max - min;
if (u <= (mode - min) / d) return min + Math.sqrt(u * d * (mode - min)); if (u <= (mode - min) / d) return min + Math.sqrt(u * d * (mode - min));
return max - Math.sqrt((1 - u) * d * (max - mode)); return max - Math.sqrt((1 - u) * d * (max - mode));
} }
static isPowerOfTwo(value: number) { static isPowerOfTwo (value: number) {
return value && (value & (value - 1)) === 0; return value && (value & (value - 1)) === 0;
} }
} }
export abstract class Interpolation { export abstract class Interpolation {
protected abstract applyInternal(a: number): number; protected abstract applyInternal (a: number): number;
apply(start: number, end: number, a: number): number { apply (start: number, end: number, a: number): number {
return start + (end - start) * this.applyInternal(a); return start + (end - start) * this.applyInternal(a);
} }
} }
@ -237,23 +237,23 @@ export abstract class Interpolation {
export class Pow extends Interpolation { export class Pow extends Interpolation {
protected power = 2; protected power = 2;
constructor(power: number) { constructor (power: number) {
super(); super();
this.power = power; this.power = power;
} }
applyInternal(a: number): number { applyInternal (a: number): number {
if (a <= 0.5) return Math.pow(a * 2, this.power) / 2; if (a <= 0.5) return Math.pow(a * 2, this.power) / 2;
return Math.pow((a - 1) * 2, this.power) / (this.power % 2 == 0 ? -2 : 2) + 1; return Math.pow((a - 1) * 2, this.power) / (this.power % 2 == 0 ? -2 : 2) + 1;
} }
} }
export class PowOut extends Pow { export class PowOut extends Pow {
constructor(power: number) { constructor (power: number) {
super(power); super(power);
} }
applyInternal(a: number): number { applyInternal (a: number): number {
return Math.pow(a - 1, this.power) * (this.power % 2 == 0 ? -1 : 1) + 1; return Math.pow(a - 1, this.power) * (this.power % 2 == 0 ? -1 : 1) + 1;
} }
} }
@ -261,18 +261,18 @@ export class PowOut extends Pow {
export class Utils { export class Utils {
static SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== "undefined"; static SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== "undefined";
static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number) { static arrayCopy<T> (source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number) {
for (let i = sourceStart, j = destStart; i < sourceStart + numElements; i++, j++) { for (let i = sourceStart, j = destStart; i < sourceStart + numElements; i++, j++) {
dest[j] = source[i]; dest[j] = source[i];
} }
} }
static arrayFill<T>(array: ArrayLike<T>, fromIndex: number, toIndex: number, value: T) { static arrayFill<T> (array: ArrayLike<T>, fromIndex: number, toIndex: number, value: T) {
for (let i = fromIndex; i < toIndex; i++) for (let i = fromIndex; i < toIndex; i++)
array[i] = value; array[i] = value;
} }
static setArraySize<T>(array: Array<T>, size: number, value: any = 0): Array<T> { static setArraySize<T> (array: Array<T>, size: number, value: any = 0): Array<T> {
let oldSize = array.length; let oldSize = array.length;
if (oldSize == size) return array; if (oldSize == size) return array;
array.length = size; array.length = size;
@ -282,18 +282,18 @@ export class Utils {
return array; return array;
} }
static ensureArrayCapacity<T>(array: Array<T>, size: number, value: any = 0): Array<T> { static ensureArrayCapacity<T> (array: Array<T>, size: number, value: any = 0): Array<T> {
if (array.length >= size) return array; if (array.length >= size) return array;
return Utils.setArraySize(array, size, value); return Utils.setArraySize(array, size, value);
} }
static newArray<T>(size: number, defaultValue: T): Array<T> { static newArray<T> (size: number, defaultValue: T): Array<T> {
let array = new Array<T>(size); let array = new Array<T>(size);
for (let i = 0; i < size; i++) array[i] = defaultValue; for (let i = 0; i < size; i++) array[i] = defaultValue;
return array; return array;
} }
static newFloatArray(size: number): NumberArrayLike { static newFloatArray (size: number): NumberArrayLike {
if (Utils.SUPPORTS_TYPED_ARRAYS) if (Utils.SUPPORTS_TYPED_ARRAYS)
return new Float32Array(size) return new Float32Array(size)
else { else {
@ -303,7 +303,7 @@ export class Utils {
} }
} }
static newShortArray(size: number): NumberArrayLike { static newShortArray (size: number): NumberArrayLike {
if (Utils.SUPPORTS_TYPED_ARRAYS) if (Utils.SUPPORTS_TYPED_ARRAYS)
return new Int16Array(size) return new Int16Array(size)
else { else {
@ -313,31 +313,31 @@ export class Utils {
} }
} }
static toFloatArray(array: Array<number>) { static toFloatArray (array: Array<number>) {
return Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array; return Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array;
} }
static toSinglePrecision(value: number) { static toSinglePrecision (value: number) {
return Utils.SUPPORTS_TYPED_ARRAYS ? Math.fround(value) : value; return Utils.SUPPORTS_TYPED_ARRAYS ? Math.fround(value) : value;
} }
// This function is used to fix WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109 // This function is used to fix WebKit 602 specific issue described at http://esotericsoftware.com/forum/iOS-10-disappearing-graphics-10109
static webkit602BugfixHelper(alpha: number, blend: MixBlend) { static webkit602BugfixHelper (alpha: number, blend: MixBlend) {
} }
static contains<T>(array: Array<T>, element: T, identity = true) { static contains<T> (array: Array<T>, element: T, identity = true) {
for (var i = 0; i < array.length; i++) for (var i = 0; i < array.length; i++)
if (array[i] == element) return true; if (array[i] == element) return true;
return false; return false;
} }
static enumValue(type: any, name: string) { static enumValue (type: any, name: string) {
return type[name[0].toUpperCase() + name.slice(1)]; return type[name[0].toUpperCase() + name.slice(1)];
} }
} }
export class DebugUtils { export class DebugUtils {
static logBones(skeleton: Skeleton) { static logBones (skeleton: Skeleton) {
for (let i = 0; i < skeleton.bones.length; i++) { for (let i = 0; i < skeleton.bones.length; i++) {
let bone = skeleton.bones[i]; let bone = skeleton.bones[i];
console.log(bone.data.name + ", " + bone.a + ", " + bone.b + ", " + bone.c + ", " + bone.d + ", " + bone.worldX + ", " + bone.worldY); console.log(bone.data.name + ", " + bone.a + ", " + bone.b + ", " + bone.c + ", " + bone.d + ", " + bone.worldX + ", " + bone.worldY);
@ -349,46 +349,46 @@ export class Pool<T> {
private items = new Array<T>(); private items = new Array<T>();
private instantiator: () => T; private instantiator: () => T;
constructor(instantiator: () => T) { constructor (instantiator: () => T) {
this.instantiator = instantiator; this.instantiator = instantiator;
} }
obtain() { obtain () {
return this.items.length > 0 ? this.items.pop() : this.instantiator(); return this.items.length > 0 ? this.items.pop() : this.instantiator();
} }
free(item: T) { free (item: T) {
if ((item as any).reset) (item as any).reset(); if ((item as any).reset) (item as any).reset();
this.items.push(item); this.items.push(item);
} }
freeAll(items: ArrayLike<T>) { freeAll (items: ArrayLike<T>) {
for (let i = 0; i < items.length; i++) for (let i = 0; i < items.length; i++)
this.free(items[i]); this.free(items[i]);
} }
clear() { clear () {
this.items.length = 0; this.items.length = 0;
} }
} }
export class Vector2 { export class Vector2 {
constructor(public x = 0, public y = 0) { constructor (public x = 0, public y = 0) {
} }
set(x: number, y: number): Vector2 { set (x: number, y: number): Vector2 {
this.x = x; this.x = x;
this.y = y; this.y = y;
return this; return this;
} }
length() { length () {
let x = this.x; let x = this.x;
let y = this.y; let y = this.y;
return Math.sqrt(x * x + y * y); return Math.sqrt(x * x + y * y);
} }
normalize() { normalize () {
let len = this.length(); let len = this.length();
if (len != 0) { if (len != 0) {
this.x /= len; this.x /= len;
@ -408,7 +408,7 @@ export class TimeKeeper {
private frameCount = 0; private frameCount = 0;
private frameTime = 0; private frameTime = 0;
update() { update () {
let now = Date.now() / 1000; let now = Date.now() / 1000;
this.delta = now - this.lastTime; this.delta = now - this.lastTime;
this.frameTime += this.delta; this.frameTime += this.delta;
@ -437,22 +437,22 @@ export class WindowedMean {
mean = 0; mean = 0;
dirty = true; dirty = true;
constructor(windowSize: number = 32) { constructor (windowSize: number = 32) {
this.values = new Array<number>(windowSize); this.values = new Array<number>(windowSize);
} }
hasEnoughData() { hasEnoughData () {
return this.addedValues >= this.values.length; return this.addedValues >= this.values.length;
} }
addValue(value: number) { addValue (value: number) {
if (this.addedValues < this.values.length) this.addedValues++; if (this.addedValues < this.values.length) this.addedValues++;
this.values[this.lastValue++] = value; this.values[this.lastValue++] = value;
if (this.lastValue > this.values.length - 1) this.lastValue = 0; if (this.lastValue > this.values.length - 1) this.lastValue = 0;
this.dirty = true; this.dirty = true;
} }
getMean() { getMean () {
if (this.hasEnoughData()) { if (this.hasEnoughData()) {
if (this.dirty) { if (this.dirty) {
let mean = 0; let mean = 0;

View File

@ -31,7 +31,7 @@ import { Skeleton } from "./Skeleton";
import { Vector2, Color } from "./Utils"; import { Vector2, Color } from "./Utils";
export interface VertexEffect { export interface VertexEffect {
begin(skeleton: Skeleton): void; begin (skeleton: Skeleton): void;
transform(position: Vector2, uv: Vector2, light: Color, dark: Color): void; transform (position: Vector2, uv: Vector2, light: Color, dark: Color): void;
end(): void; end (): void;
} }

View File

@ -34,12 +34,12 @@ import { NumberArrayLike, Utils } from "../Utils";
export abstract class Attachment { export abstract class Attachment {
name: string; name: string;
constructor(name: string) { constructor (name: string) {
if (!name) throw new Error("name cannot be null."); if (!name) throw new Error("name cannot be null.");
this.name = name; this.name = name;
} }
abstract copy(): Attachment; abstract copy (): Attachment;
} }
/** Base class for an attachment with vertices that are transformed by one or more bones and can be deformed by a slot's /** Base class for an attachment with vertices that are transformed by one or more bones and can be deformed by a slot's
@ -67,7 +67,7 @@ export abstract class VertexAttachment extends Attachment {
/** Deform keys for the deform attachment are also applied to this attachment. May be null if no deform keys should be applied. */ /** Deform keys for the deform attachment are also applied to this attachment. May be null if no deform keys should be applied. */
deformAttachment: VertexAttachment = this; deformAttachment: VertexAttachment = this;
constructor(name: string) { constructor (name: string) {
super(name); super(name);
} }
@ -82,7 +82,7 @@ export abstract class VertexAttachment extends Attachment {
* `stride` / 2. * `stride` / 2.
* @param offset The `worldVertices` index to begin writing values. * @param offset The `worldVertices` index to begin writing values.
* @param stride The number of `worldVertices` entries between the value pairs written. */ * @param stride The number of `worldVertices` entries between the value pairs written. */
computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: NumberArrayLike, offset: number, stride: number) { computeWorldVertices (slot: Slot, start: number, count: number, worldVertices: NumberArrayLike, offset: number, stride: number) {
count = offset + (count >> 1) * stride; count = offset + (count >> 1) * stride;
let skeleton = slot.bone.skeleton; let skeleton = slot.bone.skeleton;
let deformArray = slot.deform; let deformArray = slot.deform;
@ -141,7 +141,7 @@ export abstract class VertexAttachment extends Attachment {
} }
/** Does not copy id (generated) or name (set on construction). **/ /** Does not copy id (generated) or name (set on construction). **/
copyTo(attachment: VertexAttachment) { copyTo (attachment: VertexAttachment) {
if (this.bones) { if (this.bones) {
attachment.bones = new Array<number>(this.bones.length); attachment.bones = new Array<number>(this.bones.length);
Utils.arrayCopy(this.bones, 0, attachment.bones, 0, this.bones.length); Utils.arrayCopy(this.bones, 0, attachment.bones, 0, this.bones.length);

View File

@ -41,20 +41,20 @@ import { RegionAttachment } from "./RegionAttachment";
* Runtimes Guide. */ * Runtimes Guide. */
export interface AttachmentLoader { export interface AttachmentLoader {
/** @return May be null to not load an attachment. */ /** @return May be null to not load an attachment. */
newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment; newRegionAttachment (skin: Skin, name: string, path: string): RegionAttachment;
/** @return May be null to not load an attachment. */ /** @return May be null to not load an attachment. */
newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment; newMeshAttachment (skin: Skin, name: string, path: string): MeshAttachment;
/** @return May be null to not load an attachment. */ /** @return May be null to not load an attachment. */
newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment; newBoundingBoxAttachment (skin: Skin, name: string): BoundingBoxAttachment;
/** @return May be null to not load an attachment */ /** @return May be null to not load an attachment */
newPathAttachment(skin: Skin, name: string): PathAttachment; newPathAttachment (skin: Skin, name: string): PathAttachment;
/** @return May be null to not load an attachment */ /** @return May be null to not load an attachment */
newPointAttachment(skin: Skin, name: string): PointAttachment; newPointAttachment (skin: Skin, name: string): PointAttachment;
/** @return May be null to not load an attachment */ /** @return May be null to not load an attachment */
newClippingAttachment(skin: Skin, name: string): ClippingAttachment; newClippingAttachment (skin: Skin, name: string): ClippingAttachment;
} }

View File

@ -38,11 +38,11 @@ import { VertexAttachment, Attachment } from "./Attachment";
export class BoundingBoxAttachment extends VertexAttachment { export class BoundingBoxAttachment extends VertexAttachment {
color = new Color(1, 1, 1, 1); color = new Color(1, 1, 1, 1);
constructor(name: string) { constructor (name: string) {
super(name); super(name);
} }
copy(): Attachment { copy (): Attachment {
let copy = new BoundingBoxAttachment(this.name); let copy = new BoundingBoxAttachment(this.name);
this.copyTo(copy); this.copyTo(copy);
copy.color.setFromColor(this.color); copy.color.setFromColor(this.color);

View File

@ -42,11 +42,11 @@ export class ClippingAttachment extends VertexAttachment {
* are not usually rendered at runtime. */ * are not usually rendered at runtime. */
color = new Color(0.2275, 0.2275, 0.8078, 1); // ce3a3aff color = new Color(0.2275, 0.2275, 0.8078, 1); // ce3a3aff
constructor(name: string) { constructor (name: string) {
super(name); super(name);
} }
copy(): Attachment { copy (): Attachment {
let copy = new ClippingAttachment(this.name); let copy = new ClippingAttachment(this.name);
this.copyTo(copy); this.copyTo(copy);
copy.endSlot = this.endSlot; copy.endSlot = this.endSlot;

View File

@ -72,13 +72,13 @@ export class MeshAttachment extends VertexAttachment {
private parentMesh: MeshAttachment; private parentMesh: MeshAttachment;
tempColor = new Color(0, 0, 0, 0); tempColor = new Color(0, 0, 0, 0);
constructor(name: string) { constructor (name: string) {
super(name); super(name);
} }
/** Calculates {@link #uvs} using {@link #regionUVs} and the {@link #region}. Must be called after changing the region UVs or /** Calculates {@link #uvs} using {@link #regionUVs} and the {@link #region}. Must be called after changing the region UVs or
* region. */ * region. */
updateUVs() { updateUVs () {
let regionUVs = this.regionUVs; let regionUVs = this.regionUVs;
if (!this.uvs || this.uvs.length != regionUVs.length) this.uvs = Utils.newFloatArray(regionUVs.length); if (!this.uvs || this.uvs.length != regionUVs.length) this.uvs = Utils.newFloatArray(regionUVs.length);
let uvs = this.uvs; let uvs = this.uvs;
@ -140,12 +140,12 @@ export class MeshAttachment extends VertexAttachment {
/** The parent mesh if this is a linked mesh, else null. A linked mesh shares the {@link #bones}, {@link #vertices}, /** The parent mesh if this is a linked mesh, else null. A linked mesh shares the {@link #bones}, {@link #vertices},
* {@link #regionUVs}, {@link #triangles}, {@link #hullLength}, {@link #edges}, {@link #width}, and {@link #height} with the * {@link #regionUVs}, {@link #triangles}, {@link #hullLength}, {@link #edges}, {@link #width}, and {@link #height} with the
* parent mesh, but may have a different {@link #name} or {@link #path} (and therefore a different texture). */ * parent mesh, but may have a different {@link #name} or {@link #path} (and therefore a different texture). */
getParentMesh() { getParentMesh () {
return this.parentMesh; return this.parentMesh;
} }
/** @param parentMesh May be null. */ /** @param parentMesh May be null. */
setParentMesh(parentMesh: MeshAttachment) { setParentMesh (parentMesh: MeshAttachment) {
this.parentMesh = parentMesh; this.parentMesh = parentMesh;
if (parentMesh) { if (parentMesh) {
this.bones = parentMesh.bones; this.bones = parentMesh.bones;
@ -158,7 +158,7 @@ export class MeshAttachment extends VertexAttachment {
} }
} }
copy(): Attachment { copy (): Attachment {
if (this.parentMesh) return this.newLinkedMesh(); if (this.parentMesh) return this.newLinkedMesh();
let copy = new MeshAttachment(this.name); let copy = new MeshAttachment(this.name);
@ -187,7 +187,7 @@ export class MeshAttachment extends VertexAttachment {
} }
/** Returns a new mesh with the {@link #parentMesh} set to this mesh's parent mesh, if any, else to this mesh. **/ /** Returns a new mesh with the {@link #parentMesh} set to this mesh's parent mesh, if any, else to this mesh. **/
newLinkedMesh(): MeshAttachment { newLinkedMesh (): MeshAttachment {
let copy = new MeshAttachment(this.name); let copy = new MeshAttachment(this.name);
copy.region = this.region; copy.region = this.region;
copy.path = this.path; copy.path = this.path;

View File

@ -49,11 +49,11 @@ export class PathAttachment extends VertexAttachment {
* rendered at runtime. */ * rendered at runtime. */
color = new Color(1, 1, 1, 1); color = new Color(1, 1, 1, 1);
constructor(name: string) { constructor (name: string) {
super(name); super(name);
} }
copy(): Attachment { copy (): Attachment {
let copy = new PathAttachment(this.name); let copy = new PathAttachment(this.name);
this.copyTo(copy); this.copyTo(copy);
copy.lengths = new Array<number>(this.lengths.length); copy.lengths = new Array<number>(this.lengths.length);

View File

@ -43,24 +43,24 @@ export class PointAttachment extends VertexAttachment {
* are not usually rendered at runtime. */ * are not usually rendered at runtime. */
color = new Color(0.38, 0.94, 0, 1); color = new Color(0.38, 0.94, 0, 1);
constructor(name: string) { constructor (name: string) {
super(name); super(name);
} }
computeWorldPosition(bone: Bone, point: Vector2) { computeWorldPosition (bone: Bone, point: Vector2) {
point.x = this.x * bone.a + this.y * bone.b + bone.worldX; point.x = this.x * bone.a + this.y * bone.b + bone.worldX;
point.y = this.x * bone.c + this.y * bone.d + bone.worldY; point.y = this.x * bone.c + this.y * bone.d + bone.worldY;
return point; return point;
} }
computeWorldRotation(bone: Bone) { computeWorldRotation (bone: Bone) {
let cos = MathUtils.cosDeg(this.rotation), sin = MathUtils.sinDeg(this.rotation); let cos = MathUtils.cosDeg(this.rotation), sin = MathUtils.sinDeg(this.rotation);
let x = cos * bone.a + sin * bone.b; let x = cos * bone.a + sin * bone.b;
let y = cos * bone.c + sin * bone.d; let y = cos * bone.c + sin * bone.d;
return Math.atan2(y, x) * MathUtils.radDeg; return Math.atan2(y, x) * MathUtils.radDeg;
} }
copy(): Attachment { copy (): Attachment {
let copy = new PointAttachment(this.name); let copy = new PointAttachment(this.name);
copy.x = this.x; copy.x = this.x;
copy.y = this.y; copy.y = this.y;

View File

@ -75,12 +75,12 @@ export class RegionAttachment extends Attachment {
tempColor = new Color(1, 1, 1, 1); tempColor = new Color(1, 1, 1, 1);
constructor(name: string) { constructor (name: string) {
super(name); super(name);
} }
/** Calculates the {@link #offset} using the region settings. Must be called after changing region settings. */ /** Calculates the {@link #offset} using the region settings. Must be called after changing region settings. */
updateOffset(): void { updateOffset (): void {
let region = this.region; let region = this.region;
let regionScaleX = this.width / this.region.originalWidth * this.scaleX; let regionScaleX = this.width / this.region.originalWidth * this.scaleX;
let regionScaleY = this.height / this.region.originalHeight * this.scaleY; let regionScaleY = this.height / this.region.originalHeight * this.scaleY;
@ -111,7 +111,7 @@ export class RegionAttachment extends Attachment {
offset[7] = localYCos + localX2Sin; offset[7] = localYCos + localX2Sin;
} }
setRegion(region: TextureRegion): void { setRegion (region: TextureRegion): void {
this.region = region; this.region = region;
let uvs = this.uvs; let uvs = this.uvs;
if (region.degrees == 90) { if (region.degrees == 90) {
@ -142,7 +142,7 @@ export class RegionAttachment extends Attachment {
* @param worldVertices The output world vertices. Must have a length >= `offset` + 8. * @param worldVertices The output world vertices. Must have a length >= `offset` + 8.
* @param offset The `worldVertices` index to begin writing values. * @param offset The `worldVertices` index to begin writing values.
* @param stride The number of `worldVertices` entries between the value pairs written. */ * @param stride The number of `worldVertices` entries between the value pairs written. */
computeWorldVertices(bone: Bone, worldVertices: NumberArrayLike, offset: number, stride: number) { computeWorldVertices (bone: Bone, worldVertices: NumberArrayLike, offset: number, stride: number) {
let vertexOffset = this.offset; let vertexOffset = this.offset;
let x = bone.worldX, y = bone.worldY; let x = bone.worldX, y = bone.worldY;
let a = bone.a, b = bone.b, c = bone.c, d = bone.d; let a = bone.a, b = bone.b, c = bone.c, d = bone.d;
@ -172,7 +172,7 @@ export class RegionAttachment extends Attachment {
worldVertices[offset + 1] = offsetX * c + offsetY * d + y; worldVertices[offset + 1] = offsetX * c + offsetY * d + y;
} }
copy(): Attachment { copy (): Attachment {
let copy = new RegionAttachment(this.name); let copy = new RegionAttachment(this.name);
copy.region = this.region; copy.region = this.region;
copy.rendererObject = this.rendererObject; copy.rendererObject = this.rendererObject;

View File

@ -35,19 +35,19 @@ export class JitterEffect implements VertexEffect {
jitterX = 0; jitterX = 0;
jitterY = 0; jitterY = 0;
constructor(jitterX: number, jitterY: number) { constructor (jitterX: number, jitterY: number) {
this.jitterX = jitterX; this.jitterX = jitterX;
this.jitterY = jitterY; this.jitterY = jitterY;
} }
begin(skeleton: Skeleton): void { begin (skeleton: Skeleton): void {
} }
transform(position: Vector2, uv: Vector2, light: Color, dark: Color): void { transform (position: Vector2, uv: Vector2, light: Color, dark: Color): void {
position.x += MathUtils.randomTriangular(-this.jitterX, this.jitterY); position.x += MathUtils.randomTriangular(-this.jitterX, this.jitterY);
position.y += MathUtils.randomTriangular(-this.jitterX, this.jitterY); position.y += MathUtils.randomTriangular(-this.jitterX, this.jitterY);
} }
end(): void { end (): void {
} }
} }

View File

@ -40,16 +40,16 @@ export class SwirlEffect implements VertexEffect {
private worldX = 0; private worldX = 0;
private worldY = 0; private worldY = 0;
constructor(radius: number) { constructor (radius: number) {
this.radius = radius; this.radius = radius;
} }
begin(skeleton: Skeleton): void { begin (skeleton: Skeleton): void {
this.worldX = skeleton.x + this.centerX; this.worldX = skeleton.x + this.centerX;
this.worldY = skeleton.y + this.centerY; this.worldY = skeleton.y + this.centerY;
} }
transform(position: Vector2, uv: Vector2, light: Color, dark: Color): void { transform (position: Vector2, uv: Vector2, light: Color, dark: Color): void {
let radAngle = this.angle * MathUtils.degreesToRadians; let radAngle = this.angle * MathUtils.degreesToRadians;
let x = position.x - this.worldX; let x = position.x - this.worldX;
let y = position.y - this.worldY; let y = position.y - this.worldY;
@ -63,6 +63,6 @@ export class SwirlEffect implements VertexEffect {
} }
} }
end(): void { end (): void {
} }
} }

View File

@ -217,7 +217,7 @@ export class SpinePlayer {
private previousViewport: Viewport; private previousViewport: Viewport;
private viewportTransitionStart = 0; private viewportTransitionStart = 0;
constructor(parent: HTMLElement | string, private config: SpinePlayerConfig) { constructor (parent: HTMLElement | string, private config: SpinePlayerConfig) {
this.parent = typeof parent === "string" ? document.getElementById(parent) : parent; this.parent = typeof parent === "string" ? document.getElementById(parent) : parent;
if (!this.parent) throw new Error("SpinePlayer parent not found: " + parent); if (!this.parent) throw new Error("SpinePlayer parent not found: " + parent);
@ -254,7 +254,7 @@ export class SpinePlayer {
requestAnimationFrame(() => this.drawFrame()); requestAnimationFrame(() => this.drawFrame());
} }
private validateConfig(config: SpinePlayerConfig) { private validateConfig (config: SpinePlayerConfig) {
if (!config) throw new Error("A configuration object must be passed to to new SpinePlayer()."); if (!config) throw new Error("A configuration object must be passed to to new SpinePlayer().");
if ((config as any).skelUrl) config.binaryUrl = (config as any).skelUrl; if ((config as any).skelUrl) config.binaryUrl = (config as any).skelUrl;
if (!config.jsonUrl && !config.binaryUrl) throw new Error("A URL must be specified for the skeleton JSON or binary file."); if (!config.jsonUrl && !config.binaryUrl) throw new Error("A URL must be specified for the skeleton JSON or binary file.");
@ -278,7 +278,7 @@ export class SpinePlayer {
if (config.defaultMix === void 0) config.defaultMix = 0.25; if (config.defaultMix === void 0) config.defaultMix = 0.25;
} }
private initialize(): HTMLElement { private initialize (): HTMLElement {
let config = this.config; let config = this.config;
let dom = this.dom; let dom = this.dom;
@ -391,7 +391,7 @@ export class SpinePlayer {
return dom; return dom;
} }
private loadSkeleton() { private loadSkeleton () {
if (this.error) return; if (this.error) return;
if (this.assetManager.hasErrors()) if (this.assetManager.hasErrors())
@ -515,7 +515,7 @@ export class SpinePlayer {
} }
} }
private setupInput() { private setupInput () {
let config = this.config; let config = this.config;
let controlBones = config.controlBones; let controlBones = config.controlBones;
if (!controlBones.length && !config.showControls) return; if (!controlBones.length && !config.showControls) return;
@ -621,7 +621,7 @@ export class SpinePlayer {
} }
} }
play() { play () {
this.paused = false; this.paused = false;
let config = this.config; let config = this.config;
if (config.showControls) { if (config.showControls) {
@ -642,7 +642,7 @@ export class SpinePlayer {
} }
} }
pause() { pause () {
this.paused = true; this.paused = true;
if (this.config.showControls) { if (this.config.showControls) {
this.playerControls.classList.remove("spine-player-controls-hidden"); this.playerControls.classList.remove("spine-player-controls-hidden");
@ -653,19 +653,19 @@ export class SpinePlayer {
} }
/* Sets a new animation and viewport on track 0. */ /* Sets a new animation and viewport on track 0. */
setAnimation(animation: string | Animation, loop: boolean = true): TrackEntry { setAnimation (animation: string | Animation, loop: boolean = true): TrackEntry {
animation = this.setViewport(animation); animation = this.setViewport(animation);
return this.animationState.setAnimationWith(0, animation, loop); return this.animationState.setAnimationWith(0, animation, loop);
} }
/* Adds a new animation and viewport on track 0. */ /* Adds a new animation and viewport on track 0. */
addAnimation(animation: string | Animation, loop: boolean = true, delay: number = 0): TrackEntry { addAnimation (animation: string | Animation, loop: boolean = true, delay: number = 0): TrackEntry {
animation = this.setViewport(animation); animation = this.setViewport(animation);
return this.animationState.addAnimationWith(0, animation, loop, delay); return this.animationState.addAnimationWith(0, animation, loop, delay);
} }
/* Sets the viewport for the specified animation. */ /* Sets the viewport for the specified animation. */
setViewport(animation: string | Animation): Animation { setViewport (animation: string | Animation): Animation {
if (typeof animation == "string") animation = this.skeleton.data.findAnimation(animation); if (typeof animation == "string") animation = this.skeleton.data.findAnimation(animation);
this.previousViewport = this.currentViewport; this.previousViewport = this.currentViewport;
@ -711,13 +711,13 @@ export class SpinePlayer {
return animation; return animation;
} }
private percentageToWorldUnit(size: number, percentageOrAbsolute: string | number): number { private percentageToWorldUnit (size: number, percentageOrAbsolute: string | number): number {
if (typeof percentageOrAbsolute === "string") if (typeof percentageOrAbsolute === "string")
return size * parseFloat(percentageOrAbsolute.substr(0, percentageOrAbsolute.length - 1)) / 100; return size * parseFloat(percentageOrAbsolute.substr(0, percentageOrAbsolute.length - 1)) / 100;
return percentageOrAbsolute; return percentageOrAbsolute;
} }
private calculateAnimationViewport(animation: Animation, viewport: Viewport) { private calculateAnimationViewport (animation: Animation, viewport: Viewport) {
this.skeleton.setToSetupPose(); this.skeleton.setToSetupPose();
let steps = 100, stepTime = animation.duration ? animation.duration / steps : 0, time = 0; let steps = 100, stepTime = animation.duration ? animation.duration / steps : 0, time = 0;
@ -744,7 +744,7 @@ export class SpinePlayer {
viewport.height = maxY - minY; viewport.height = maxY - minY;
} }
private drawFrame(requestNextFrame = true) { private drawFrame (requestNextFrame = true) {
try { try {
if (this.error) return; if (this.error) return;
if (requestNextFrame && !this.stopRequestAnimationFrame) requestAnimationFrame(() => this.drawFrame()); if (requestNextFrame && !this.stopRequestAnimationFrame) requestAnimationFrame(() => this.drawFrame());
@ -884,15 +884,15 @@ export class SpinePlayer {
} }
} }
stopRendering() { stopRendering () {
this.stopRequestAnimationFrame = true; this.stopRequestAnimationFrame = true;
} }
private hidePopup(id: string): boolean { private hidePopup (id: string): boolean {
return this.popup && this.popup.hide(id); return this.popup && this.popup.hide(id);
} }
private showSpeedDialog(speedButton: HTMLElement) { private showSpeedDialog (speedButton: HTMLElement) {
let id = "speed"; let id = "speed";
if (this.hidePopup(id)) return; if (this.hidePopup(id)) return;
@ -912,7 +912,7 @@ export class SpinePlayer {
popup.show(); popup.show();
} }
private showAnimationsDialog(animationsButton: HTMLElement) { private showAnimationsDialog (animationsButton: HTMLElement) {
let id = "animations"; let id = "animations";
if (this.hidePopup(id)) return; if (this.hidePopup(id)) return;
if (!this.skeleton || !this.skeleton.data.animations.length) return; if (!this.skeleton || !this.skeleton.data.animations.length) return;
@ -942,7 +942,7 @@ export class SpinePlayer {
popup.show(); popup.show();
} }
private showSkinsDialog(skinButton: HTMLElement) { private showSkinsDialog (skinButton: HTMLElement) {
let id = "skins"; let id = "skins";
if (this.hidePopup(id)) return; if (this.hidePopup(id)) return;
if (!this.skeleton || !this.skeleton.data.animations.length) return; if (!this.skeleton || !this.skeleton.data.animations.length) return;
@ -970,7 +970,7 @@ export class SpinePlayer {
popup.show(); popup.show();
} }
private showSettingsDialog(settingsButton: HTMLElement) { private showSettingsDialog (settingsButton: HTMLElement) {
let id = "settings"; let id = "settings";
if (this.hidePopup(id)) return; if (this.hidePopup(id)) return;
if (!this.skeleton || !this.skeleton.data.animations.length) return; if (!this.skeleton || !this.skeleton.data.animations.length) return;
@ -998,7 +998,7 @@ export class SpinePlayer {
popup.show(); popup.show();
} }
private showError(message: string, error: Error = null) { private showError (message: string, error: Error = null) {
if (this.error) { if (this.error) {
if (error) throw error; // Don't lose error if showError throws, is caught, and showError is called again. if (error) throw error; // Don't lose error if showError throws, is caught, and showError is called again.
} else { } else {
@ -1016,14 +1016,14 @@ class Popup {
public dom: HTMLElement; public dom: HTMLElement;
private className: string; private className: string;
constructor(private id: string, private button: HTMLElement, private player: SpinePlayer, parent: HTMLElement, htmlContent: string) { constructor (private id: string, private button: HTMLElement, private player: SpinePlayer, parent: HTMLElement, htmlContent: string) {
this.dom = createElement(/*html*/`<div class="spine-player-popup spine-player-hidden"></div>`); this.dom = createElement(/*html*/`<div class="spine-player-popup spine-player-hidden"></div>`);
this.dom.innerHTML = htmlContent; this.dom.innerHTML = htmlContent;
parent.appendChild(this.dom); parent.appendChild(this.dom);
this.className = "spine-player-button-icon-" + id + "-selected"; this.className = "spine-player-button-icon-" + id + "-selected";
} }
hide(id: string): boolean { hide (id: string): boolean {
this.dom.remove(); this.dom.remove();
this.button.classList.remove(this.className); this.button.classList.remove(this.className);
if (this.id == id) { if (this.id == id) {
@ -1032,7 +1032,7 @@ class Popup {
} }
} }
show() { show () {
this.player.popup = this; this.player.popup = this;
this.button.classList.add(this.className); this.button.classList.add(this.className);
this.dom.classList.remove("spine-player-hidden"); this.dom.classList.remove("spine-player-hidden");
@ -1072,9 +1072,9 @@ class Switch {
private enabled = false; private enabled = false;
public change: (value: boolean) => void; public change: (value: boolean) => void;
constructor(private text: string) { } constructor (private text: string) { }
create(): HTMLElement { create (): HTMLElement {
this.switch = createElement(/*html*/` this.switch = createElement(/*html*/`
<div class="spine-player-switch"> <div class="spine-player-switch">
<span class="spine-player-switch-text">${this.text}</span> <span class="spine-player-switch-text">${this.text}</span>
@ -1089,13 +1089,13 @@ class Switch {
return this.switch; return this.switch;
} }
setEnabled(enabled: boolean) { setEnabled (enabled: boolean) {
if (enabled) this.switch.classList.add("active"); if (enabled) this.switch.classList.add("active");
else this.switch.classList.remove("active"); else this.switch.classList.remove("active");
this.enabled = enabled; this.enabled = enabled;
} }
isEnabled(): boolean { isEnabled (): boolean {
return this.enabled; return this.enabled;
} }
} }
@ -1106,9 +1106,9 @@ class Slider {
private knob: HTMLElement; private knob: HTMLElement;
public change: (percentage: number) => void; public change: (percentage: number) => void;
constructor(public snaps = 0, public snapPercentage = 0.1, public big = false) { } constructor (public snaps = 0, public snapPercentage = 0.1, public big = false) { }
create(): HTMLElement { create (): HTMLElement {
this.slider = createElement(/*html*/` this.slider = createElement(/*html*/`
<div class="spine-player-slider ${this.big ? "big" : ""}"> <div class="spine-player-slider ${this.big ? "big" : ""}">
<div class="spine-player-slider-value"></div> <div class="spine-player-slider-value"></div>
@ -1140,7 +1140,7 @@ class Slider {
return this.slider; return this.slider;
} }
setValue(percentage: number): number { setValue (percentage: number): number {
percentage = Math.max(0, Math.min(1, percentage)); percentage = Math.max(0, Math.min(1, percentage));
if (this.snaps) { if (this.snaps) {
let snap = 1 / this.snaps; let snap = 1 / this.snaps;
@ -1158,22 +1158,22 @@ class Slider {
} }
} }
function findWithClass(element: HTMLElement, className: string): HTMLElement { function findWithClass (element: HTMLElement, className: string): HTMLElement {
return element.getElementsByClassName(className)[0] as HTMLElement; return element.getElementsByClassName(className)[0] as HTMLElement;
} }
function createElement(html: string): HTMLElement { function createElement (html: string): HTMLElement {
let div = document.createElement("div"); let div = document.createElement("div");
div.innerHTML = html; div.innerHTML = html;
return div.children[0] as HTMLElement; return div.children[0] as HTMLElement;
} }
function removeClass(elements: HTMLCollection, clazz: string) { function removeClass (elements: HTMLCollection, clazz: string) {
for (let i = 0; i < elements.length; i++) for (let i = 0; i < elements.length; i++)
elements[i].classList.remove(clazz); elements[i].classList.remove(clazz);
} }
function toString(object: any) { function toString (object: any) {
return JSON.stringify(object) return JSON.stringify(object)
.replace(/&/g, "&amp;") .replace(/&/g, "&amp;")
.replace(/</g, "&lt;") .replace(/</g, "&lt;")

View File

@ -27,7 +27,7 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/ *****************************************************************************/
declare function CodeMirror(el: Element, config: any): void; declare function CodeMirror (el: Element, config: any): void;
export class SpinePlayerEditor { export class SpinePlayerEditor {
private static DEFAULT_CODE = private static DEFAULT_CODE =
@ -57,11 +57,11 @@ body { margin: 0px; }
private code: any; private code: any;
private player: HTMLIFrameElement; private player: HTMLIFrameElement;
constructor(parent: HTMLElement) { constructor (parent: HTMLElement) {
this.render(parent); this.render(parent);
} }
private render(parent: HTMLElement) { private render (parent: HTMLElement) {
let dom = /*html*/` let dom = /*html*/`
<div class="spine-player-editor-container"> <div class="spine-player-editor-container">
<div class="spine-player-editor-code"></div> <div class="spine-player-editor-code"></div>
@ -90,19 +90,19 @@ body { margin: 0px; }
}) })
} }
setPreAndPostfix(prefix: string, postfix: string) { setPreAndPostfix (prefix: string, postfix: string) {
this.prefix = prefix; this.prefix = prefix;
this.postfix = postfix; this.postfix = postfix;
this.startPlayer() this.startPlayer()
} }
setCode(code: string) { setCode (code: string) {
this.code.setValue(code); this.code.setValue(code);
this.startPlayer(); this.startPlayer();
} }
private timerId = 0; private timerId = 0;
startPlayer() { startPlayer () {
clearTimeout(this.timerId); clearTimeout(this.timerId);
this.timerId = setTimeout(() => { this.timerId = setTimeout(() => {
let code = this.code.getDoc().getValue(); let code = this.code.getDoc().getValue();

View File

@ -31,7 +31,7 @@ import { AssetManagerBase, Downloader } from "@esotericsoftware/spine-core"
import { ThreeJsTexture } from "./ThreeJsTexture"; import { ThreeJsTexture } from "./ThreeJsTexture";
export class AssetManager extends AssetManagerBase { export class AssetManager extends AssetManagerBase {
constructor(pathPrefix: string = "", downloader: Downloader = null) { constructor (pathPrefix: string = "", downloader: Downloader = null) {
super((image: HTMLImageElement) => { super((image: HTMLImageElement) => {
return new ThreeJsTexture(image); return new ThreeJsTexture(image);
}, pathPrefix, downloader); }, pathPrefix, downloader);

View File

@ -38,7 +38,7 @@ export class MeshBatcher extends THREE.Mesh {
private indices: Uint16Array; private indices: Uint16Array;
private indicesLength = 0; private indicesLength = 0;
constructor(maxVertices: number = 10920, materialCustomizer: SkeletonMeshMaterialParametersCustomizer = (parameters) => { }) { constructor (maxVertices: number = 10920, materialCustomizer: SkeletonMeshMaterialParametersCustomizer = (parameters) => { }) {
super(); super();
if (maxVertices > 10920) throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices); if (maxVertices > 10920) throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
let vertices = this.vertices = new Float32Array(maxVertices * MeshBatcher.VERTEX_SIZE); let vertices = this.vertices = new Float32Array(maxVertices * MeshBatcher.VERTEX_SIZE);
@ -57,7 +57,7 @@ export class MeshBatcher extends THREE.Mesh {
this.material = new SkeletonMeshMaterial(materialCustomizer); this.material = new SkeletonMeshMaterial(materialCustomizer);
} }
dispose() { dispose () {
this.geometry.dispose(); this.geometry.dispose();
if (this.material instanceof THREE.Material) if (this.material instanceof THREE.Material)
this.material.dispose(); this.material.dispose();
@ -70,7 +70,7 @@ export class MeshBatcher extends THREE.Mesh {
} }
} }
clear() { clear () {
let geo = (<THREE.BufferGeometry>this.geometry); let geo = (<THREE.BufferGeometry>this.geometry);
geo.drawRange.start = 0; geo.drawRange.start = 0;
geo.drawRange.count = 0; geo.drawRange.count = 0;
@ -78,18 +78,18 @@ export class MeshBatcher extends THREE.Mesh {
return this; return this;
} }
begin() { begin () {
this.verticesLength = 0; this.verticesLength = 0;
this.indicesLength = 0; this.indicesLength = 0;
} }
canBatch(verticesLength: number, indicesLength: number) { canBatch (verticesLength: number, indicesLength: number) {
if (this.indicesLength + indicesLength >= this.indices.byteLength / 2) return false; if (this.indicesLength + indicesLength >= this.indices.byteLength / 2) return false;
if (this.verticesLength + verticesLength >= this.vertices.byteLength / 2) return false; if (this.verticesLength + verticesLength >= this.vertices.byteLength / 2) return false;
return true; return true;
} }
batch(vertices: ArrayLike<number>, verticesLength: number, indices: ArrayLike<number>, indicesLength: number, z: number = 0) { batch (vertices: ArrayLike<number>, verticesLength: number, indices: ArrayLike<number>, indicesLength: number, z: number = 0) {
let indexStart = this.verticesLength / MeshBatcher.VERTEX_SIZE; let indexStart = this.verticesLength / MeshBatcher.VERTEX_SIZE;
let vertexBuffer = this.vertices; let vertexBuffer = this.vertices;
let i = this.verticesLength; let i = this.verticesLength;
@ -113,7 +113,7 @@ export class MeshBatcher extends THREE.Mesh {
this.indicesLength += indicesLength; this.indicesLength += indicesLength;
} }
end() { end () {
this.vertexBuffer.needsUpdate = this.verticesLength > 0; this.vertexBuffer.needsUpdate = this.verticesLength > 0;
this.vertexBuffer.updateRange.offset = 0; this.vertexBuffer.updateRange.offset = 0;
this.vertexBuffer.updateRange.count = this.verticesLength; this.vertexBuffer.updateRange.count = this.verticesLength;

View File

@ -37,7 +37,7 @@ export interface SkeletonMeshMaterialParametersCustomizer {
} }
export class SkeletonMeshMaterial extends THREE.ShaderMaterial { export class SkeletonMeshMaterial extends THREE.ShaderMaterial {
constructor(customizer: SkeletonMeshMaterialParametersCustomizer) { constructor (customizer: SkeletonMeshMaterialParametersCustomizer) {
let vertexShader = ` let vertexShader = `
attribute vec4 color; attribute vec4 color;
varying vec2 vUv; varying vec2 vUv;
@ -93,7 +93,7 @@ export class SkeletonMesh extends THREE.Object3D {
private tempColor = new Color(); private tempColor = new Color();
private materialCustomizer: SkeletonMeshMaterialParametersCustomizer; private materialCustomizer: SkeletonMeshMaterialParametersCustomizer;
constructor(skeletonData: SkeletonData, materialCustomizer: SkeletonMeshMaterialParametersCustomizer = (parameters) => { }) { constructor (skeletonData: SkeletonData, materialCustomizer: SkeletonMeshMaterialParametersCustomizer = (parameters) => { }) {
super(); super();
this.materialCustomizer = materialCustomizer; this.materialCustomizer = materialCustomizer;
this.skeleton = new Skeleton(skeletonData); this.skeleton = new Skeleton(skeletonData);
@ -101,7 +101,7 @@ export class SkeletonMesh extends THREE.Object3D {
this.state = new AnimationState(animData); this.state = new AnimationState(animData);
} }
update(deltaTime: number) { update (deltaTime: number) {
let state = this.state; let state = this.state;
let skeleton = this.skeleton; let skeleton = this.skeleton;
@ -112,13 +112,13 @@ export class SkeletonMesh extends THREE.Object3D {
this.updateGeometry(); this.updateGeometry();
} }
dispose() { dispose () {
for (var i = 0; i < this.batches.length; i++) { for (var i = 0; i < this.batches.length; i++) {
this.batches[i].dispose(); this.batches[i].dispose();
} }
} }
private clearBatches() { private clearBatches () {
for (var i = 0; i < this.batches.length; i++) { for (var i = 0; i < this.batches.length; i++) {
this.batches[i].clear(); this.batches[i].clear();
this.batches[i].visible = false; this.batches[i].visible = false;
@ -126,7 +126,7 @@ export class SkeletonMesh extends THREE.Object3D {
this.nextBatchIndex = 0; this.nextBatchIndex = 0;
} }
private nextBatch() { private nextBatch () {
if (this.batches.length == this.nextBatchIndex) { if (this.batches.length == this.nextBatchIndex) {
let batch = new MeshBatcher(10920, this.materialCustomizer); let batch = new MeshBatcher(10920, this.materialCustomizer);
this.add(batch); this.add(batch);
@ -137,7 +137,7 @@ export class SkeletonMesh extends THREE.Object3D {
return batch; return batch;
} }
private updateGeometry() { private updateGeometry () {
this.clearBatches(); this.clearBatches();
let tempPos = this.tempPos; let tempPos = this.tempPos;

View File

@ -33,28 +33,28 @@ import * as THREE from "three";
export class ThreeJsTexture extends Texture { export class ThreeJsTexture extends Texture {
texture: THREE.Texture; texture: THREE.Texture;
constructor(image: HTMLImageElement) { constructor (image: HTMLImageElement) {
super(image); super(image);
this.texture = new THREE.Texture(image); this.texture = new THREE.Texture(image);
this.texture.flipY = false; this.texture.flipY = false;
this.texture.needsUpdate = true; this.texture.needsUpdate = true;
} }
setFilters(minFilter: TextureFilter, magFilter: TextureFilter) { setFilters (minFilter: TextureFilter, magFilter: TextureFilter) {
this.texture.minFilter = ThreeJsTexture.toThreeJsTextureFilter(minFilter); this.texture.minFilter = ThreeJsTexture.toThreeJsTextureFilter(minFilter);
this.texture.magFilter = ThreeJsTexture.toThreeJsTextureFilter(magFilter); this.texture.magFilter = ThreeJsTexture.toThreeJsTextureFilter(magFilter);
} }
setWraps(uWrap: TextureWrap, vWrap: TextureWrap) { setWraps (uWrap: TextureWrap, vWrap: TextureWrap) {
this.texture.wrapS = ThreeJsTexture.toThreeJsTextureWrap(uWrap); this.texture.wrapS = ThreeJsTexture.toThreeJsTextureWrap(uWrap);
this.texture.wrapT = ThreeJsTexture.toThreeJsTextureWrap(vWrap); this.texture.wrapT = ThreeJsTexture.toThreeJsTextureWrap(vWrap);
} }
dispose() { dispose () {
this.texture.dispose(); this.texture.dispose();
} }
static toThreeJsTextureFilter(filter: TextureFilter) { static toThreeJsTextureFilter (filter: TextureFilter) {
if (filter === TextureFilter.Linear) return THREE.LinearFilter; if (filter === TextureFilter.Linear) return THREE.LinearFilter;
else if (filter === TextureFilter.MipMap) return THREE.LinearMipMapLinearFilter; // also includes TextureFilter.MipMapLinearLinear else if (filter === TextureFilter.MipMap) return THREE.LinearMipMapLinearFilter; // also includes TextureFilter.MipMapLinearLinear
else if (filter === TextureFilter.MipMapLinearNearest) return THREE.LinearMipMapNearestFilter; else if (filter === TextureFilter.MipMapLinearNearest) return THREE.LinearMipMapNearestFilter;
@ -64,7 +64,7 @@ export class ThreeJsTexture extends Texture {
else throw new Error("Unknown texture filter: " + filter); else throw new Error("Unknown texture filter: " + filter);
} }
static toThreeJsTextureWrap(wrap: TextureWrap) { static toThreeJsTextureWrap (wrap: TextureWrap) {
if (wrap === TextureWrap.ClampToEdge) return THREE.ClampToEdgeWrapping; if (wrap === TextureWrap.ClampToEdge) return THREE.ClampToEdgeWrapping;
else if (wrap === TextureWrap.MirroredRepeat) return THREE.MirroredRepeatWrapping; else if (wrap === TextureWrap.MirroredRepeat) return THREE.MirroredRepeatWrapping;
else if (wrap === TextureWrap.Repeat) return THREE.RepeatWrapping; else if (wrap === TextureWrap.Repeat) return THREE.RepeatWrapping;

View File

@ -33,7 +33,7 @@ import { GLTexture } from "./GLTexture";
export class AssetManager extends AssetManagerBase { export class AssetManager extends AssetManagerBase {
constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, pathPrefix: string = "", downloader: Downloader = null) { constructor (context: ManagedWebGLRenderingContext | WebGLRenderingContext, pathPrefix: string = "", downloader: Downloader = null) {
super((image: HTMLImageElement | ImageBitmap) => { super((image: HTMLImageElement | ImageBitmap) => {
return new GLTexture(context, image); return new GLTexture(context, image);
}, pathPrefix, downloader); }, pathPrefix, downloader);

View File

@ -44,13 +44,13 @@ export class OrthoCamera {
projection = new Matrix4(); projection = new Matrix4();
view = new Matrix4(); view = new Matrix4();
constructor(viewportWidth: number, viewportHeight: number) { constructor (viewportWidth: number, viewportHeight: number) {
this.viewportWidth = viewportWidth; this.viewportWidth = viewportWidth;
this.viewportHeight = viewportHeight; this.viewportHeight = viewportHeight;
this.update(); this.update();
} }
update() { update () {
let projection = this.projection; let projection = this.projection;
let view = this.view; let view = this.view;
let projectionView = this.projectionView; let projectionView = this.projectionView;
@ -65,7 +65,7 @@ export class OrthoCamera {
inverseProjectionView.set(projectionView.values).invert(); inverseProjectionView.set(projectionView.values).invert();
} }
screenToWorld(screenCoords: Vector3, screenWidth: number, screenHeight: number) { screenToWorld (screenCoords: Vector3, screenWidth: number, screenHeight: number) {
let x = screenCoords.x, y = screenHeight - screenCoords.y - 1; let x = screenCoords.x, y = screenHeight - screenCoords.y - 1;
screenCoords.x = (2 * x) / screenWidth - 1; screenCoords.x = (2 * x) / screenWidth - 1;
screenCoords.y = (2 * y) / screenHeight - 1; screenCoords.y = (2 * y) / screenHeight - 1;
@ -74,7 +74,7 @@ export class OrthoCamera {
return screenCoords; return screenCoords;
} }
worldToScreen(worldCoords: Vector3, screenWidth: number, screenHeight: number) { worldToScreen (worldCoords: Vector3, screenWidth: number, screenHeight: number) {
worldCoords.project(this.projectionView); worldCoords.project(this.projectionView);
worldCoords.x = screenWidth * (worldCoords.x + 1) / 2; worldCoords.x = screenWidth * (worldCoords.x + 1) / 2;
worldCoords.y = screenHeight * (worldCoords.y + 1) / 2; worldCoords.y = screenHeight * (worldCoords.y + 1) / 2;
@ -82,7 +82,7 @@ export class OrthoCamera {
return worldCoords; return worldCoords;
} }
setViewport(viewportWidth: number, viewportHeight: number) { setViewport (viewportWidth: number, viewportHeight: number) {
this.viewportWidth = viewportWidth; this.viewportWidth = viewportWidth;
this.viewportHeight = viewportHeight; this.viewportHeight = viewportHeight;
} }

View File

@ -38,7 +38,7 @@ export class GLTexture extends Texture implements Disposable, Restorable {
public static DISABLE_UNPACK_PREMULTIPLIED_ALPHA_WEBGL = false; public static DISABLE_UNPACK_PREMULTIPLIED_ALPHA_WEBGL = false;
constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, image: HTMLImageElement | ImageBitmap, useMipMaps: boolean = false) { constructor (context: ManagedWebGLRenderingContext | WebGLRenderingContext, image: HTMLImageElement | ImageBitmap, useMipMaps: boolean = false) {
super(image); super(image);
this.context = context instanceof ManagedWebGLRenderingContext ? context : new ManagedWebGLRenderingContext(context); this.context = context instanceof ManagedWebGLRenderingContext ? context : new ManagedWebGLRenderingContext(context);
this.useMipMaps = useMipMaps; this.useMipMaps = useMipMaps;
@ -46,14 +46,14 @@ export class GLTexture extends Texture implements Disposable, Restorable {
this.context.addRestorable(this); this.context.addRestorable(this);
} }
setFilters(minFilter: TextureFilter, magFilter: TextureFilter) { setFilters (minFilter: TextureFilter, magFilter: TextureFilter) {
let gl = this.context.gl; let gl = this.context.gl;
this.bind(); this.bind();
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, GLTexture.validateMagFilter(magFilter)); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, GLTexture.validateMagFilter(magFilter));
} }
static validateMagFilter(magFilter: TextureFilter) { static validateMagFilter (magFilter: TextureFilter) {
switch (magFilter) { switch (magFilter) {
case TextureFilter.MipMap: case TextureFilter.MipMap:
case TextureFilter.MipMapLinearLinear: case TextureFilter.MipMapLinearLinear:
@ -66,14 +66,14 @@ export class GLTexture extends Texture implements Disposable, Restorable {
} }
} }
setWraps(uWrap: TextureWrap, vWrap: TextureWrap) { setWraps (uWrap: TextureWrap, vWrap: TextureWrap) {
let gl = this.context.gl; let gl = this.context.gl;
this.bind(); this.bind();
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, uWrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, uWrap);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, vWrap); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, vWrap);
} }
update(useMipMaps: boolean) { update (useMipMaps: boolean) {
let gl = this.context.gl; let gl = this.context.gl;
if (!this.texture) this.texture = this.context.gl.createTexture(); if (!this.texture) this.texture = this.context.gl.createTexture();
this.bind(); this.bind();
@ -86,25 +86,25 @@ export class GLTexture extends Texture implements Disposable, Restorable {
if (useMipMaps) gl.generateMipmap(gl.TEXTURE_2D); if (useMipMaps) gl.generateMipmap(gl.TEXTURE_2D);
} }
restore() { restore () {
this.texture = null; this.texture = null;
this.update(this.useMipMaps); this.update(this.useMipMaps);
} }
bind(unit: number = 0) { bind (unit: number = 0) {
let gl = this.context.gl; let gl = this.context.gl;
this.boundUnit = unit; this.boundUnit = unit;
gl.activeTexture(gl.TEXTURE0 + unit); gl.activeTexture(gl.TEXTURE0 + unit);
gl.bindTexture(gl.TEXTURE_2D, this.texture); gl.bindTexture(gl.TEXTURE_2D, this.texture);
} }
unbind() { unbind () {
let gl = this.context.gl; let gl = this.context.gl;
gl.activeTexture(gl.TEXTURE0 + this.boundUnit); gl.activeTexture(gl.TEXTURE0 + this.boundUnit);
gl.bindTexture(gl.TEXTURE_2D, null); gl.bindTexture(gl.TEXTURE_2D, null);
} }
dispose() { dispose () {
this.context.removeRestorable(this); this.context.removeRestorable(this);
let gl = this.context.gl; let gl = this.context.gl;
gl.deleteTexture(this.texture); gl.deleteTexture(this.texture);

View File

@ -41,12 +41,12 @@ export class Input {
return new Touch(0, 0, 0); return new Touch(0, 0, 0);
}); });
constructor(element: HTMLElement) { constructor (element: HTMLElement) {
this.element = element; this.element = element;
this.setupCallbacks(element); this.setupCallbacks(element);
} }
private setupCallbacks(element: HTMLElement) { private setupCallbacks (element: HTMLElement) {
let mouseDown = (ev: UIEvent) => { let mouseDown = (ev: UIEvent) => {
if (ev instanceof MouseEvent) { if (ev instanceof MouseEvent) {
let rect = element.getBoundingClientRect(); let rect = element.getBoundingClientRect();
@ -208,11 +208,11 @@ export class Input {
}, false); }, false);
} }
addListener(listener: InputListener) { addListener (listener: InputListener) {
this.listeners.push(listener); this.listeners.push(listener);
} }
removeListener(listener: InputListener) { removeListener (listener: InputListener) {
let idx = this.listeners.indexOf(listener); let idx = this.listeners.indexOf(listener);
if (idx > -1) { if (idx > -1) {
this.listeners.splice(idx, 1); this.listeners.splice(idx, 1);
@ -221,13 +221,13 @@ export class Input {
} }
export class Touch { export class Touch {
constructor(public identifier: number, public x: number, public y: number) { constructor (public identifier: number, public x: number, public y: number) {
} }
} }
export interface InputListener { export interface InputListener {
down(x: number, y: number): void; down (x: number, y: number): void;
up(x: number, y: number): void; up (x: number, y: number): void;
moved(x: number, y: number): void; moved (x: number, y: number): void;
dragged(x: number, y: number): void; dragged (x: number, y: number): void;
} }

View File

@ -49,7 +49,7 @@ export class LoadingScreen {
backgroundColor = new Color(0.135, 0.135, 0.135, 1); backgroundColor = new Color(0.135, 0.135, 0.135, 1);
private tempColor = new Color(); private tempColor = new Color();
constructor(renderer: SceneRenderer) { constructor (renderer: SceneRenderer) {
this.renderer = renderer; this.renderer = renderer;
this.timeKeeper.maxDelta = 9; this.timeKeeper.maxDelta = 9;
@ -70,7 +70,7 @@ export class LoadingScreen {
} }
} }
draw(complete = false) { draw (complete = false) {
if (loaded < 2 || (complete && this.fadeOut > FADE_OUT)) return; if (loaded < 2 || (complete && this.fadeOut > FADE_OUT)) return;
this.timeKeeper.update(); this.timeKeeper.update();

View File

@ -55,7 +55,7 @@ export class Matrix4 {
private static zAxis: Vector3 = null; private static zAxis: Vector3 = null;
private static tmpMatrix = new Matrix4(); private static tmpMatrix = new Matrix4();
constructor() { constructor () {
let v = this.values; let v = this.values;
v[M00] = 1; v[M00] = 1;
v[M11] = 1; v[M11] = 1;
@ -63,12 +63,12 @@ export class Matrix4 {
v[M33] = 1; v[M33] = 1;
} }
set(values: ArrayLike<number>): Matrix4 { set (values: ArrayLike<number>): Matrix4 {
this.values.set(values); this.values.set(values);
return this; return this;
} }
transpose(): Matrix4 { transpose (): Matrix4 {
let t = this.temp; let t = this.temp;
let v = this.values; let v = this.values;
t[M00] = v[M00]; t[M00] = v[M00];
@ -90,7 +90,7 @@ export class Matrix4 {
return this.set(t); return this.set(t);
} }
identity(): Matrix4 { identity (): Matrix4 {
let v = this.values; let v = this.values;
v[M00] = 1; v[M00] = 1;
v[M01] = 0; v[M01] = 0;
@ -111,7 +111,7 @@ export class Matrix4 {
return this; return this;
} }
invert(): Matrix4 { invert (): Matrix4 {
let v = this.values; let v = this.values;
let t = this.temp; let t = this.temp;
let l_det = v[M30] * v[M21] * v[M12] * v[M03] - v[M20] * v[M31] * v[M12] * v[M03] - v[M30] * v[M11] * v[M22] * v[M03] let l_det = v[M30] * v[M21] * v[M12] * v[M03] - v[M20] * v[M31] * v[M12] * v[M03] - v[M30] * v[M11] * v[M22] * v[M03]
@ -175,7 +175,7 @@ export class Matrix4 {
return this; return this;
} }
determinant(): number { determinant (): number {
let v = this.values; let v = this.values;
return v[M30] * v[M21] * v[M12] * v[M03] - v[M20] * v[M31] * v[M12] * v[M03] - v[M30] * v[M11] * v[M22] * v[M03] return v[M30] * v[M21] * v[M12] * v[M03] - v[M20] * v[M31] * v[M12] * v[M03] - v[M30] * v[M11] * v[M22] * v[M03]
+ v[M10] * v[M31] * v[M22] * v[M03] + v[M20] * v[M11] * v[M32] * v[M03] - v[M10] * v[M21] * v[M32] * v[M03] + v[M10] * v[M31] * v[M22] * v[M03] + v[M20] * v[M11] * v[M32] * v[M03] - v[M10] * v[M21] * v[M32] * v[M03]
@ -187,7 +187,7 @@ export class Matrix4 {
- v[M00] * v[M21] * v[M12] * v[M33] - v[M10] * v[M01] * v[M22] * v[M33] + v[M00] * v[M11] * v[M22] * v[M33]; - v[M00] * v[M21] * v[M12] * v[M33] - v[M10] * v[M01] * v[M22] * v[M33] + v[M00] * v[M11] * v[M22] * v[M33];
} }
translate(x: number, y: number, z: number): Matrix4 { translate (x: number, y: number, z: number): Matrix4 {
let v = this.values; let v = this.values;
v[M03] += x; v[M03] += x;
v[M13] += y; v[M13] += y;
@ -195,11 +195,11 @@ export class Matrix4 {
return this; return this;
} }
copy(): Matrix4 { copy (): Matrix4 {
return new Matrix4().set(this.values); return new Matrix4().set(this.values);
} }
projection(near: number, far: number, fovy: number, aspectRatio: number): Matrix4 { projection (near: number, far: number, fovy: number, aspectRatio: number): Matrix4 {
this.identity(); this.identity();
let l_fd = (1.0 / Math.tan((fovy * (Math.PI / 180)) / 2.0)); let l_fd = (1.0 / Math.tan((fovy * (Math.PI / 180)) / 2.0));
let l_a1 = (far + near) / (near - far); let l_a1 = (far + near) / (near - far);
@ -224,11 +224,11 @@ export class Matrix4 {
return this; return this;
} }
ortho2d(x: number, y: number, width: number, height: number): Matrix4 { ortho2d (x: number, y: number, width: number, height: number): Matrix4 {
return this.ortho(x, x + width, y, y + height, 0, 1); return this.ortho(x, x + width, y, y + height, 0, 1);
} }
ortho(left: number, right: number, bottom: number, top: number, near: number, far: number): Matrix4 { ortho (left: number, right: number, bottom: number, top: number, near: number, far: number): Matrix4 {
this.identity(); this.identity();
let x_orth = 2 / (right - left); let x_orth = 2 / (right - left);
let y_orth = 2 / (top - bottom); let y_orth = 2 / (top - bottom);
@ -258,7 +258,7 @@ export class Matrix4 {
return this; return this;
} }
multiply(matrix: Matrix4): Matrix4 { multiply (matrix: Matrix4): Matrix4 {
let t = this.temp; let t = this.temp;
let v = this.values; let v = this.values;
let m = matrix.values; let m = matrix.values;
@ -281,7 +281,7 @@ export class Matrix4 {
return this.set(this.temp); return this.set(this.temp);
} }
multiplyLeft(matrix: Matrix4): Matrix4 { multiplyLeft (matrix: Matrix4): Matrix4 {
let t = this.temp; let t = this.temp;
let v = this.values; let v = this.values;
let m = matrix.values; let m = matrix.values;
@ -304,7 +304,7 @@ export class Matrix4 {
return this.set(this.temp); return this.set(this.temp);
} }
lookAt(position: Vector3, direction: Vector3, up: Vector3) { lookAt (position: Vector3, direction: Vector3, up: Vector3) {
Matrix4.initTemps(); Matrix4.initTemps();
let xAxis = Matrix4.xAxis, yAxis = Matrix4.yAxis, zAxis = Matrix4.zAxis; let xAxis = Matrix4.xAxis, yAxis = Matrix4.yAxis, zAxis = Matrix4.zAxis;
zAxis.setFrom(direction).normalize(); zAxis.setFrom(direction).normalize();
@ -332,7 +332,7 @@ export class Matrix4 {
return this; return this;
} }
static initTemps() { static initTemps () {
if (Matrix4.xAxis === null) Matrix4.xAxis = new Vector3(); if (Matrix4.xAxis === null) Matrix4.xAxis = new Vector3();
if (Matrix4.yAxis === null) Matrix4.yAxis = new Vector3(); if (Matrix4.yAxis === null) Matrix4.yAxis = new Vector3();
if (Matrix4.zAxis === null) Matrix4.zAxis = new Vector3(); if (Matrix4.zAxis === null) Matrix4.zAxis = new Vector3();

View File

@ -44,25 +44,25 @@ export class Mesh implements Disposable, Restorable {
private dirtyIndices = false; private dirtyIndices = false;
private elementsPerVertex = 0; private elementsPerVertex = 0;
getAttributes(): VertexAttribute[] { return this.attributes; } getAttributes (): VertexAttribute[] { return this.attributes; }
maxVertices(): number { return this.vertices.length / this.elementsPerVertex; } maxVertices (): number { return this.vertices.length / this.elementsPerVertex; }
numVertices(): number { return this.verticesLength / this.elementsPerVertex; } numVertices (): number { return this.verticesLength / this.elementsPerVertex; }
setVerticesLength(length: number) { setVerticesLength (length: number) {
this.dirtyVertices = true; this.dirtyVertices = true;
this.verticesLength = length; this.verticesLength = length;
} }
getVertices(): Float32Array { return this.vertices; } getVertices (): Float32Array { return this.vertices; }
maxIndices(): number { return this.indices.length; } maxIndices (): number { return this.indices.length; }
numIndices(): number { return this.indicesLength; } numIndices (): number { return this.indicesLength; }
setIndicesLength(length: number) { setIndicesLength (length: number) {
this.dirtyIndices = true; this.dirtyIndices = true;
this.indicesLength = length; this.indicesLength = length;
} }
getIndices(): Uint16Array { return this.indices }; getIndices (): Uint16Array { return this.indices };
getVertexSizeInFloats(): number { getVertexSizeInFloats (): number {
let size = 0; let size = 0;
for (var i = 0; i < this.attributes.length; i++) { for (var i = 0; i < this.attributes.length; i++) {
let attribute = this.attributes[i]; let attribute = this.attributes[i];
@ -71,7 +71,7 @@ export class Mesh implements Disposable, Restorable {
return size; return size;
} }
constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, private attributes: VertexAttribute[], maxVertices: number, maxIndices: number) { constructor (context: ManagedWebGLRenderingContext | WebGLRenderingContext, private attributes: VertexAttribute[], maxVertices: number, maxIndices: number) {
this.context = context instanceof ManagedWebGLRenderingContext ? context : new ManagedWebGLRenderingContext(context); this.context = context instanceof ManagedWebGLRenderingContext ? context : new ManagedWebGLRenderingContext(context);
this.elementsPerVertex = 0; this.elementsPerVertex = 0;
for (let i = 0; i < attributes.length; i++) { for (let i = 0; i < attributes.length; i++) {
@ -82,25 +82,25 @@ export class Mesh implements Disposable, Restorable {
this.context.addRestorable(this); this.context.addRestorable(this);
} }
setVertices(vertices: Array<number>) { setVertices (vertices: Array<number>) {
this.dirtyVertices = true; this.dirtyVertices = true;
if (vertices.length > this.vertices.length) throw Error("Mesh can't store more than " + this.maxVertices() + " vertices"); if (vertices.length > this.vertices.length) throw Error("Mesh can't store more than " + this.maxVertices() + " vertices");
this.vertices.set(vertices, 0); this.vertices.set(vertices, 0);
this.verticesLength = vertices.length; this.verticesLength = vertices.length;
} }
setIndices(indices: Array<number>) { setIndices (indices: Array<number>) {
this.dirtyIndices = true; this.dirtyIndices = true;
if (indices.length > this.indices.length) throw Error("Mesh can't store more than " + this.maxIndices() + " indices"); if (indices.length > this.indices.length) throw Error("Mesh can't store more than " + this.maxIndices() + " indices");
this.indices.set(indices, 0); this.indices.set(indices, 0);
this.indicesLength = indices.length; this.indicesLength = indices.length;
} }
draw(shader: Shader, primitiveType: number) { draw (shader: Shader, primitiveType: number) {
this.drawWithOffset(shader, primitiveType, 0, this.indicesLength > 0 ? this.indicesLength : this.verticesLength / this.elementsPerVertex); this.drawWithOffset(shader, primitiveType, 0, this.indicesLength > 0 ? this.indicesLength : this.verticesLength / this.elementsPerVertex);
} }
drawWithOffset(shader: Shader, primitiveType: number, offset: number, count: number) { drawWithOffset (shader: Shader, primitiveType: number, offset: number, count: number) {
let gl = this.context.gl; let gl = this.context.gl;
if (this.dirtyVertices || this.dirtyIndices) this.update(); if (this.dirtyVertices || this.dirtyIndices) this.update();
this.bind(shader); this.bind(shader);
@ -112,7 +112,7 @@ export class Mesh implements Disposable, Restorable {
this.unbind(shader); this.unbind(shader);
} }
bind(shader: Shader) { bind (shader: Shader) {
let gl = this.context.gl; let gl = this.context.gl;
gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer); gl.bindBuffer(gl.ARRAY_BUFFER, this.verticesBuffer);
let offset = 0; let offset = 0;
@ -126,7 +126,7 @@ export class Mesh implements Disposable, Restorable {
if (this.indicesLength > 0) gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indicesBuffer); if (this.indicesLength > 0) gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
} }
unbind(shader: Shader) { unbind (shader: Shader) {
let gl = this.context.gl; let gl = this.context.gl;
for (let i = 0; i < this.attributes.length; i++) { for (let i = 0; i < this.attributes.length; i++) {
let attrib = this.attributes[i]; let attrib = this.attributes[i];
@ -137,7 +137,7 @@ export class Mesh implements Disposable, Restorable {
if (this.indicesLength > 0) gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); if (this.indicesLength > 0) gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
} }
private update() { private update () {
let gl = this.context.gl; let gl = this.context.gl;
if (this.dirtyVertices) { if (this.dirtyVertices) {
if (!this.verticesBuffer) { if (!this.verticesBuffer) {
@ -158,13 +158,13 @@ export class Mesh implements Disposable, Restorable {
} }
} }
restore() { restore () {
this.verticesBuffer = null; this.verticesBuffer = null;
this.indicesBuffer = null; this.indicesBuffer = null;
this.update(); this.update();
} }
dispose() { dispose () {
this.context.removeRestorable(this); this.context.removeRestorable(this);
let gl = this.context.gl; let gl = this.context.gl;
gl.deleteBuffer(this.verticesBuffer); gl.deleteBuffer(this.verticesBuffer);
@ -173,35 +173,35 @@ export class Mesh implements Disposable, Restorable {
} }
export class VertexAttribute { export class VertexAttribute {
constructor(public name: string, public type: VertexAttributeType, public numElements: number) { } constructor (public name: string, public type: VertexAttributeType, public numElements: number) { }
} }
export class Position2Attribute extends VertexAttribute { export class Position2Attribute extends VertexAttribute {
constructor() { constructor () {
super(Shader.POSITION, VertexAttributeType.Float, 2); super(Shader.POSITION, VertexAttributeType.Float, 2);
} }
} }
export class Position3Attribute extends VertexAttribute { export class Position3Attribute extends VertexAttribute {
constructor() { constructor () {
super(Shader.POSITION, VertexAttributeType.Float, 3); super(Shader.POSITION, VertexAttributeType.Float, 3);
} }
} }
export class TexCoordAttribute extends VertexAttribute { export class TexCoordAttribute extends VertexAttribute {
constructor(unit: number = 0) { constructor (unit: number = 0) {
super(Shader.TEXCOORDS + (unit == 0 ? "" : unit), VertexAttributeType.Float, 2); super(Shader.TEXCOORDS + (unit == 0 ? "" : unit), VertexAttributeType.Float, 2);
} }
} }
export class ColorAttribute extends VertexAttribute { export class ColorAttribute extends VertexAttribute {
constructor() { constructor () {
super(Shader.COLOR, VertexAttributeType.Float, 4); super(Shader.COLOR, VertexAttributeType.Float, 4);
} }
} }
export class Color2Attribute extends VertexAttribute { export class Color2Attribute extends VertexAttribute {
constructor() { constructor () {
super(Shader.COLOR2, VertexAttributeType.Float, 4); super(Shader.COLOR2, VertexAttributeType.Float, 4);
} }
} }

View File

@ -46,7 +46,7 @@ export class PolygonBatcher implements Disposable {
private srcAlphaBlend: number; private srcAlphaBlend: number;
private dstBlend: number; private dstBlend: number;
constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, twoColorTint: boolean = true, maxVertices: number = 10920) { constructor (context: ManagedWebGLRenderingContext | WebGLRenderingContext, twoColorTint: boolean = true, maxVertices: number = 10920) {
if (maxVertices > 10920) throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices); if (maxVertices > 10920) throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
this.context = context instanceof ManagedWebGLRenderingContext ? context : new ManagedWebGLRenderingContext(context); this.context = context instanceof ManagedWebGLRenderingContext ? context : new ManagedWebGLRenderingContext(context);
let attributes = twoColorTint ? let attributes = twoColorTint ?
@ -59,7 +59,7 @@ export class PolygonBatcher implements Disposable {
this.dstBlend = gl.ONE_MINUS_SRC_ALPHA; this.dstBlend = gl.ONE_MINUS_SRC_ALPHA;
} }
begin(shader: Shader) { begin (shader: Shader) {
if (this.isDrawing) throw new Error("PolygonBatch is already drawing. Call PolygonBatch.end() before calling PolygonBatch.begin()"); if (this.isDrawing) throw new Error("PolygonBatch is already drawing. Call PolygonBatch.end() before calling PolygonBatch.begin()");
this.drawCalls = 0; this.drawCalls = 0;
this.shader = shader; this.shader = shader;
@ -71,7 +71,7 @@ export class PolygonBatcher implements Disposable {
gl.blendFuncSeparate(this.srcColorBlend, this.dstBlend, this.srcAlphaBlend, this.dstBlend); gl.blendFuncSeparate(this.srcColorBlend, this.dstBlend, this.srcAlphaBlend, this.dstBlend);
} }
setBlendMode(srcColorBlend: number, srcAlphaBlend: number, dstBlend: number) { setBlendMode (srcColorBlend: number, srcAlphaBlend: number, dstBlend: number) {
this.srcColorBlend = srcColorBlend; this.srcColorBlend = srcColorBlend;
this.srcAlphaBlend = srcAlphaBlend; this.srcAlphaBlend = srcAlphaBlend;
this.dstBlend = dstBlend; this.dstBlend = dstBlend;
@ -82,7 +82,7 @@ export class PolygonBatcher implements Disposable {
} }
} }
draw(texture: GLTexture, vertices: ArrayLike<number>, indices: Array<number>) { draw (texture: GLTexture, vertices: ArrayLike<number>, indices: Array<number>) {
if (texture != this.lastTexture) { if (texture != this.lastTexture) {
this.flush(); this.flush();
this.lastTexture = texture; this.lastTexture = texture;
@ -103,7 +103,7 @@ export class PolygonBatcher implements Disposable {
this.mesh.setIndicesLength(this.indicesLength); this.mesh.setIndicesLength(this.indicesLength);
} }
flush() { flush () {
if (this.verticesLength == 0) return; if (this.verticesLength == 0) return;
this.lastTexture.bind(); this.lastTexture.bind();
@ -116,7 +116,7 @@ export class PolygonBatcher implements Disposable {
this.drawCalls++; this.drawCalls++;
} }
end() { end () {
if (!this.isDrawing) throw new Error("PolygonBatch is not drawing. Call PolygonBatch.begin() before calling PolygonBatch.end()"); if (!this.isDrawing) throw new Error("PolygonBatch is not drawing. Call PolygonBatch.begin() before calling PolygonBatch.end()");
if (this.verticesLength > 0 || this.indicesLength > 0) this.flush(); if (this.verticesLength > 0 || this.indicesLength > 0) this.flush();
this.shader = null; this.shader = null;
@ -127,11 +127,11 @@ export class PolygonBatcher implements Disposable {
gl.disable(gl.BLEND); gl.disable(gl.BLEND);
} }
getDrawCalls() { getDrawCalls () {
return this.drawCalls; return this.drawCalls;
} }
dispose() { dispose () {
this.mesh.dispose(); this.mesh.dispose();
} }
} }

View File

@ -60,7 +60,7 @@ export class SceneRenderer implements Disposable {
skeletonRenderer: SkeletonRenderer; skeletonRenderer: SkeletonRenderer;
skeletonDebugRenderer: SkeletonDebugRenderer; skeletonDebugRenderer: SkeletonDebugRenderer;
constructor(canvas: HTMLCanvasElement, context: ManagedWebGLRenderingContext | WebGLRenderingContext, twoColorTint: boolean = true) { constructor (canvas: HTMLCanvasElement, context: ManagedWebGLRenderingContext | WebGLRenderingContext, twoColorTint: boolean = true) {
this.canvas = canvas; this.canvas = canvas;
this.context = context instanceof ManagedWebGLRenderingContext ? context : new ManagedWebGLRenderingContext(context); this.context = context instanceof ManagedWebGLRenderingContext ? context : new ManagedWebGLRenderingContext(context);
this.twoColorTint = twoColorTint; this.twoColorTint = twoColorTint;
@ -73,24 +73,24 @@ export class SceneRenderer implements Disposable {
this.skeletonDebugRenderer = new SkeletonDebugRenderer(this.context); this.skeletonDebugRenderer = new SkeletonDebugRenderer(this.context);
} }
begin() { begin () {
this.camera.update(); this.camera.update();
this.enableRenderer(this.batcher); this.enableRenderer(this.batcher);
} }
drawSkeleton(skeleton: Skeleton, premultipliedAlpha = false, slotRangeStart = -1, slotRangeEnd = -1) { drawSkeleton (skeleton: Skeleton, premultipliedAlpha = false, slotRangeStart = -1, slotRangeEnd = -1) {
this.enableRenderer(this.batcher); this.enableRenderer(this.batcher);
this.skeletonRenderer.premultipliedAlpha = premultipliedAlpha; this.skeletonRenderer.premultipliedAlpha = premultipliedAlpha;
this.skeletonRenderer.draw(this.batcher, skeleton, slotRangeStart, slotRangeEnd); this.skeletonRenderer.draw(this.batcher, skeleton, slotRangeStart, slotRangeEnd);
} }
drawSkeletonDebug(skeleton: Skeleton, premultipliedAlpha = false, ignoredBones: Array<string> = null) { drawSkeletonDebug (skeleton: Skeleton, premultipliedAlpha = false, ignoredBones: Array<string> = null) {
this.enableRenderer(this.shapes); this.enableRenderer(this.shapes);
this.skeletonDebugRenderer.premultipliedAlpha = premultipliedAlpha; this.skeletonDebugRenderer.premultipliedAlpha = premultipliedAlpha;
this.skeletonDebugRenderer.draw(this.shapes, skeleton, ignoredBones); this.skeletonDebugRenderer.draw(this.shapes, skeleton, ignoredBones);
} }
drawTexture(texture: GLTexture, x: number, y: number, width: number, height: number, color: Color = null) { drawTexture (texture: GLTexture, x: number, y: number, width: number, height: number, color: Color = null) {
this.enableRenderer(this.batcher); this.enableRenderer(this.batcher);
if (color === null) color = WHITE; if (color === null) color = WHITE;
var i = 0; var i = 0;
@ -153,7 +153,7 @@ export class SceneRenderer implements Disposable {
this.batcher.draw(texture, quad, QUAD_TRIANGLES); this.batcher.draw(texture, quad, QUAD_TRIANGLES);
} }
drawTextureUV(texture: GLTexture, x: number, y: number, width: number, height: number, u: number, v: number, u2: number, v2: number, color: Color = null) { drawTextureUV (texture: GLTexture, x: number, y: number, width: number, height: number, u: number, v: number, u2: number, v2: number, color: Color = null) {
this.enableRenderer(this.batcher); this.enableRenderer(this.batcher);
if (color === null) color = WHITE; if (color === null) color = WHITE;
var i = 0; var i = 0;
@ -216,7 +216,7 @@ export class SceneRenderer implements Disposable {
this.batcher.draw(texture, quad, QUAD_TRIANGLES); this.batcher.draw(texture, quad, QUAD_TRIANGLES);
} }
drawTextureRotated(texture: GLTexture, x: number, y: number, width: number, height: number, pivotX: number, pivotY: number, angle: number, color: Color = null) { drawTextureRotated (texture: GLTexture, x: number, y: number, width: number, height: number, pivotX: number, pivotY: number, angle: number, color: Color = null) {
this.enableRenderer(this.batcher); this.enableRenderer(this.batcher);
if (color === null) color = WHITE; if (color === null) color = WHITE;
@ -346,7 +346,7 @@ export class SceneRenderer implements Disposable {
this.batcher.draw(texture, quad, QUAD_TRIANGLES); this.batcher.draw(texture, quad, QUAD_TRIANGLES);
} }
drawRegion(region: TextureAtlasRegion, x: number, y: number, width: number, height: number, color: Color = null) { drawRegion (region: TextureAtlasRegion, x: number, y: number, width: number, height: number, color: Color = null) {
this.enableRenderer(this.batcher); this.enableRenderer(this.batcher);
if (color === null) color = WHITE; if (color === null) color = WHITE;
var i = 0; var i = 0;
@ -409,53 +409,53 @@ export class SceneRenderer implements Disposable {
this.batcher.draw(<GLTexture>region.page.texture, quad, QUAD_TRIANGLES); this.batcher.draw(<GLTexture>region.page.texture, quad, QUAD_TRIANGLES);
} }
line(x: number, y: number, x2: number, y2: number, color: Color = null, color2: Color = null) { line (x: number, y: number, x2: number, y2: number, color: Color = null, color2: Color = null) {
this.enableRenderer(this.shapes); this.enableRenderer(this.shapes);
this.shapes.line(x, y, x2, y2, color); this.shapes.line(x, y, x2, y2, color);
} }
triangle(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, color: Color = null, color2: Color = null, color3: Color = null) { triangle (filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, color: Color = null, color2: Color = null, color3: Color = null) {
this.enableRenderer(this.shapes); this.enableRenderer(this.shapes);
this.shapes.triangle(filled, x, y, x2, y2, x3, y3, color, color2, color3); this.shapes.triangle(filled, x, y, x2, y2, x3, y3, color, color2, color3);
} }
quad(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number, color: Color = null, color2: Color = null, color3: Color = null, color4: Color = null) { quad (filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number, color: Color = null, color2: Color = null, color3: Color = null, color4: Color = null) {
this.enableRenderer(this.shapes); this.enableRenderer(this.shapes);
this.shapes.quad(filled, x, y, x2, y2, x3, y3, x4, y4, color, color2, color3, color4); this.shapes.quad(filled, x, y, x2, y2, x3, y3, x4, y4, color, color2, color3, color4);
} }
rect(filled: boolean, x: number, y: number, width: number, height: number, color: Color = null) { rect (filled: boolean, x: number, y: number, width: number, height: number, color: Color = null) {
this.enableRenderer(this.shapes); this.enableRenderer(this.shapes);
this.shapes.rect(filled, x, y, width, height, color); this.shapes.rect(filled, x, y, width, height, color);
} }
rectLine(filled: boolean, x1: number, y1: number, x2: number, y2: number, width: number, color: Color = null) { rectLine (filled: boolean, x1: number, y1: number, x2: number, y2: number, width: number, color: Color = null) {
this.enableRenderer(this.shapes); this.enableRenderer(this.shapes);
this.shapes.rectLine(filled, x1, y1, x2, y2, width, color); this.shapes.rectLine(filled, x1, y1, x2, y2, width, color);
} }
polygon(polygonVertices: ArrayLike<number>, offset: number, count: number, color: Color = null) { polygon (polygonVertices: ArrayLike<number>, offset: number, count: number, color: Color = null) {
this.enableRenderer(this.shapes); this.enableRenderer(this.shapes);
this.shapes.polygon(polygonVertices, offset, count, color); this.shapes.polygon(polygonVertices, offset, count, color);
} }
circle(filled: boolean, x: number, y: number, radius: number, color: Color = null, segments: number = 0) { circle (filled: boolean, x: number, y: number, radius: number, color: Color = null, segments: number = 0) {
this.enableRenderer(this.shapes); this.enableRenderer(this.shapes);
this.shapes.circle(filled, x, y, radius, color, segments); this.shapes.circle(filled, x, y, radius, color, segments);
} }
curve(x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color: Color = null) { curve (x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color: Color = null) {
this.enableRenderer(this.shapes); this.enableRenderer(this.shapes);
this.shapes.curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2, segments, color); this.shapes.curve(x1, y1, cx1, cy1, cx2, cy2, x2, y2, segments, color);
} }
end() { end () {
if (this.activeRenderer === this.batcher) this.batcher.end(); if (this.activeRenderer === this.batcher) this.batcher.end();
else if (this.activeRenderer === this.shapes) this.shapes.end(); else if (this.activeRenderer === this.shapes) this.shapes.end();
this.activeRenderer = null; this.activeRenderer = null;
} }
resize(resizeMode: ResizeMode) { resize (resizeMode: ResizeMode) {
let canvas = this.canvas; let canvas = this.canvas;
var dpr = window.devicePixelRatio || 1; var dpr = window.devicePixelRatio || 1;
var w = Math.round(canvas.clientWidth * dpr); var w = Math.round(canvas.clientWidth * dpr);
@ -481,7 +481,7 @@ export class SceneRenderer implements Disposable {
this.camera.update(); this.camera.update();
} }
private enableRenderer(renderer: PolygonBatcher | ShapeRenderer | SkeletonDebugRenderer) { private enableRenderer (renderer: PolygonBatcher | ShapeRenderer | SkeletonDebugRenderer) {
if (this.activeRenderer === renderer) return; if (this.activeRenderer === renderer) return;
this.end(); this.end();
if (renderer instanceof PolygonBatcher) { if (renderer instanceof PolygonBatcher) {
@ -499,7 +499,7 @@ export class SceneRenderer implements Disposable {
this.activeRenderer = this.skeletonDebugRenderer; this.activeRenderer = this.skeletonDebugRenderer;
} }
dispose() { dispose () {
this.batcher.dispose(); this.batcher.dispose();
this.batcherShader.dispose(); this.batcherShader.dispose();
this.shapes.dispose(); this.shapes.dispose();

View File

@ -48,13 +48,13 @@ export class Shader implements Disposable, Restorable {
private tmp3x3: Float32Array = new Float32Array(3 * 3); private tmp3x3: Float32Array = new Float32Array(3 * 3);
private tmp4x4: Float32Array = new Float32Array(4 * 4); private tmp4x4: Float32Array = new Float32Array(4 * 4);
public getProgram() { return this.program; } public getProgram () { return this.program; }
public getVertexShader() { return this.vertexShader; } public getVertexShader () { return this.vertexShader; }
public getFragmentShader() { return this.fragmentShader; } public getFragmentShader () { return this.fragmentShader; }
public getVertexShaderSource() { return this.vsSource; } public getVertexShaderSource () { return this.vsSource; }
public getFragmentSource() { return this.fsSource; } public getFragmentSource () { return this.fsSource; }
constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, private vertexShader: string, private fragmentShader: string) { constructor (context: ManagedWebGLRenderingContext | WebGLRenderingContext, private vertexShader: string, private fragmentShader: string) {
this.vsSource = vertexShader; this.vsSource = vertexShader;
this.fsSource = fragmentShader; this.fsSource = fragmentShader;
this.context = context instanceof ManagedWebGLRenderingContext ? context : new ManagedWebGLRenderingContext(context); this.context = context instanceof ManagedWebGLRenderingContext ? context : new ManagedWebGLRenderingContext(context);
@ -62,7 +62,7 @@ export class Shader implements Disposable, Restorable {
this.compile(); this.compile();
} }
private compile() { private compile () {
let gl = this.context.gl; let gl = this.context.gl;
try { try {
this.vs = this.compileShader(gl.VERTEX_SHADER, this.vertexShader); this.vs = this.compileShader(gl.VERTEX_SHADER, this.vertexShader);
@ -74,7 +74,7 @@ export class Shader implements Disposable, Restorable {
} }
} }
private compileShader(type: number, source: string) { private compileShader (type: number, source: string) {
let gl = this.context.gl; let gl = this.context.gl;
let shader = gl.createShader(type); let shader = gl.createShader(type);
gl.shaderSource(shader, source); gl.shaderSource(shader, source);
@ -87,7 +87,7 @@ export class Shader implements Disposable, Restorable {
return shader; return shader;
} }
private compileProgram(vs: WebGLShader, fs: WebGLShader) { private compileProgram (vs: WebGLShader, fs: WebGLShader) {
let gl = this.context.gl; let gl = this.context.gl;
let program = gl.createProgram(); let program = gl.createProgram();
gl.attachShader(program, vs); gl.attachShader(program, vs);
@ -102,71 +102,71 @@ export class Shader implements Disposable, Restorable {
return program; return program;
} }
restore() { restore () {
this.compile(); this.compile();
} }
public bind() { public bind () {
this.context.gl.useProgram(this.program); this.context.gl.useProgram(this.program);
} }
public unbind() { public unbind () {
this.context.gl.useProgram(null); this.context.gl.useProgram(null);
} }
public setUniformi(uniform: string, value: number) { public setUniformi (uniform: string, value: number) {
this.context.gl.uniform1i(this.getUniformLocation(uniform), value); this.context.gl.uniform1i(this.getUniformLocation(uniform), value);
} }
public setUniformf(uniform: string, value: number) { public setUniformf (uniform: string, value: number) {
this.context.gl.uniform1f(this.getUniformLocation(uniform), value); this.context.gl.uniform1f(this.getUniformLocation(uniform), value);
} }
public setUniform2f(uniform: string, value: number, value2: number) { public setUniform2f (uniform: string, value: number, value2: number) {
this.context.gl.uniform2f(this.getUniformLocation(uniform), value, value2); this.context.gl.uniform2f(this.getUniformLocation(uniform), value, value2);
} }
public setUniform3f(uniform: string, value: number, value2: number, value3: number) { public setUniform3f (uniform: string, value: number, value2: number, value3: number) {
this.context.gl.uniform3f(this.getUniformLocation(uniform), value, value2, value3); this.context.gl.uniform3f(this.getUniformLocation(uniform), value, value2, value3);
} }
public setUniform4f(uniform: string, value: number, value2: number, value3: number, value4: number) { public setUniform4f (uniform: string, value: number, value2: number, value3: number, value4: number) {
this.context.gl.uniform4f(this.getUniformLocation(uniform), value, value2, value3, value4); this.context.gl.uniform4f(this.getUniformLocation(uniform), value, value2, value3, value4);
} }
public setUniform2x2f(uniform: string, value: ArrayLike<number>) { public setUniform2x2f (uniform: string, value: ArrayLike<number>) {
let gl = this.context.gl; let gl = this.context.gl;
this.tmp2x2.set(value); this.tmp2x2.set(value);
gl.uniformMatrix2fv(this.getUniformLocation(uniform), false, this.tmp2x2); gl.uniformMatrix2fv(this.getUniformLocation(uniform), false, this.tmp2x2);
} }
public setUniform3x3f(uniform: string, value: ArrayLike<number>) { public setUniform3x3f (uniform: string, value: ArrayLike<number>) {
let gl = this.context.gl; let gl = this.context.gl;
this.tmp3x3.set(value); this.tmp3x3.set(value);
gl.uniformMatrix3fv(this.getUniformLocation(uniform), false, this.tmp3x3); gl.uniformMatrix3fv(this.getUniformLocation(uniform), false, this.tmp3x3);
} }
public setUniform4x4f(uniform: string, value: ArrayLike<number>) { public setUniform4x4f (uniform: string, value: ArrayLike<number>) {
let gl = this.context.gl; let gl = this.context.gl;
this.tmp4x4.set(value); this.tmp4x4.set(value);
gl.uniformMatrix4fv(this.getUniformLocation(uniform), false, this.tmp4x4); gl.uniformMatrix4fv(this.getUniformLocation(uniform), false, this.tmp4x4);
} }
public getUniformLocation(uniform: string): WebGLUniformLocation { public getUniformLocation (uniform: string): WebGLUniformLocation {
let gl = this.context.gl; let gl = this.context.gl;
let location = gl.getUniformLocation(this.program, uniform); let location = gl.getUniformLocation(this.program, uniform);
if (!location && !gl.isContextLost()) throw new Error(`Couldn't find location for uniform ${uniform}`); if (!location && !gl.isContextLost()) throw new Error(`Couldn't find location for uniform ${uniform}`);
return location; return location;
} }
public getAttributeLocation(attribute: string): number { public getAttributeLocation (attribute: string): number {
let gl = this.context.gl; let gl = this.context.gl;
let location = gl.getAttribLocation(this.program, attribute); let location = gl.getAttribLocation(this.program, attribute);
if (location == -1 && !gl.isContextLost()) throw new Error(`Couldn't find location for attribute ${attribute}`); if (location == -1 && !gl.isContextLost()) throw new Error(`Couldn't find location for attribute ${attribute}`);
return location; return location;
} }
public dispose() { public dispose () {
this.context.removeRestorable(this); this.context.removeRestorable(this);
let gl = this.context.gl; let gl = this.context.gl;
@ -186,7 +186,7 @@ export class Shader implements Disposable, Restorable {
} }
} }
public static newColoredTextured(context: ManagedWebGLRenderingContext | WebGLRenderingContext): Shader { public static newColoredTextured (context: ManagedWebGLRenderingContext | WebGLRenderingContext): Shader {
let vs = ` let vs = `
attribute vec4 ${Shader.POSITION}; attribute vec4 ${Shader.POSITION};
attribute vec4 ${Shader.COLOR}; attribute vec4 ${Shader.COLOR};
@ -221,7 +221,7 @@ export class Shader implements Disposable, Restorable {
return new Shader(context, vs, fs); return new Shader(context, vs, fs);
} }
public static newTwoColoredTextured(context: ManagedWebGLRenderingContext | WebGLRenderingContext): Shader { public static newTwoColoredTextured (context: ManagedWebGLRenderingContext | WebGLRenderingContext): Shader {
let vs = ` let vs = `
attribute vec4 ${Shader.POSITION}; attribute vec4 ${Shader.POSITION};
attribute vec4 ${Shader.COLOR}; attribute vec4 ${Shader.COLOR};
@ -262,7 +262,7 @@ export class Shader implements Disposable, Restorable {
return new Shader(context, vs, fs); return new Shader(context, vs, fs);
} }
public static newColored(context: ManagedWebGLRenderingContext | WebGLRenderingContext): Shader { public static newColored (context: ManagedWebGLRenderingContext | WebGLRenderingContext): Shader {
let vs = ` let vs = `
attribute vec4 ${Shader.POSITION}; attribute vec4 ${Shader.POSITION};
attribute vec4 ${Shader.COLOR}; attribute vec4 ${Shader.COLOR};

View File

@ -45,7 +45,7 @@ export class ShapeRenderer implements Disposable {
private srcAlphaBlend: number; private srcAlphaBlend: number;
private dstBlend: number; private dstBlend: number;
constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext, maxVertices: number = 10920) { constructor (context: ManagedWebGLRenderingContext | WebGLRenderingContext, maxVertices: number = 10920) {
if (maxVertices > 10920) throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices); if (maxVertices > 10920) throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
this.context = context instanceof ManagedWebGLRenderingContext ? context : new ManagedWebGLRenderingContext(context); this.context = context instanceof ManagedWebGLRenderingContext ? context : new ManagedWebGLRenderingContext(context);
this.mesh = new Mesh(context, [new Position2Attribute(), new ColorAttribute()], maxVertices, 0); this.mesh = new Mesh(context, [new Position2Attribute(), new ColorAttribute()], maxVertices, 0);
@ -55,7 +55,7 @@ export class ShapeRenderer implements Disposable {
this.dstBlend = gl.ONE_MINUS_SRC_ALPHA; this.dstBlend = gl.ONE_MINUS_SRC_ALPHA;
} }
begin(shader: Shader) { begin (shader: Shader) {
if (this.isDrawing) throw new Error("ShapeRenderer.begin() has already been called"); if (this.isDrawing) throw new Error("ShapeRenderer.begin() has already been called");
this.shader = shader; this.shader = shader;
this.vertexIndex = 0; this.vertexIndex = 0;
@ -66,7 +66,7 @@ export class ShapeRenderer implements Disposable {
gl.blendFuncSeparate(this.srcColorBlend, this.dstBlend, this.srcAlphaBlend, this.dstBlend); gl.blendFuncSeparate(this.srcColorBlend, this.dstBlend, this.srcAlphaBlend, this.dstBlend);
} }
setBlendMode(srcColorBlend: number, srcAlphaBlend: number, dstBlend: number) { setBlendMode (srcColorBlend: number, srcAlphaBlend: number, dstBlend: number) {
this.srcColorBlend = srcColorBlend; this.srcColorBlend = srcColorBlend;
this.srcAlphaBlend = srcAlphaBlend; this.srcAlphaBlend = srcAlphaBlend;
this.dstBlend = dstBlend; this.dstBlend = dstBlend;
@ -77,21 +77,21 @@ export class ShapeRenderer implements Disposable {
} }
} }
setColor(color: Color) { setColor (color: Color) {
this.color.setFromColor(color); this.color.setFromColor(color);
} }
setColorWith(r: number, g: number, b: number, a: number) { setColorWith (r: number, g: number, b: number, a: number) {
this.color.set(r, g, b, a); this.color.set(r, g, b, a);
} }
point(x: number, y: number, color: Color = null) { point (x: number, y: number, color: Color = null) {
this.check(ShapeType.Point, 1); this.check(ShapeType.Point, 1);
if (color === null) color = this.color; if (color === null) color = this.color;
this.vertex(x, y, color); this.vertex(x, y, color);
} }
line(x: number, y: number, x2: number, y2: number, color: Color = null) { line (x: number, y: number, x2: number, y2: number, color: Color = null) {
this.check(ShapeType.Line, 2); this.check(ShapeType.Line, 2);
let vertices = this.mesh.getVertices(); let vertices = this.mesh.getVertices();
let idx = this.vertexIndex; let idx = this.vertexIndex;
@ -100,7 +100,7 @@ export class ShapeRenderer implements Disposable {
this.vertex(x2, y2, color); this.vertex(x2, y2, color);
} }
triangle(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, color: Color = null, color2: Color = null, color3: Color = null) { triangle (filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, color: Color = null, color2: Color = null, color3: Color = null) {
this.check(filled ? ShapeType.Filled : ShapeType.Line, 3); this.check(filled ? ShapeType.Filled : ShapeType.Line, 3);
let vertices = this.mesh.getVertices(); let vertices = this.mesh.getVertices();
let idx = this.vertexIndex; let idx = this.vertexIndex;
@ -123,7 +123,7 @@ export class ShapeRenderer implements Disposable {
} }
} }
quad(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number, color: Color = null, color2: Color = null, color3: Color = null, color4: Color = null) { quad (filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number, color: Color = null, color2: Color = null, color3: Color = null, color4: Color = null) {
this.check(filled ? ShapeType.Filled : ShapeType.Line, 3); this.check(filled ? ShapeType.Filled : ShapeType.Line, 3);
let vertices = this.mesh.getVertices(); let vertices = this.mesh.getVertices();
let idx = this.vertexIndex; let idx = this.vertexIndex;
@ -142,11 +142,11 @@ export class ShapeRenderer implements Disposable {
} }
} }
rect(filled: boolean, x: number, y: number, width: number, height: number, color: Color = null) { rect (filled: boolean, x: number, y: number, width: number, height: number, color: Color = null) {
this.quad(filled, x, y, x + width, y, x + width, y + height, x, y + height, color, color, color, color); this.quad(filled, x, y, x + width, y, x + width, y + height, x, y + height, color, color, color, color);
} }
rectLine(filled: boolean, x1: number, y1: number, x2: number, y2: number, width: number, color: Color = null) { rectLine (filled: boolean, x1: number, y1: number, x2: number, y2: number, width: number, color: Color = null) {
this.check(filled ? ShapeType.Filled : ShapeType.Line, 8); this.check(filled ? ShapeType.Filled : ShapeType.Line, 8);
if (color === null) color = this.color; if (color === null) color = this.color;
let t = this.tmp.set(y2 - y1, x1 - x2); let t = this.tmp.set(y2 - y1, x1 - x2);
@ -176,12 +176,12 @@ export class ShapeRenderer implements Disposable {
} }
} }
x(x: number, y: number, size: number) { x (x: number, y: number, size: number) {
this.line(x - size, y - size, x + size, y + size); this.line(x - size, y - size, x + size, y + size);
this.line(x - size, y + size, x + size, y - size); this.line(x - size, y + size, x + size, y - size);
} }
polygon(polygonVertices: ArrayLike<number>, offset: number, count: number, color: Color = null) { polygon (polygonVertices: ArrayLike<number>, offset: number, count: number, color: Color = null) {
if (count < 3) throw new Error("Polygon must contain at least 3 vertices"); if (count < 3) throw new Error("Polygon must contain at least 3 vertices");
this.check(ShapeType.Line, count * 2); this.check(ShapeType.Line, count * 2);
if (color === null) color = this.color; if (color === null) color = this.color;
@ -215,7 +215,7 @@ export class ShapeRenderer implements Disposable {
} }
} }
circle(filled: boolean, x: number, y: number, radius: number, color: Color = null, segments: number = 0) { circle (filled: boolean, x: number, y: number, radius: number, color: Color = null, segments: number = 0) {
if (segments === 0) segments = Math.max(1, (6 * MathUtils.cbrt(radius)) | 0); if (segments === 0) segments = Math.max(1, (6 * MathUtils.cbrt(radius)) | 0);
if (segments <= 0) throw new Error("segments must be > 0."); if (segments <= 0) throw new Error("segments must be > 0.");
if (color === null) color = this.color; if (color === null) color = this.color;
@ -256,7 +256,7 @@ export class ShapeRenderer implements Disposable {
this.vertex(x + cx, y + cy, color); this.vertex(x + cx, y + cy, color);
} }
curve(x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color: Color = null) { curve (x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color: Color = null) {
this.check(ShapeType.Line, segments * 2 + 2); this.check(ShapeType.Line, segments * 2 + 2);
if (color === null) color = this.color; if (color === null) color = this.color;
@ -302,7 +302,7 @@ export class ShapeRenderer implements Disposable {
this.vertex(x2, y2, color); this.vertex(x2, y2, color);
} }
private vertex(x: number, y: number, color: Color) { private vertex (x: number, y: number, color: Color) {
let idx = this.vertexIndex; let idx = this.vertexIndex;
let vertices = this.mesh.getVertices(); let vertices = this.mesh.getVertices();
vertices[idx++] = x; vertices[idx++] = x;
@ -314,7 +314,7 @@ export class ShapeRenderer implements Disposable {
this.vertexIndex = idx; this.vertexIndex = idx;
} }
end() { end () {
if (!this.isDrawing) throw new Error("ShapeRenderer.begin() has not been called"); if (!this.isDrawing) throw new Error("ShapeRenderer.begin() has not been called");
this.flush(); this.flush();
let gl = this.context.gl; let gl = this.context.gl;
@ -322,14 +322,14 @@ export class ShapeRenderer implements Disposable {
this.isDrawing = false; this.isDrawing = false;
} }
private flush() { private flush () {
if (this.vertexIndex == 0) return; if (this.vertexIndex == 0) return;
this.mesh.setVerticesLength(this.vertexIndex); this.mesh.setVerticesLength(this.vertexIndex);
this.mesh.draw(this.shader, this.shapeType); this.mesh.draw(this.shader, this.shapeType);
this.vertexIndex = 0; this.vertexIndex = 0;
} }
private check(shapeType: ShapeType, numVertices: number) { private check (shapeType: ShapeType, numVertices: number) {
if (!this.isDrawing) throw new Error("ShapeRenderer.begin() has not been called"); if (!this.isDrawing) throw new Error("ShapeRenderer.begin() has not been called");
if (this.shapeType == shapeType) { if (this.shapeType == shapeType) {
if (this.mesh.maxVertices() - this.mesh.numVertices() < numVertices) this.flush(); if (this.mesh.maxVertices() - this.mesh.numVertices() < numVertices) this.flush();
@ -340,7 +340,7 @@ export class ShapeRenderer implements Disposable {
} }
} }
dispose() { dispose () {
this.mesh.dispose(); this.mesh.dispose();
} }
} }

View File

@ -58,11 +58,11 @@ export class SkeletonDebugRenderer implements Disposable {
private static LIGHT_GRAY = new Color(192 / 255, 192 / 255, 192 / 255, 1); private static LIGHT_GRAY = new Color(192 / 255, 192 / 255, 192 / 255, 1);
private static GREEN = new Color(0, 1, 0, 1); private static GREEN = new Color(0, 1, 0, 1);
constructor(context: ManagedWebGLRenderingContext | WebGLRenderingContext) { constructor (context: ManagedWebGLRenderingContext | WebGLRenderingContext) {
this.context = context instanceof ManagedWebGLRenderingContext ? context : new ManagedWebGLRenderingContext(context); this.context = context instanceof ManagedWebGLRenderingContext ? context : new ManagedWebGLRenderingContext(context);
} }
draw(shapes: ShapeRenderer, skeleton: Skeleton, ignoredBones: Array<string> = null) { draw (shapes: ShapeRenderer, skeleton: Skeleton, ignoredBones: Array<string> = null) {
let skeletonX = skeleton.x; let skeletonX = skeleton.x;
let skeletonY = skeleton.y; let skeletonY = skeleton.y;
let gl = this.context.gl; let gl = this.context.gl;
@ -222,6 +222,6 @@ export class SkeletonDebugRenderer implements Disposable {
} }
} }
dispose() { dispose () {
} }
} }

View File

@ -34,7 +34,7 @@ import { ManagedWebGLRenderingContext, WebGLBlendModeConverter } from "./WebGL";
class Renderable { class Renderable {
constructor(public vertices: NumberArrayLike, public numVertices: number, public numFloats: number) { } constructor (public vertices: NumberArrayLike, public numVertices: number, public numFloats: number) { }
}; };
export class SkeletonRenderer { export class SkeletonRenderer {
@ -54,14 +54,14 @@ export class SkeletonRenderer {
private temp3 = new Color(); private temp3 = new Color();
private temp4 = new Color(); private temp4 = new Color();
constructor(context: ManagedWebGLRenderingContext, twoColorTint: boolean = true) { constructor (context: ManagedWebGLRenderingContext, twoColorTint: boolean = true) {
this.twoColorTint = twoColorTint; this.twoColorTint = twoColorTint;
if (twoColorTint) if (twoColorTint)
this.vertexSize += 4; this.vertexSize += 4;
this.vertices = Utils.newFloatArray(this.vertexSize * 1024); this.vertices = Utils.newFloatArray(this.vertexSize * 1024);
} }
draw(batcher: PolygonBatcher, skeleton: Skeleton, slotRangeStart: number = -1, slotRangeEnd: number = -1) { draw (batcher: PolygonBatcher, skeleton: Skeleton, slotRangeStart: number = -1, slotRangeEnd: number = -1) {
let clipper = this.clipper; let clipper = this.clipper;
let premultipliedAlpha = this.premultipliedAlpha; let premultipliedAlpha = this.premultipliedAlpha;
let twoColorTint = this.twoColorTint; let twoColorTint = this.twoColorTint;

View File

@ -34,48 +34,48 @@ export class Vector3 {
y = 0; y = 0;
z = 0; z = 0;
constructor(x: number = 0, y: number = 0, z: number = 0) { constructor (x: number = 0, y: number = 0, z: number = 0) {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
} }
setFrom(v: Vector3): Vector3 { setFrom (v: Vector3): Vector3 {
this.x = v.x; this.x = v.x;
this.y = v.y; this.y = v.y;
this.z = v.z; this.z = v.z;
return this; return this;
} }
set(x: number, y: number, z: number): Vector3 { set (x: number, y: number, z: number): Vector3 {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
return this; return this;
} }
add(v: Vector3): Vector3 { add (v: Vector3): Vector3 {
this.x += v.x; this.x += v.x;
this.y += v.y; this.y += v.y;
this.z += v.z; this.z += v.z;
return this; return this;
} }
sub(v: Vector3): Vector3 { sub (v: Vector3): Vector3 {
this.x -= v.x; this.x -= v.x;
this.y -= v.y; this.y -= v.y;
this.z -= v.z; this.z -= v.z;
return this; return this;
} }
scale(s: number): Vector3 { scale (s: number): Vector3 {
this.x *= s; this.x *= s;
this.y *= s; this.y *= s;
this.z *= s; this.z *= s;
return this; return this;
} }
normalize(): Vector3 { normalize (): Vector3 {
let len = this.length(); let len = this.length();
if (len == 0) return this; if (len == 0) return this;
len = 1 / len; len = 1 / len;
@ -85,18 +85,18 @@ export class Vector3 {
return this; return this;
} }
cross(v: Vector3): Vector3 { cross (v: Vector3): Vector3 {
return this.set(this.y * v.z - this.z * v.y, this.z * v.x - this.x * v.z, this.x * v.y - this.y * v.x) return this.set(this.y * v.z - this.z * v.y, this.z * v.x - this.x * v.z, this.x * v.y - this.y * v.x)
} }
multiply(matrix: Matrix4): Vector3 { multiply (matrix: Matrix4): Vector3 {
let l_mat = matrix.values; let l_mat = matrix.values;
return this.set(this.x * l_mat[M00] + this.y * l_mat[M01] + this.z * l_mat[M02] + l_mat[M03], return this.set(this.x * l_mat[M00] + this.y * l_mat[M01] + this.z * l_mat[M02] + l_mat[M03],
this.x * l_mat[M10] + this.y * l_mat[M11] + this.z * l_mat[M12] + l_mat[M13], this.x * l_mat[M10] + this.y * l_mat[M11] + this.z * l_mat[M12] + l_mat[M13],
this.x * l_mat[M20] + this.y * l_mat[M21] + this.z * l_mat[M22] + l_mat[M23]); this.x * l_mat[M20] + this.y * l_mat[M21] + this.z * l_mat[M22] + l_mat[M23]);
} }
project(matrix: Matrix4): Vector3 { project (matrix: Matrix4): Vector3 {
let l_mat = matrix.values; let l_mat = matrix.values;
let l_w = 1 / (this.x * l_mat[M30] + this.y * l_mat[M31] + this.z * l_mat[M32] + l_mat[M33]); let l_w = 1 / (this.x * l_mat[M30] + this.y * l_mat[M31] + this.z * l_mat[M32] + l_mat[M33]);
return this.set((this.x * l_mat[M00] + this.y * l_mat[M01] + this.z * l_mat[M02] + l_mat[M03]) * l_w, return this.set((this.x * l_mat[M00] + this.y * l_mat[M01] + this.z * l_mat[M02] + l_mat[M03]) * l_w,
@ -104,15 +104,15 @@ export class Vector3 {
(this.x * l_mat[M20] + this.y * l_mat[M21] + this.z * l_mat[M22] + l_mat[M23]) * l_w); (this.x * l_mat[M20] + this.y * l_mat[M21] + this.z * l_mat[M22] + l_mat[M23]) * l_w);
} }
dot(v: Vector3): number { dot (v: Vector3): number {
return this.x * v.x + this.y * v.y + this.z * v.z; return this.x * v.x + this.y * v.y + this.z * v.z;
} }
length(): number { length (): number {
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
} }
distance(v: Vector3): number { distance (v: Vector3): number {
let a = v.x - this.x; let a = v.x - this.x;
let b = v.y - this.y; let b = v.y - this.y;
let c = v.z - this.z; let c = v.z - this.z;

View File

@ -34,7 +34,7 @@ export class ManagedWebGLRenderingContext {
public gl: WebGLRenderingContext; public gl: WebGLRenderingContext;
private restorables = new Array<Restorable>(); private restorables = new Array<Restorable>();
constructor(canvasOrContext: HTMLCanvasElement | WebGLRenderingContext | EventTarget, contextConfig: any = { alpha: "true" }) { constructor (canvasOrContext: HTMLCanvasElement | WebGLRenderingContext | EventTarget, contextConfig: any = { alpha: "true" }) {
if (!((canvasOrContext instanceof WebGLRenderingContext) || (typeof WebGL2RenderingContext !== 'undefined' && canvasOrContext instanceof WebGL2RenderingContext))) if (!((canvasOrContext instanceof WebGLRenderingContext) || (typeof WebGL2RenderingContext !== 'undefined' && canvasOrContext instanceof WebGL2RenderingContext)))
this.setupCanvas(canvasOrContext, contextConfig); this.setupCanvas(canvasOrContext, contextConfig);
else { else {
@ -43,7 +43,7 @@ export class ManagedWebGLRenderingContext {
} }
} }
private setupCanvas(canvas: any, contextConfig: any) { private setupCanvas (canvas: any, contextConfig: any) {
this.gl = <WebGLRenderingContext>(canvas.getContext("webgl2", contextConfig) || canvas.getContext("webgl", contextConfig)); this.gl = <WebGLRenderingContext>(canvas.getContext("webgl2", contextConfig) || canvas.getContext("webgl", contextConfig));
this.canvas = canvas; this.canvas = canvas;
canvas.addEventListener("webglcontextlost", (e: any) => { canvas.addEventListener("webglcontextlost", (e: any) => {
@ -57,11 +57,11 @@ export class ManagedWebGLRenderingContext {
}); });
} }
addRestorable(restorable: Restorable) { addRestorable (restorable: Restorable) {
this.restorables.push(restorable); this.restorables.push(restorable);
} }
removeRestorable(restorable: Restorable) { removeRestorable (restorable: Restorable) {
let index = this.restorables.indexOf(restorable); let index = this.restorables.indexOf(restorable);
if (index > -1) this.restorables.splice(index, 1); if (index > -1) this.restorables.splice(index, 1);
} }
@ -75,7 +75,7 @@ const ONE_MINUS_DST_ALPHA = 0x0305;
const DST_COLOR = 0x0306; const DST_COLOR = 0x0306;
export class WebGLBlendModeConverter { export class WebGLBlendModeConverter {
static getDestGLBlendMode(blendMode: BlendMode) { static getDestGLBlendMode (blendMode: BlendMode) {
switch (blendMode) { switch (blendMode) {
case BlendMode.Normal: return ONE_MINUS_SRC_ALPHA; case BlendMode.Normal: return ONE_MINUS_SRC_ALPHA;
case BlendMode.Additive: return ONE; case BlendMode.Additive: return ONE;
@ -85,7 +85,7 @@ export class WebGLBlendModeConverter {
} }
} }
static getSourceColorGLBlendMode(blendMode: BlendMode, premultipliedAlpha: boolean = false) { static getSourceColorGLBlendMode (blendMode: BlendMode, premultipliedAlpha: boolean = false) {
switch (blendMode) { switch (blendMode) {
case BlendMode.Normal: return premultipliedAlpha ? ONE : SRC_ALPHA; case BlendMode.Normal: return premultipliedAlpha ? ONE : SRC_ALPHA;
case BlendMode.Additive: return premultipliedAlpha ? ONE : SRC_ALPHA; case BlendMode.Additive: return premultipliedAlpha ? ONE : SRC_ALPHA;
@ -95,7 +95,7 @@ export class WebGLBlendModeConverter {
} }
} }
static getSourceAlphaGLBlendMode(blendMode: BlendMode) { static getSourceAlphaGLBlendMode (blendMode: BlendMode) {
switch (blendMode) { switch (blendMode) {
case BlendMode.Normal: return ONE; case BlendMode.Normal: return ONE;
case BlendMode.Additive: return ONE; case BlendMode.Additive: return ONE;