Эх сурвалжийг харах

[ts][webgl][widget] Implemented clipping, updated README.md and CHANGELOG

badlogic 8 жил өмнө
parent
commit
d4266cf89a

+ 3 - 1
CHANGELOG.md

@@ -120,12 +120,14 @@
   * Added `Bone.localToWorldRotation`(rotation given relative to x-axis, counter-clockwise, in degrees).  
   * Added two color tinting support, including `TwoColorTimeline` and additional fields on `Slot` and `SlotData`.  
   * Added `PointAttachment`, additional method `newPointAttachment` in `AttachmentLoader` interface.
+  * Added `ClippingAttachment`, additional method `newClippingAttachment` in `AttachmentLoader` interface.
 
 ### WebGL backend
  * Fixed renderer to work with 3.6 changes.
  * Added support for two color tinting.
  * Improved performance by using `DYNAMIC_DRAW` for vertex buffer objects and fixing bug that copied to much data to the GPU each frame in `PolygonBatcher`/`Mesh`.
  * Added two color tinting support, enabled by default. You can disable it via the constructors of `SceneRenderer`, `SkeletonRenderer`and `PolygonBatcher`. Note that you will need to use a shader created via `Shader.newTwoColoredTexturedShader` shader with `SkeletonRenderer` and `PolygonBatcher` if two color tinting is enabled.
+ * Added clipping support
 
 ### Canvas backend
  * Fixed renderer to work for 3.6 changes. Sadly, we can't support two color tinting via the Canvas API.
@@ -136,5 +138,5 @@
  * Fixed renderer to work with 3.6 changes. Two color tinting is not supported.
 
 ### Widget backend
- * Fixed renderer to work for 3.6 changes. Supports two color tinting (see webgl backend changes for details).
+ * Fixed renderer to work for 3.6 changes. Supports two color tinting & clipping (see webgl backend changes for details).
  * Added fields `atlasContent`, `atlasPagesContent`, and `jsonContent` to `WidgetConfiguration` allowing you to directly pass the contents of the `.atlas`, atlas page `.png` files, and the `.json` file without having to do a request. See `README.md` and the example for details.

+ 2 - 2
spine-ts/README.md

@@ -22,9 +22,9 @@ spine-ts works with data exported from Spine 3.6.xx
 
 spine-ts WebGL & Widget backends supports all Spine features. 
 
-spine-ts Canvas does not support color tinting and mesh attachments. Only the alpha channel from tint colors is applied. Experimental support for mesh attachments can be enabled by setting `spine.canvas.SkeletonRenderer.useTriangleRendering` to true. Note that this method is slow and may lead to artifacts on some browsers. 
+spine-ts Canvas does not support color tinting, mesh attachments and clipping. Only the alpha channel from tint colors is applied. Experimental support for mesh attachments can be enabled by setting `spine.canvas.SkeletonRenderer.useTriangleRendering` to true. Note that this method is slow and may lead to artifacts on some browsers. 
 
-spine-ts THREE.JS does not support color tinting and blend modes. The THREE.JS backend provides `SkeletonMesh.zOffset` to avoid z-fighting. Adjust to your near/far plane settings.
+spine-ts THREE.JS does not support color tinting, blend modes and clipping. The THREE.JS backend provides `SkeletonMesh.zOffset` to avoid z-fighting. Adjust to your near/far plane settings.
 
 spine-ts does not yet support loading the binary format.
 

+ 48 - 3
spine-ts/build/spine-all.d.ts

@@ -454,6 +454,7 @@ declare module spine {
 		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
 		newPathAttachment(skin: Skin, name: string): PathAttachment;
 		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
 	}
 }
 declare module spine {
@@ -477,6 +478,7 @@ declare module spine {
 		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
 		newPathAttachment(skin: Skin, name: string): PathAttachment;
 		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
 	}
 }
 declare module spine {
@@ -495,6 +497,13 @@ declare module spine {
 		constructor(name: string);
 	}
 }
+declare module spine {
+	class ClippingAttachment extends VertexAttachment {
+		endSlot: SlotData;
+		color: Color;
+		constructor(name: string);
+	}
+}
 declare module spine {
 	class MeshAttachment extends VertexAttachment {
 		region: TextureRegion;
@@ -678,6 +687,21 @@ declare module spine {
 		getOrder(): number;
 	}
 }
+declare module spine {
+	class ConvexDecomposer {
+		private convexPolygons;
+		private convexPolygonsIndices;
+		private indicesArray;
+		private isConcaveArray;
+		private triangles;
+		private polygonPool;
+		private polygonIndicesPool;
+		decompose(input: ArrayLike<number>): Array<Array<number>>;
+		private static isConcave(index, vertexCount, vertices, indices);
+		private static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y);
+		private static winding(p1x, p1y, p2x, p2y, p3x, p3y);
+	}
+}
 declare module spine {
 	class Event {
 		data: EventData;
@@ -873,6 +897,25 @@ declare module spine {
 		getHeight(): number;
 	}
 }
+declare module spine {
+	class SkeletonClipping {
+		private decomposer;
+		private clippingPolygon;
+		private clipOutput;
+		clippedVertices: number[];
+		clippedTriangles: number[];
+		private scratch;
+		private clipAttachment;
+		private clippingPolygons;
+		clipStart(slot: Slot, clip: ClippingAttachment): void;
+		clipEndWithSlot(slot: Slot): void;
+		clipEnd(): void;
+		isClipping(): boolean;
+		clipTriangles(vertices: ArrayLike<number>, verticesLength: number, triangles: ArrayLike<number>, trianglesLength: number, uvs: ArrayLike<number>, light: Color, dark: Color, twoColor: boolean): void;
+		clip(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, clippingArea: Array<number>, output: Array<number>): boolean;
+		static makeClockwise(polygon: ArrayLike<number>): void;
+	}
+}
 declare module spine {
 	class SkeletonData {
 		name: string;
@@ -911,7 +954,7 @@ declare module spine {
 		private linkedMeshes;
 		constructor(attachmentLoader: AttachmentLoader);
 		readSkeletonData(json: string | any): SkeletonData;
-		readAttachment(map: any, skin: Skin, slotIndex: number, name: string): Attachment;
+		readAttachment(map: any, skin: Skin, slotIndex: number, name: string, skeletonData: SkeletonData): Attachment;
 		readVertices(map: any, attachment: VertexAttachment, verticesLength: number): void;
 		readAnimation(map: any, name: string, skeletonData: SkeletonData): void;
 		readCurve(map: any, timeline: CurveTimeline, frameIndex: number): void;
@@ -1089,6 +1132,7 @@ declare module spine {
 		static ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
 		static newArray<T>(size: number, defaultValue: T): Array<T>;
 		static newFloatArray(size: number): ArrayLike<number>;
+		static newShortArray(size: number): ArrayLike<number>;
 		static toFloatArray(array: Array<number>): number[] | Float32Array;
 	}
 	class DebugUtils {
@@ -1524,6 +1568,7 @@ declare module spine.webgl {
 		attachmentLineColor: Color;
 		triangleLineColor: Color;
 		pathColor: Color;
+		clipColor: Color;
 		aabbColor: Color;
 		drawBones: boolean;
 		drawRegionAttachments: boolean;
@@ -1532,6 +1577,7 @@ declare module spine.webgl {
 		drawMeshTriangles: boolean;
 		drawPaths: boolean;
 		drawSkeletonXY: boolean;
+		drawClipping: boolean;
 		premultipliedAlpha: boolean;
 		scale: number;
 		boneWidth: number;
@@ -1557,10 +1603,9 @@ declare module spine.webgl {
 		private vertexSize;
 		private twoColorTint;
 		private renderable;
+		private clipper;
 		constructor(gl: WebGLRenderingContext, twoColorTint?: boolean);
 		draw(batcher: PolygonBatcher, skeleton: Skeleton): void;
-		private computeRegionVertices(slot, region, pma, twoColorTint?);
-		private computeMeshVertices(slot, mesh, pma, twoColorTint?);
 	}
 }
 declare module spine.webgl {

+ 634 - 135
spine-ts/build/spine-all.js

@@ -2242,6 +2242,9 @@ var spine;
 		AtlasAttachmentLoader.prototype.newPointAttachment = function (skin, name) {
 			return new spine.PointAttachment(name);
 		};
+		AtlasAttachmentLoader.prototype.newClippingAttachment = function (skin, name) {
+			return new spine.ClippingAttachment(name);
+		};
 		return AtlasAttachmentLoader;
 	}());
 	spine.AtlasAttachmentLoader = AtlasAttachmentLoader;
@@ -2354,6 +2357,18 @@ var spine;
 	spine.BoundingBoxAttachment = BoundingBoxAttachment;
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var ClippingAttachment = (function (_super) {
+		__extends(ClippingAttachment, _super);
+		function ClippingAttachment(name) {
+			_super.call(this, name);
+			this.color = new spine.Color(0.2275, 0.2275, 0.8078, 1);
+		}
+		return ClippingAttachment;
+	}(spine.VertexAttachment));
+	spine.ClippingAttachment = ClippingAttachment;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var MeshAttachment = (function (_super) {
 		__extends(MeshAttachment, _super);
@@ -2897,6 +2912,207 @@ var spine;
 	var TransformMode = spine.TransformMode;
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var ConvexDecomposer = (function () {
+		function ConvexDecomposer() {
+			this.convexPolygons = new Array();
+			this.convexPolygonsIndices = new Array();
+			this.indicesArray = new Array();
+			this.isConcaveArray = new Array();
+			this.triangles = new Array();
+			this.polygonPool = new spine.Pool(function () {
+				return new Array();
+			});
+			this.polygonIndicesPool = new spine.Pool(function () {
+				return new Array();
+			});
+		}
+		ConvexDecomposer.prototype.decompose = function (input) {
+			var vertices = input;
+			var vertexCount = input.length >> 1;
+			var indices = this.indicesArray;
+			indices.length = 0;
+			for (var i = 0; i < vertexCount; i++)
+				indices[i] = i;
+			var isConcave = this.isConcaveArray;
+			isConcave.length = 0;
+			for (var i = 0, n = vertexCount; i < n; ++i)
+				isConcave[i] = ConvexDecomposer.isConcave(i, vertexCount, vertices, indices);
+			var triangles = this.triangles;
+			triangles.length = 0;
+			while (vertexCount > 3) {
+				var previous = vertexCount - 1, i = 0, next = 1;
+				while (true) {
+					outer: if (!isConcave[i]) {
+						var p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1;
+						var p1x = vertices[p1], p1y = vertices[p1 + 1];
+						var p2x = vertices[p2], p2y = vertices[p2 + 1];
+						var p3x = vertices[p3], p3y = vertices[p3 + 1];
+						for (var ii = (next + 1) % vertexCount; ii != previous; ii = (ii + 1) % vertexCount) {
+							if (!isConcave[ii])
+								continue;
+							var v = indices[ii] << 1;
+							var vx = vertices[v], vy = vertices[v + 1];
+							if (ConvexDecomposer.positiveArea(p3x, p3y, p1x, p1y, vx, vy)) {
+								if (ConvexDecomposer.positiveArea(p1x, p1y, p2x, p2y, vx, vy)) {
+									if (ConvexDecomposer.positiveArea(p2x, p2y, p3x, p3y, vx, vy))
+										break outer;
+								}
+							}
+						}
+						break;
+					}
+					if (next == 0) {
+						do {
+							if (!isConcave[i])
+								break;
+							i--;
+						} while (i > 0);
+						break;
+					}
+					previous = i;
+					i = next;
+					next = (next + 1) % vertexCount;
+				}
+				triangles.push(indices[(vertexCount + i - 1) % vertexCount]);
+				triangles.push(indices[i]);
+				triangles.push(indices[(i + 1) % vertexCount]);
+				indices.splice(i, 1);
+				isConcave.splice(i, 1);
+				vertexCount--;
+				var previousIndex = (vertexCount + i - 1) % vertexCount;
+				var nextIndex = i == vertexCount ? 0 : i;
+				isConcave[previousIndex] = ConvexDecomposer.isConcave(previousIndex, vertexCount, vertices, indices);
+				isConcave[nextIndex] = ConvexDecomposer.isConcave(nextIndex, vertexCount, vertices, indices);
+			}
+			if (vertexCount == 3) {
+				triangles.push(indices[2]);
+				triangles.push(indices[0]);
+				triangles.push(indices[1]);
+			}
+			var convexPolygons = this.convexPolygons;
+			this.polygonPool.freeAll(convexPolygons);
+			convexPolygons.length = 0;
+			var convexPolygonsIndices = this.convexPolygonsIndices;
+			this.polygonIndicesPool.freeAll(convexPolygonsIndices);
+			convexPolygonsIndices.length = 0;
+			var polygonIndices = this.polygonIndicesPool.obtain();
+			polygonIndices.length = 0;
+			var polygon = this.polygonPool.obtain();
+			polygon.length = 0;
+			var fanBaseIndex = -1, lastWinding = 0;
+			for (var i = 0, n = triangles.length; i < n; i += 3) {
+				var t1 = triangles[i] << 1, t2 = triangles[i + 1] << 1, t3 = triangles[i + 2] << 1;
+				var x1 = vertices[t1], y1 = vertices[t1 + 1];
+				var x2 = vertices[t2], y2 = vertices[t2 + 1];
+				var x3 = vertices[t3], y3 = vertices[t3 + 1];
+				var merged = false;
+				if (fanBaseIndex == t1) {
+					var o = polygon.length - 4;
+					var winding1 = ConvexDecomposer.winding(polygon[o], polygon[o + 1], polygon[o + 2], polygon[o + 3], x3, y3);
+					var winding2 = ConvexDecomposer.winding(x3, y3, polygon[0], polygon[1], polygon[2], polygon[3]);
+					if (winding1 == lastWinding && winding2 == lastWinding) {
+						polygon.push(x3);
+						polygon.push(y3);
+						polygonIndices.push(t3);
+						merged = true;
+					}
+				}
+				if (!merged) {
+					if (polygon.length > 0) {
+						convexPolygons.push(polygon);
+						convexPolygonsIndices.push(polygonIndices);
+					}
+					polygon = this.polygonPool.obtain();
+					polygon.length = 0;
+					polygon.push(x1);
+					polygon.push(y1);
+					polygon.push(x2);
+					polygon.push(y2);
+					polygon.push(x3);
+					polygon.push(y3);
+					polygonIndices = this.polygonIndicesPool.obtain();
+					polygonIndices.length = 0;
+					polygonIndices.push(t1);
+					polygonIndices.push(t2);
+					polygonIndices.push(t3);
+					lastWinding = ConvexDecomposer.winding(x1, y1, x2, y2, x3, y3);
+					fanBaseIndex = t1;
+				}
+			}
+			if (polygon.length > 0) {
+				convexPolygons.push(polygon);
+				convexPolygonsIndices.push(polygonIndices);
+			}
+			for (var i = 0, n = convexPolygons.length; i < n; i++) {
+				polygonIndices = convexPolygonsIndices[i];
+				if (polygonIndices.length == 0)
+					continue;
+				var firstIndex = polygonIndices[0];
+				var lastIndex = polygonIndices[polygonIndices.length - 1];
+				polygon = convexPolygons[i];
+				var o = polygon.length - 4;
+				var prevPrevX = polygon[o], prevPrevY = polygon[o + 1];
+				var prevX = polygon[o + 2], prevY = polygon[o + 3];
+				var firstX = polygon[0], firstY = polygon[1];
+				var secondX = polygon[2], secondY = polygon[3];
+				var winding = ConvexDecomposer.winding(prevPrevX, prevPrevY, prevX, prevY, firstX, firstY);
+				for (var ii = 0; ii < n; ii++) {
+					if (ii == i)
+						continue;
+					var otherIndices = convexPolygonsIndices[ii];
+					if (otherIndices.length != 3)
+						continue;
+					var otherFirstIndex = otherIndices[0];
+					var otherSecondIndex = otherIndices[1];
+					var otherLastIndex = otherIndices[2];
+					var otherPoly = convexPolygons[ii];
+					var x3 = otherPoly[otherPoly.length - 2], y3 = otherPoly[otherPoly.length - 1];
+					if (otherFirstIndex != firstIndex || otherSecondIndex != lastIndex)
+						continue;
+					var winding1 = ConvexDecomposer.winding(prevPrevX, prevPrevY, prevX, prevY, x3, y3);
+					var winding2 = ConvexDecomposer.winding(x3, y3, firstX, firstY, secondX, secondY);
+					if (winding1 == winding && winding2 == winding) {
+						otherPoly.length = 0;
+						otherIndices.length = 0;
+						polygon.push(x3);
+						polygon.push(y3);
+						polygonIndices.push(otherLastIndex);
+						prevPrevX = prevX;
+						prevPrevY = prevY;
+						prevX = x3;
+						prevY = y3;
+						ii = 0;
+					}
+				}
+			}
+			for (var i = convexPolygons.length - 1; i >= 0; i--) {
+				polygon = convexPolygons[i];
+				if (polygon.length == 0) {
+					convexPolygons.splice(i, 1);
+					this.polygonPool.free(polygon);
+				}
+			}
+			return convexPolygons;
+		};
+		ConvexDecomposer.isConcave = function (index, vertexCount, vertices, indices) {
+			var previous = indices[(vertexCount + index - 1) % vertexCount] << 1;
+			var current = indices[index] << 1;
+			var next = indices[(index + 1) % vertexCount] << 1;
+			return !this.positiveArea(vertices[previous], vertices[previous + 1], vertices[current], vertices[current + 1], vertices[next], vertices[next + 1]);
+		};
+		ConvexDecomposer.positiveArea = function (p1x, p1y, p2x, p2y, p3x, p3y) {
+			return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0;
+		};
+		ConvexDecomposer.winding = function (p1x, p1y, p2x, p2y, p3x, p3y) {
+			var px = p2x - p1x, py = p2y - p1y;
+			return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1;
+		};
+		return ConvexDecomposer;
+	}());
+	spine.ConvexDecomposer = ConvexDecomposer;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var Event = (function () {
 		function Event(time, data) {
@@ -4265,6 +4481,285 @@ var spine;
 	spine.SkeletonBounds = SkeletonBounds;
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var SkeletonClipping = (function () {
+		function SkeletonClipping() {
+			this.decomposer = new spine.ConvexDecomposer();
+			this.clippingPolygon = new Array();
+			this.clipOutput = new Array();
+			this.clippedVertices = new Array();
+			this.clippedTriangles = new Array();
+			this.scratch = new Array();
+		}
+		SkeletonClipping.prototype.clipStart = function (slot, clip) {
+			if (this.clipAttachment != null)
+				return;
+			this.clipAttachment = clip;
+			var n = clip.worldVerticesLength;
+			var vertices = spine.Utils.setArraySize(this.clippingPolygon, n);
+			clip.computeWorldVertices(slot, 0, n, vertices, 0, 2);
+			var clippingPolygon = this.clippingPolygon;
+			SkeletonClipping.makeClockwise(clippingPolygon);
+			var clippingPolygons = this.clippingPolygons = this.decomposer.decompose(clippingPolygon);
+			for (var i = 0, n_1 = clippingPolygons.length; i < n_1; i++) {
+				var polygon = clippingPolygons[i];
+				SkeletonClipping.makeClockwise(polygon);
+				polygon.push(polygon[0]);
+				polygon.push(polygon[1]);
+			}
+		};
+		SkeletonClipping.prototype.clipEndWithSlot = function (slot) {
+			if (this.clipAttachment != null && this.clipAttachment.endSlot == slot.data)
+				this.clipEnd();
+		};
+		SkeletonClipping.prototype.clipEnd = function () {
+			if (this.clipAttachment == null)
+				return;
+			this.clipAttachment = null;
+			this.clippingPolygons = null;
+			this.clippedVertices.length = 0;
+			this.clippedTriangles.length = 0;
+			this.clippingPolygon.length = 0;
+		};
+		SkeletonClipping.prototype.isClipping = function () {
+			return this.clipAttachment != null;
+		};
+		SkeletonClipping.prototype.clipTriangles = function (vertices, verticesLength, triangles, trianglesLength, uvs, light, dark, twoColor) {
+			var clipOutput = this.clipOutput, clippedVertices = this.clippedVertices;
+			var clippedTriangles = this.clippedTriangles;
+			var polygons = this.clippingPolygons;
+			var polygonsCount = this.clippingPolygons.length;
+			var vertexSize = twoColor ? 12 : 8;
+			var index = 0;
+			clippedVertices.length = 0;
+			clippedTriangles.length = 0;
+			outer: for (var i = 0; i < trianglesLength; i += 3) {
+				var vertexOffset = triangles[i] << 1;
+				var x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1];
+				var u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1];
+				vertexOffset = triangles[i + 1] << 1;
+				var x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1];
+				var u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1];
+				vertexOffset = triangles[i + 2] << 1;
+				var x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1];
+				var u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1];
+				for (var p = 0; p < polygonsCount; p++) {
+					var s = clippedVertices.length;
+					if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) {
+						var clipOutputLength = clipOutput.length;
+						if (clipOutputLength == 0)
+							continue;
+						var d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1;
+						var d = 1 / (d0 * d2 + d1 * (y1 - y3));
+						var clipOutputCount = clipOutputLength >> 1;
+						var clipOutputItems = this.clipOutput;
+						var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + clipOutputCount * vertexSize);
+						for (var ii = 0; ii < clipOutputLength; ii += 2) {
+							var x = clipOutputItems[ii], y = clipOutputItems[ii + 1];
+							clippedVerticesItems[s] = x;
+							clippedVerticesItems[s + 1] = y;
+							clippedVerticesItems[s + 2] = light.r;
+							clippedVerticesItems[s + 3] = light.g;
+							clippedVerticesItems[s + 4] = light.b;
+							clippedVerticesItems[s + 5] = light.a;
+							var c0 = x - x3, c1 = y - y3;
+							var a = (d0 * c0 + d1 * c1) * d;
+							var b = (d4 * c0 + d2 * c1) * d;
+							var c = 1 - a - b;
+							clippedVerticesItems[s + 6] = u1 * a + u2 * b + u3 * c;
+							clippedVerticesItems[s + 7] = v1 * a + v2 * b + v3 * c;
+							if (twoColor) {
+								clippedVerticesItems[s + 8] = dark.r;
+								clippedVerticesItems[s + 8] = dark.g;
+								clippedVerticesItems[s + 10] = dark.b;
+								clippedVerticesItems[s + 11] = dark.a;
+							}
+							s += vertexSize;
+						}
+						s = clippedTriangles.length;
+						var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2));
+						clipOutputCount--;
+						for (var ii = 1; ii < clipOutputCount; ii++) {
+							clippedTrianglesItems[s] = index;
+							clippedTrianglesItems[s + 1] = (index + ii);
+							clippedTrianglesItems[s + 2] = (index + ii + 1);
+							s += 3;
+						}
+						index += clipOutputCount + 1;
+					}
+					else {
+						var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + 3 * vertexSize);
+						clippedVerticesItems[s] = x1;
+						clippedVerticesItems[s + 1] = y1;
+						clippedVerticesItems[s + 2] = light.r;
+						clippedVerticesItems[s + 3] = light.g;
+						clippedVerticesItems[s + 4] = light.b;
+						clippedVerticesItems[s + 5] = light.a;
+						if (!twoColor) {
+							clippedVerticesItems[s + 6] = u1;
+							clippedVerticesItems[s + 7] = v1;
+							clippedVerticesItems[s + 8] = x2;
+							clippedVerticesItems[s + 9] = y2;
+							clippedVerticesItems[s + 10] = light.r;
+							clippedVerticesItems[s + 11] = light.g;
+							clippedVerticesItems[s + 12] = light.b;
+							clippedVerticesItems[s + 13] = light.a;
+							clippedVerticesItems[s + 14] = u2;
+							clippedVerticesItems[s + 15] = v2;
+							clippedVerticesItems[s + 16] = x3;
+							clippedVerticesItems[s + 17] = y3;
+							clippedVerticesItems[s + 18] = light.r;
+							clippedVerticesItems[s + 19] = light.g;
+							clippedVerticesItems[s + 20] = light.b;
+							clippedVerticesItems[s + 21] = light.a;
+							clippedVerticesItems[s + 22] = u3;
+							clippedVerticesItems[s + 23] = v3;
+						}
+						else {
+							clippedVerticesItems[s + 6] = u1;
+							clippedVerticesItems[s + 7] = v1;
+							clippedVerticesItems[s + 8] = dark.r;
+							clippedVerticesItems[s + 9] = dark.g;
+							clippedVerticesItems[s + 10] = dark.b;
+							clippedVerticesItems[s + 11] = dark.a;
+							clippedVerticesItems[s + 12] = x2;
+							clippedVerticesItems[s + 13] = y2;
+							clippedVerticesItems[s + 14] = light.r;
+							clippedVerticesItems[s + 15] = light.g;
+							clippedVerticesItems[s + 16] = light.b;
+							clippedVerticesItems[s + 17] = light.a;
+							clippedVerticesItems[s + 18] = u2;
+							clippedVerticesItems[s + 19] = v2;
+							clippedVerticesItems[s + 20] = dark.r;
+							clippedVerticesItems[s + 21] = dark.g;
+							clippedVerticesItems[s + 22] = dark.b;
+							clippedVerticesItems[s + 23] = dark.a;
+							clippedVerticesItems[s + 24] = x3;
+							clippedVerticesItems[s + 25] = y3;
+							clippedVerticesItems[s + 26] = light.r;
+							clippedVerticesItems[s + 27] = light.g;
+							clippedVerticesItems[s + 28] = light.b;
+							clippedVerticesItems[s + 29] = light.a;
+							clippedVerticesItems[s + 30] = u3;
+							clippedVerticesItems[s + 31] = v3;
+							clippedVerticesItems[s + 32] = dark.r;
+							clippedVerticesItems[s + 33] = dark.g;
+							clippedVerticesItems[s + 34] = dark.b;
+							clippedVerticesItems[s + 35] = dark.a;
+						}
+						s = clippedTriangles.length;
+						var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3);
+						clippedTrianglesItems[s] = index;
+						clippedTrianglesItems[s + 1] = (index + 1);
+						clippedTrianglesItems[s + 2] = (index + 2);
+						index += 3;
+						continue outer;
+					}
+				}
+			}
+		};
+		SkeletonClipping.prototype.clip = function (x1, y1, x2, y2, x3, y3, clippingArea, output) {
+			var originalOutput = output;
+			var clipped = false;
+			var input = null;
+			if (clippingArea.length % 4 >= 2) {
+				input = output;
+				output = this.scratch;
+			}
+			else
+				input = this.scratch;
+			input.length = 0;
+			input.push(x1);
+			input.push(y1);
+			input.push(x2);
+			input.push(y2);
+			input.push(x3);
+			input.push(y3);
+			input.push(x1);
+			input.push(y1);
+			output.length = 0;
+			var clippingVertices = clippingArea;
+			var clippingVerticesLast = clippingArea.length - 4;
+			for (var i = 0;; i += 2) {
+				var edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1];
+				var edgeX2 = clippingVertices[i + 2], edgeY2 = clippingVertices[i + 3];
+				var deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2;
+				var inputVertices = input;
+				var inputVerticesLength = input.length - 2, outputStart = output.length;
+				for (var ii = 0; ii < inputVerticesLength; ii += 2) {
+					var inputX = inputVertices[ii], inputY = inputVertices[ii + 1];
+					var inputX2 = inputVertices[ii + 2], inputY2 = inputVertices[ii + 3];
+					var side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0;
+					if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0) {
+						if (side2) {
+							output.push(inputX2);
+							output.push(inputY2);
+							continue;
+						}
+						var c0 = inputY2 - inputY, c2 = inputX2 - inputX;
+						var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
+						output.push(edgeX + (edgeX2 - edgeX) * ua);
+						output.push(edgeY + (edgeY2 - edgeY) * ua);
+					}
+					else if (side2) {
+						var c0 = inputY2 - inputY, c2 = inputX2 - inputX;
+						var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
+						output.push(edgeX + (edgeX2 - edgeX) * ua);
+						output.push(edgeY + (edgeY2 - edgeY) * ua);
+						output.push(inputX2);
+						output.push(inputY2);
+					}
+					clipped = true;
+				}
+				if (outputStart == output.length) {
+					originalOutput.length = 0;
+					return true;
+				}
+				output.push(output[0]);
+				output.push(output[1]);
+				if (i == clippingVerticesLast)
+					break;
+				var temp = output;
+				output = input;
+				output.length = 0;
+				input = temp;
+			}
+			if (originalOutput != output) {
+				originalOutput.length = 0;
+				for (var i = 0, n = output.length - 2; i < n; i++)
+					originalOutput[i] = output[i];
+			}
+			else
+				originalOutput.length = originalOutput.length - 2;
+			return clipped;
+		};
+		SkeletonClipping.makeClockwise = function (polygon) {
+			var vertices = polygon;
+			var verticeslength = polygon.length;
+			var area = vertices[verticeslength - 2] * vertices[1] - vertices[0] * vertices[verticeslength - 1], p1x = 0, p1y = 0, p2x = 0, p2y = 0;
+			for (var i = 0, n = verticeslength - 3; i < n; i += 2) {
+				p1x = vertices[i];
+				p1y = vertices[i + 1];
+				p2x = vertices[i + 2];
+				p2y = vertices[i + 3];
+				area += p1x * p2y - p2x * p1y;
+			}
+			if (area < 0)
+				return;
+			for (var i = 0, lastX = verticeslength - 2, n = verticeslength >> 1; i < n; i += 2) {
+				var x = vertices[i], y = vertices[i + 1];
+				var other = lastX - i;
+				vertices[i] = vertices[other];
+				vertices[i + 1] = vertices[other + 1];
+				vertices[other] = x;
+				vertices[other + 1] = y;
+			}
+		};
+		return SkeletonClipping;
+	}());
+	spine.SkeletonClipping = SkeletonClipping;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var SkeletonData = (function () {
 		function SkeletonData() {
@@ -4556,7 +5051,7 @@ var spine;
 							throw new Error("Slot not found: " + slotName);
 						var slotMap = skinMap[slotName];
 						for (var entryName in slotMap) {
-							var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName);
+							var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName, skeletonData);
 							if (attachment != null)
 								skin.addAttachment(slotIndex, entryName, attachment);
 						}
@@ -4596,7 +5091,7 @@ var spine;
 			}
 			return skeletonData;
 		};
-		SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name) {
+		SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name, skeletonData) {
 			var scale = this.scale;
 			name = this.getValue(map, "name", name);
 			var type = this.getValue(map, "type", "region");
@@ -4683,6 +5178,24 @@ var spine;
 						point.color.setFromString(color);
 					return point;
 				}
+				case "clipping": {
+					var clip = this.attachmentLoader.newClippingAttachment(skin, name);
+					if (clip == null)
+						return null;
+					var end = this.getValue(map, "end", null);
+					if (end != null) {
+						var slot = skeletonData.findSlot(end);
+						if (slot == null)
+							throw new Error("Clipping end slot not found: " + end);
+						clip.endSlot = slot;
+					}
+					var vertexCount = map.vertexCount;
+					this.readVertices(map, clip, vertexCount << 1);
+					var color = this.getValue(map, "color", null);
+					if (color != null)
+						clip.color.setFromString(color);
+					return clip;
+				}
 			}
 			return null;
 		};
@@ -5797,6 +6310,17 @@ var spine;
 				return array;
 			}
 		};
+		Utils.newShortArray = function (size) {
+			if (Utils.SUPPORTS_TYPED_ARRAYS) {
+				return new Int16Array(size);
+			}
+			else {
+				var array = new Array(size);
+				for (var i = 0; i < array.length; i++)
+					array[i] = 0;
+				return array;
+			}
+		};
 		Utils.toFloatArray = function (array) {
 			return Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array;
 		};
@@ -8101,6 +8625,7 @@ var spine;
 				this.attachmentLineColor = new spine.Color(0, 0, 1, 0.5);
 				this.triangleLineColor = new spine.Color(1, 0.64, 0, 0.5);
 				this.pathColor = new spine.Color().setFromString("FF7F00");
+				this.clipColor = new spine.Color(0.8, 0, 0, 2);
 				this.aabbColor = new spine.Color(0, 1, 0, 0.5);
 				this.drawBones = true;
 				this.drawRegionAttachments = true;
@@ -8109,6 +8634,7 @@ var spine;
 				this.drawMeshTriangles = true;
 				this.drawPaths = true;
 				this.drawSkeletonXY = false;
+				this.drawClipping = true;
 				this.premultipliedAlpha = false;
 				this.scale = 1;
 				this.boneWidth = 2;
@@ -8249,6 +8775,27 @@ var spine;
 						shapes.circle(true, skeletonX + bone.worldX, skeletonY + bone.worldY, 3 * this.scale, SkeletonDebugRenderer.GREEN, 8);
 					}
 				}
+				if (this.drawClipping) {
+					var slots = skeleton.slots;
+					shapes.setColor(this.clipColor);
+					for (var i = 0, n = slots.length; i < n; i++) {
+						var slot = slots[i];
+						var attachment = slot.getAttachment();
+						if (!(attachment instanceof spine.ClippingAttachment))
+							continue;
+						var clip = attachment;
+						var nn = clip.worldVerticesLength;
+						var world = this.temp = spine.Utils.setArraySize(this.temp, nn, 0);
+						clip.computeWorldVertices(slot, 0, nn, world, 0, 2);
+						for (var i_5 = 0, n_2 = world.length; i_5 < n_2; i_5 += 2) {
+							var x = world[i_5];
+							var y = world[i_5 + 1];
+							var x2 = world[(i_5 + 2) % world.length];
+							var y2 = world[(i_5 + 3) % world.length];
+							shapes.line(x, y, x2, y2);
+						}
+					}
+				}
 			};
 			SkeletonDebugRenderer.prototype.dispose = function () {
 			};
@@ -8264,8 +8811,9 @@ var spine;
 	var webgl;
 	(function (webgl) {
 		var Renderable = (function () {
-			function Renderable(vertices, numFloats) {
+			function Renderable(vertices, numVertices, numFloats) {
 				this.vertices = vertices;
+				this.numVertices = numVertices;
 				this.numFloats = numFloats;
 			}
 			return Renderable;
@@ -8279,7 +8827,8 @@ var spine;
 				this.tempColor2 = new spine.Color();
 				this.vertexSize = 2 + 2 + 4;
 				this.twoColorTint = false;
-				this.renderable = new Renderable(null, 0);
+				this.renderable = new Renderable(null, 0, 0);
+				this.clipper = new spine.SkeletonClipping();
 				this.gl = gl;
 				this.twoColorTint = twoColorTint;
 				if (twoColorTint)
@@ -8287,165 +8836,115 @@ var spine;
 				this.vertices = spine.Utils.newFloatArray(this.vertexSize * 1024);
 			}
 			SkeletonRenderer.prototype.draw = function (batcher, skeleton) {
+				var clipper = this.clipper;
 				var premultipliedAlpha = this.premultipliedAlpha;
+				var twoColorTint = this.twoColorTint;
 				var blendMode = null;
-				var vertices = null;
+				var renderable = this.renderable;
+				var uvs = null;
 				var triangles = null;
 				var drawOrder = skeleton.drawOrder;
+				var attachmentColor = null;
+				var skeletonColor = skeleton.color;
+				var vertexSize = twoColorTint ? 12 : 8;
 				for (var i = 0, n = drawOrder.length; i < n; i++) {
+					var clippedVertexSize = clipper.isClipping() ? 2 : vertexSize;
 					var slot = drawOrder[i];
 					var attachment = slot.getAttachment();
 					var texture = null;
 					if (attachment instanceof spine.RegionAttachment) {
 						var region = attachment;
-						vertices = this.computeRegionVertices(slot, region, premultipliedAlpha, this.twoColorTint);
+						renderable.vertices = this.vertices;
+						renderable.numVertices = 4;
+						renderable.numFloats = clippedVertexSize << 2;
+						region.computeWorldVertices(slot.bone, renderable.vertices, 0, clippedVertexSize);
 						triangles = SkeletonRenderer.QUAD_TRIANGLES;
+						uvs = region.uvs;
 						texture = region.region.renderObject.texture;
+						attachmentColor = region.color;
 					}
 					else if (attachment instanceof spine.MeshAttachment) {
 						var mesh = attachment;
-						vertices = this.computeMeshVertices(slot, mesh, premultipliedAlpha, this.twoColorTint);
+						renderable.vertices = this.vertices;
+						renderable.numVertices = (mesh.worldVerticesLength >> 1);
+						renderable.numFloats = renderable.numVertices * clippedVertexSize;
+						if (renderable.numFloats > renderable.vertices.length) {
+							renderable.vertices = this.vertices = spine.Utils.newFloatArray(renderable.numFloats);
+						}
+						mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, renderable.vertices, 0, clippedVertexSize);
 						triangles = mesh.triangles;
 						texture = mesh.region.renderObject.texture;
+						uvs = mesh.uvs;
+						attachmentColor = mesh.color;
+					}
+					else if (attachment instanceof spine.ClippingAttachment) {
+						var clip = (attachment);
+						clipper.clipStart(slot, clip);
+						continue;
 					}
 					else
 						continue;
 					if (texture != null) {
+						var slotColor = slot.color;
+						var finalColor = this.tempColor;
+						finalColor.r = skeletonColor.r * slotColor.r * attachmentColor.r;
+						finalColor.g = skeletonColor.g * slotColor.g * attachmentColor.g;
+						finalColor.b = skeletonColor.b * slotColor.b * attachmentColor.b;
+						finalColor.a = skeletonColor.a * slotColor.a * attachmentColor.a;
+						if (premultipliedAlpha) {
+							finalColor.r *= finalColor.a;
+							finalColor.g *= finalColor.a;
+							finalColor.b *= finalColor.a;
+						}
+						var darkColor = this.tempColor2;
+						if (slot.darkColor == null)
+							darkColor.set(0, 0, 0, 1);
+						else
+							darkColor.setFromColor(slot.darkColor);
 						var slotBlendMode = slot.data.blendMode;
 						if (slotBlendMode != blendMode) {
 							blendMode = slotBlendMode;
 							batcher.setBlendMode(webgl.getSourceGLBlendMode(this.gl, blendMode, premultipliedAlpha), webgl.getDestGLBlendMode(this.gl, blendMode));
 						}
-						var view = vertices.vertices.subarray(0, vertices.numFloats);
-						batcher.draw(texture, view, triangles);
-					}
-				}
-			};
-			SkeletonRenderer.prototype.computeRegionVertices = function (slot, region, pma, twoColorTint) {
-				if (twoColorTint === void 0) { twoColorTint = false; }
-				var skeleton = slot.bone.skeleton;
-				var skeletonColor = skeleton.color;
-				var slotColor = slot.color;
-				var regionColor = region.color;
-				var alpha = skeletonColor.a * slotColor.a * regionColor.a;
-				var multiplier = pma ? alpha : 1;
-				var color = this.tempColor;
-				color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
-				var dark = this.tempColor2;
-				if (slot.darkColor == null)
-					dark.set(0, 0, 0, 1);
-				else
-					dark.setFromColor(slot.darkColor);
-				region.computeWorldVertices(slot.bone, this.vertices, 0, this.vertexSize);
-				var vertices = this.vertices;
-				var uvs = region.uvs;
-				var i = 2;
-				vertices[i++] = color.r;
-				vertices[i++] = color.g;
-				vertices[i++] = color.b;
-				vertices[i++] = color.a;
-				vertices[i++] = uvs[0];
-				vertices[i++] = uvs[1];
-				if (twoColorTint) {
-					vertices[i++] = dark.r;
-					vertices[i++] = dark.g;
-					vertices[i++] = dark.b;
-					vertices[i++] = 1;
-				}
-				i += 2;
-				vertices[i++] = color.r;
-				vertices[i++] = color.g;
-				vertices[i++] = color.b;
-				vertices[i++] = color.a;
-				vertices[i++] = uvs[2];
-				vertices[i++] = uvs[3];
-				if (twoColorTint) {
-					vertices[i++] = dark.r;
-					vertices[i++] = dark.g;
-					vertices[i++] = dark.b;
-					vertices[i++] = 1;
-				}
-				i += 2;
-				vertices[i++] = color.r;
-				vertices[i++] = color.g;
-				vertices[i++] = color.b;
-				vertices[i++] = color.a;
-				vertices[i++] = uvs[4];
-				vertices[i++] = uvs[5];
-				if (twoColorTint) {
-					vertices[i++] = dark.r;
-					vertices[i++] = dark.g;
-					vertices[i++] = dark.b;
-					vertices[i++] = 1;
-				}
-				i += 2;
-				vertices[i++] = color.r;
-				vertices[i++] = color.g;
-				vertices[i++] = color.b;
-				vertices[i++] = color.a;
-				vertices[i++] = uvs[6];
-				vertices[i++] = uvs[7];
-				if (twoColorTint) {
-					vertices[i++] = dark.r;
-					vertices[i++] = dark.g;
-					vertices[i++] = dark.b;
-					vertices[i++] = 1;
-				}
-				this.renderable.vertices = vertices;
-				this.renderable.numFloats = 4 * (twoColorTint ? 12 : 8);
-				return this.renderable;
-			};
-			SkeletonRenderer.prototype.computeMeshVertices = function (slot, mesh, pma, twoColorTint) {
-				if (twoColorTint === void 0) { twoColorTint = false; }
-				var skeleton = slot.bone.skeleton;
-				var skeletonColor = skeleton.color;
-				var slotColor = slot.color;
-				var regionColor = mesh.color;
-				var alpha = skeletonColor.a * slotColor.a * regionColor.a;
-				var multiplier = pma ? alpha : 1;
-				var color = this.tempColor;
-				color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
-				var dark = this.tempColor2;
-				if (slot.darkColor == null)
-					dark.set(0, 0, 0, 1);
-				else
-					dark.setFromColor(slot.darkColor);
-				var numVertices = mesh.worldVerticesLength / 2;
-				if (this.vertices.length < mesh.worldVerticesLength) {
-					this.vertices = spine.Utils.newFloatArray(mesh.worldVerticesLength);
-				}
-				var vertices = this.vertices;
-				mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, this.vertexSize);
-				var uvs = mesh.uvs;
-				if (!twoColorTint) {
-					for (var i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
-						vertices[v++] = color.r;
-						vertices[v++] = color.g;
-						vertices[v++] = color.b;
-						vertices[v++] = color.a;
-						vertices[v++] = uvs[u++];
-						vertices[v++] = uvs[u++];
-						v += 2;
-					}
-				}
-				else {
-					for (var i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
-						vertices[v++] = color.r;
-						vertices[v++] = color.g;
-						vertices[v++] = color.b;
-						vertices[v++] = color.a;
-						vertices[v++] = uvs[u++];
-						vertices[v++] = uvs[u++];
-						vertices[v++] = dark.r;
-						vertices[v++] = dark.g;
-						vertices[v++] = dark.b;
-						vertices[v++] = 1;
-						v += 2;
+						if (clipper.isClipping()) {
+							clipper.clipTriangles(renderable.vertices, renderable.numFloats, triangles, triangles.length, uvs, finalColor, darkColor, twoColorTint);
+							var clippedVertices = new Float32Array(clipper.clippedVertices);
+							var clippedTriangles = clipper.clippedTriangles;
+							batcher.draw(texture, clippedVertices, clippedTriangles);
+						}
+						else {
+							var verts = renderable.vertices;
+							if (!twoColorTint) {
+								for (var v = 2, u = 0, n_3 = renderable.numFloats; v < n_3; v += vertexSize, u += 2) {
+									verts[v] = finalColor.r;
+									verts[v + 1] = finalColor.g;
+									verts[v + 2] = finalColor.b;
+									verts[v + 3] = finalColor.a;
+									verts[v + 4] = uvs[u];
+									verts[v + 5] = uvs[u + 1];
+								}
+							}
+							else {
+								for (var v = 2, u = 0, n_4 = renderable.numFloats; v < n_4; v += vertexSize, u += 2) {
+									verts[v] = finalColor.r;
+									verts[v + 1] = finalColor.g;
+									verts[v + 2] = finalColor.b;
+									verts[v + 3] = finalColor.a;
+									verts[v + 4] = uvs[u];
+									verts[v + 5] = uvs[u + 1];
+									verts[v + 6] = darkColor.r;
+									verts[v + 7] = darkColor.g;
+									verts[v + 8] = darkColor.b;
+									verts[v + 9] = darkColor.a;
+								}
+							}
+							var view = renderable.vertices.subarray(0, renderable.numFloats);
+							batcher.draw(texture, view, triangles);
+						}
 					}
+					clipper.clipEndWithSlot(slot);
 				}
-				this.renderable.vertices = vertices;
-				this.renderable.numFloats = numVertices * (twoColorTint ? 12 : 8);
-				return this.renderable;
+				clipper.clipEnd();
 			};
 			SkeletonRenderer.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
 			return SkeletonRenderer;

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
spine-ts/build/spine-all.js.map


+ 45 - 1
spine-ts/build/spine-canvas.d.ts

@@ -454,6 +454,7 @@ declare module spine {
 		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
 		newPathAttachment(skin: Skin, name: string): PathAttachment;
 		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
 	}
 }
 declare module spine {
@@ -477,6 +478,7 @@ declare module spine {
 		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
 		newPathAttachment(skin: Skin, name: string): PathAttachment;
 		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
 	}
 }
 declare module spine {
@@ -495,6 +497,13 @@ declare module spine {
 		constructor(name: string);
 	}
 }
+declare module spine {
+	class ClippingAttachment extends VertexAttachment {
+		endSlot: SlotData;
+		color: Color;
+		constructor(name: string);
+	}
+}
 declare module spine {
 	class MeshAttachment extends VertexAttachment {
 		region: TextureRegion;
@@ -678,6 +687,21 @@ declare module spine {
 		getOrder(): number;
 	}
 }
+declare module spine {
+	class ConvexDecomposer {
+		private convexPolygons;
+		private convexPolygonsIndices;
+		private indicesArray;
+		private isConcaveArray;
+		private triangles;
+		private polygonPool;
+		private polygonIndicesPool;
+		decompose(input: ArrayLike<number>): Array<Array<number>>;
+		private static isConcave(index, vertexCount, vertices, indices);
+		private static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y);
+		private static winding(p1x, p1y, p2x, p2y, p3x, p3y);
+	}
+}
 declare module spine {
 	class Event {
 		data: EventData;
@@ -873,6 +897,25 @@ declare module spine {
 		getHeight(): number;
 	}
 }
+declare module spine {
+	class SkeletonClipping {
+		private decomposer;
+		private clippingPolygon;
+		private clipOutput;
+		clippedVertices: number[];
+		clippedTriangles: number[];
+		private scratch;
+		private clipAttachment;
+		private clippingPolygons;
+		clipStart(slot: Slot, clip: ClippingAttachment): void;
+		clipEndWithSlot(slot: Slot): void;
+		clipEnd(): void;
+		isClipping(): boolean;
+		clipTriangles(vertices: ArrayLike<number>, verticesLength: number, triangles: ArrayLike<number>, trianglesLength: number, uvs: ArrayLike<number>, light: Color, dark: Color, twoColor: boolean): void;
+		clip(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, clippingArea: Array<number>, output: Array<number>): boolean;
+		static makeClockwise(polygon: ArrayLike<number>): void;
+	}
+}
 declare module spine {
 	class SkeletonData {
 		name: string;
@@ -911,7 +954,7 @@ declare module spine {
 		private linkedMeshes;
 		constructor(attachmentLoader: AttachmentLoader);
 		readSkeletonData(json: string | any): SkeletonData;
-		readAttachment(map: any, skin: Skin, slotIndex: number, name: string): Attachment;
+		readAttachment(map: any, skin: Skin, slotIndex: number, name: string, skeletonData: SkeletonData): Attachment;
 		readVertices(map: any, attachment: VertexAttachment, verticesLength: number): void;
 		readAnimation(map: any, name: string, skeletonData: SkeletonData): void;
 		readCurve(map: any, timeline: CurveTimeline, frameIndex: number): void;
@@ -1089,6 +1132,7 @@ declare module spine {
 		static ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
 		static newArray<T>(size: number, defaultValue: T): Array<T>;
 		static newFloatArray(size: number): ArrayLike<number>;
+		static newShortArray(size: number): ArrayLike<number>;
 		static toFloatArray(array: Array<number>): number[] | Float32Array;
 	}
 	class DebugUtils {

+ 526 - 2
spine-ts/build/spine-canvas.js

@@ -2242,6 +2242,9 @@ var spine;
 		AtlasAttachmentLoader.prototype.newPointAttachment = function (skin, name) {
 			return new spine.PointAttachment(name);
 		};
+		AtlasAttachmentLoader.prototype.newClippingAttachment = function (skin, name) {
+			return new spine.ClippingAttachment(name);
+		};
 		return AtlasAttachmentLoader;
 	}());
 	spine.AtlasAttachmentLoader = AtlasAttachmentLoader;
@@ -2354,6 +2357,18 @@ var spine;
 	spine.BoundingBoxAttachment = BoundingBoxAttachment;
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var ClippingAttachment = (function (_super) {
+		__extends(ClippingAttachment, _super);
+		function ClippingAttachment(name) {
+			_super.call(this, name);
+			this.color = new spine.Color(0.2275, 0.2275, 0.8078, 1);
+		}
+		return ClippingAttachment;
+	}(spine.VertexAttachment));
+	spine.ClippingAttachment = ClippingAttachment;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var MeshAttachment = (function (_super) {
 		__extends(MeshAttachment, _super);
@@ -2897,6 +2912,207 @@ var spine;
 	var TransformMode = spine.TransformMode;
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var ConvexDecomposer = (function () {
+		function ConvexDecomposer() {
+			this.convexPolygons = new Array();
+			this.convexPolygonsIndices = new Array();
+			this.indicesArray = new Array();
+			this.isConcaveArray = new Array();
+			this.triangles = new Array();
+			this.polygonPool = new spine.Pool(function () {
+				return new Array();
+			});
+			this.polygonIndicesPool = new spine.Pool(function () {
+				return new Array();
+			});
+		}
+		ConvexDecomposer.prototype.decompose = function (input) {
+			var vertices = input;
+			var vertexCount = input.length >> 1;
+			var indices = this.indicesArray;
+			indices.length = 0;
+			for (var i = 0; i < vertexCount; i++)
+				indices[i] = i;
+			var isConcave = this.isConcaveArray;
+			isConcave.length = 0;
+			for (var i = 0, n = vertexCount; i < n; ++i)
+				isConcave[i] = ConvexDecomposer.isConcave(i, vertexCount, vertices, indices);
+			var triangles = this.triangles;
+			triangles.length = 0;
+			while (vertexCount > 3) {
+				var previous = vertexCount - 1, i = 0, next = 1;
+				while (true) {
+					outer: if (!isConcave[i]) {
+						var p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1;
+						var p1x = vertices[p1], p1y = vertices[p1 + 1];
+						var p2x = vertices[p2], p2y = vertices[p2 + 1];
+						var p3x = vertices[p3], p3y = vertices[p3 + 1];
+						for (var ii = (next + 1) % vertexCount; ii != previous; ii = (ii + 1) % vertexCount) {
+							if (!isConcave[ii])
+								continue;
+							var v = indices[ii] << 1;
+							var vx = vertices[v], vy = vertices[v + 1];
+							if (ConvexDecomposer.positiveArea(p3x, p3y, p1x, p1y, vx, vy)) {
+								if (ConvexDecomposer.positiveArea(p1x, p1y, p2x, p2y, vx, vy)) {
+									if (ConvexDecomposer.positiveArea(p2x, p2y, p3x, p3y, vx, vy))
+										break outer;
+								}
+							}
+						}
+						break;
+					}
+					if (next == 0) {
+						do {
+							if (!isConcave[i])
+								break;
+							i--;
+						} while (i > 0);
+						break;
+					}
+					previous = i;
+					i = next;
+					next = (next + 1) % vertexCount;
+				}
+				triangles.push(indices[(vertexCount + i - 1) % vertexCount]);
+				triangles.push(indices[i]);
+				triangles.push(indices[(i + 1) % vertexCount]);
+				indices.splice(i, 1);
+				isConcave.splice(i, 1);
+				vertexCount--;
+				var previousIndex = (vertexCount + i - 1) % vertexCount;
+				var nextIndex = i == vertexCount ? 0 : i;
+				isConcave[previousIndex] = ConvexDecomposer.isConcave(previousIndex, vertexCount, vertices, indices);
+				isConcave[nextIndex] = ConvexDecomposer.isConcave(nextIndex, vertexCount, vertices, indices);
+			}
+			if (vertexCount == 3) {
+				triangles.push(indices[2]);
+				triangles.push(indices[0]);
+				triangles.push(indices[1]);
+			}
+			var convexPolygons = this.convexPolygons;
+			this.polygonPool.freeAll(convexPolygons);
+			convexPolygons.length = 0;
+			var convexPolygonsIndices = this.convexPolygonsIndices;
+			this.polygonIndicesPool.freeAll(convexPolygonsIndices);
+			convexPolygonsIndices.length = 0;
+			var polygonIndices = this.polygonIndicesPool.obtain();
+			polygonIndices.length = 0;
+			var polygon = this.polygonPool.obtain();
+			polygon.length = 0;
+			var fanBaseIndex = -1, lastWinding = 0;
+			for (var i = 0, n = triangles.length; i < n; i += 3) {
+				var t1 = triangles[i] << 1, t2 = triangles[i + 1] << 1, t3 = triangles[i + 2] << 1;
+				var x1 = vertices[t1], y1 = vertices[t1 + 1];
+				var x2 = vertices[t2], y2 = vertices[t2 + 1];
+				var x3 = vertices[t3], y3 = vertices[t3 + 1];
+				var merged = false;
+				if (fanBaseIndex == t1) {
+					var o = polygon.length - 4;
+					var winding1 = ConvexDecomposer.winding(polygon[o], polygon[o + 1], polygon[o + 2], polygon[o + 3], x3, y3);
+					var winding2 = ConvexDecomposer.winding(x3, y3, polygon[0], polygon[1], polygon[2], polygon[3]);
+					if (winding1 == lastWinding && winding2 == lastWinding) {
+						polygon.push(x3);
+						polygon.push(y3);
+						polygonIndices.push(t3);
+						merged = true;
+					}
+				}
+				if (!merged) {
+					if (polygon.length > 0) {
+						convexPolygons.push(polygon);
+						convexPolygonsIndices.push(polygonIndices);
+					}
+					polygon = this.polygonPool.obtain();
+					polygon.length = 0;
+					polygon.push(x1);
+					polygon.push(y1);
+					polygon.push(x2);
+					polygon.push(y2);
+					polygon.push(x3);
+					polygon.push(y3);
+					polygonIndices = this.polygonIndicesPool.obtain();
+					polygonIndices.length = 0;
+					polygonIndices.push(t1);
+					polygonIndices.push(t2);
+					polygonIndices.push(t3);
+					lastWinding = ConvexDecomposer.winding(x1, y1, x2, y2, x3, y3);
+					fanBaseIndex = t1;
+				}
+			}
+			if (polygon.length > 0) {
+				convexPolygons.push(polygon);
+				convexPolygonsIndices.push(polygonIndices);
+			}
+			for (var i = 0, n = convexPolygons.length; i < n; i++) {
+				polygonIndices = convexPolygonsIndices[i];
+				if (polygonIndices.length == 0)
+					continue;
+				var firstIndex = polygonIndices[0];
+				var lastIndex = polygonIndices[polygonIndices.length - 1];
+				polygon = convexPolygons[i];
+				var o = polygon.length - 4;
+				var prevPrevX = polygon[o], prevPrevY = polygon[o + 1];
+				var prevX = polygon[o + 2], prevY = polygon[o + 3];
+				var firstX = polygon[0], firstY = polygon[1];
+				var secondX = polygon[2], secondY = polygon[3];
+				var winding = ConvexDecomposer.winding(prevPrevX, prevPrevY, prevX, prevY, firstX, firstY);
+				for (var ii = 0; ii < n; ii++) {
+					if (ii == i)
+						continue;
+					var otherIndices = convexPolygonsIndices[ii];
+					if (otherIndices.length != 3)
+						continue;
+					var otherFirstIndex = otherIndices[0];
+					var otherSecondIndex = otherIndices[1];
+					var otherLastIndex = otherIndices[2];
+					var otherPoly = convexPolygons[ii];
+					var x3 = otherPoly[otherPoly.length - 2], y3 = otherPoly[otherPoly.length - 1];
+					if (otherFirstIndex != firstIndex || otherSecondIndex != lastIndex)
+						continue;
+					var winding1 = ConvexDecomposer.winding(prevPrevX, prevPrevY, prevX, prevY, x3, y3);
+					var winding2 = ConvexDecomposer.winding(x3, y3, firstX, firstY, secondX, secondY);
+					if (winding1 == winding && winding2 == winding) {
+						otherPoly.length = 0;
+						otherIndices.length = 0;
+						polygon.push(x3);
+						polygon.push(y3);
+						polygonIndices.push(otherLastIndex);
+						prevPrevX = prevX;
+						prevPrevY = prevY;
+						prevX = x3;
+						prevY = y3;
+						ii = 0;
+					}
+				}
+			}
+			for (var i = convexPolygons.length - 1; i >= 0; i--) {
+				polygon = convexPolygons[i];
+				if (polygon.length == 0) {
+					convexPolygons.splice(i, 1);
+					this.polygonPool.free(polygon);
+				}
+			}
+			return convexPolygons;
+		};
+		ConvexDecomposer.isConcave = function (index, vertexCount, vertices, indices) {
+			var previous = indices[(vertexCount + index - 1) % vertexCount] << 1;
+			var current = indices[index] << 1;
+			var next = indices[(index + 1) % vertexCount] << 1;
+			return !this.positiveArea(vertices[previous], vertices[previous + 1], vertices[current], vertices[current + 1], vertices[next], vertices[next + 1]);
+		};
+		ConvexDecomposer.positiveArea = function (p1x, p1y, p2x, p2y, p3x, p3y) {
+			return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0;
+		};
+		ConvexDecomposer.winding = function (p1x, p1y, p2x, p2y, p3x, p3y) {
+			var px = p2x - p1x, py = p2y - p1y;
+			return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1;
+		};
+		return ConvexDecomposer;
+	}());
+	spine.ConvexDecomposer = ConvexDecomposer;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var Event = (function () {
 		function Event(time, data) {
@@ -4265,6 +4481,285 @@ var spine;
 	spine.SkeletonBounds = SkeletonBounds;
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var SkeletonClipping = (function () {
+		function SkeletonClipping() {
+			this.decomposer = new spine.ConvexDecomposer();
+			this.clippingPolygon = new Array();
+			this.clipOutput = new Array();
+			this.clippedVertices = new Array();
+			this.clippedTriangles = new Array();
+			this.scratch = new Array();
+		}
+		SkeletonClipping.prototype.clipStart = function (slot, clip) {
+			if (this.clipAttachment != null)
+				return;
+			this.clipAttachment = clip;
+			var n = clip.worldVerticesLength;
+			var vertices = spine.Utils.setArraySize(this.clippingPolygon, n);
+			clip.computeWorldVertices(slot, 0, n, vertices, 0, 2);
+			var clippingPolygon = this.clippingPolygon;
+			SkeletonClipping.makeClockwise(clippingPolygon);
+			var clippingPolygons = this.clippingPolygons = this.decomposer.decompose(clippingPolygon);
+			for (var i = 0, n_1 = clippingPolygons.length; i < n_1; i++) {
+				var polygon = clippingPolygons[i];
+				SkeletonClipping.makeClockwise(polygon);
+				polygon.push(polygon[0]);
+				polygon.push(polygon[1]);
+			}
+		};
+		SkeletonClipping.prototype.clipEndWithSlot = function (slot) {
+			if (this.clipAttachment != null && this.clipAttachment.endSlot == slot.data)
+				this.clipEnd();
+		};
+		SkeletonClipping.prototype.clipEnd = function () {
+			if (this.clipAttachment == null)
+				return;
+			this.clipAttachment = null;
+			this.clippingPolygons = null;
+			this.clippedVertices.length = 0;
+			this.clippedTriangles.length = 0;
+			this.clippingPolygon.length = 0;
+		};
+		SkeletonClipping.prototype.isClipping = function () {
+			return this.clipAttachment != null;
+		};
+		SkeletonClipping.prototype.clipTriangles = function (vertices, verticesLength, triangles, trianglesLength, uvs, light, dark, twoColor) {
+			var clipOutput = this.clipOutput, clippedVertices = this.clippedVertices;
+			var clippedTriangles = this.clippedTriangles;
+			var polygons = this.clippingPolygons;
+			var polygonsCount = this.clippingPolygons.length;
+			var vertexSize = twoColor ? 12 : 8;
+			var index = 0;
+			clippedVertices.length = 0;
+			clippedTriangles.length = 0;
+			outer: for (var i = 0; i < trianglesLength; i += 3) {
+				var vertexOffset = triangles[i] << 1;
+				var x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1];
+				var u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1];
+				vertexOffset = triangles[i + 1] << 1;
+				var x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1];
+				var u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1];
+				vertexOffset = triangles[i + 2] << 1;
+				var x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1];
+				var u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1];
+				for (var p = 0; p < polygonsCount; p++) {
+					var s = clippedVertices.length;
+					if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) {
+						var clipOutputLength = clipOutput.length;
+						if (clipOutputLength == 0)
+							continue;
+						var d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1;
+						var d = 1 / (d0 * d2 + d1 * (y1 - y3));
+						var clipOutputCount = clipOutputLength >> 1;
+						var clipOutputItems = this.clipOutput;
+						var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + clipOutputCount * vertexSize);
+						for (var ii = 0; ii < clipOutputLength; ii += 2) {
+							var x = clipOutputItems[ii], y = clipOutputItems[ii + 1];
+							clippedVerticesItems[s] = x;
+							clippedVerticesItems[s + 1] = y;
+							clippedVerticesItems[s + 2] = light.r;
+							clippedVerticesItems[s + 3] = light.g;
+							clippedVerticesItems[s + 4] = light.b;
+							clippedVerticesItems[s + 5] = light.a;
+							var c0 = x - x3, c1 = y - y3;
+							var a = (d0 * c0 + d1 * c1) * d;
+							var b = (d4 * c0 + d2 * c1) * d;
+							var c = 1 - a - b;
+							clippedVerticesItems[s + 6] = u1 * a + u2 * b + u3 * c;
+							clippedVerticesItems[s + 7] = v1 * a + v2 * b + v3 * c;
+							if (twoColor) {
+								clippedVerticesItems[s + 8] = dark.r;
+								clippedVerticesItems[s + 8] = dark.g;
+								clippedVerticesItems[s + 10] = dark.b;
+								clippedVerticesItems[s + 11] = dark.a;
+							}
+							s += vertexSize;
+						}
+						s = clippedTriangles.length;
+						var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2));
+						clipOutputCount--;
+						for (var ii = 1; ii < clipOutputCount; ii++) {
+							clippedTrianglesItems[s] = index;
+							clippedTrianglesItems[s + 1] = (index + ii);
+							clippedTrianglesItems[s + 2] = (index + ii + 1);
+							s += 3;
+						}
+						index += clipOutputCount + 1;
+					}
+					else {
+						var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + 3 * vertexSize);
+						clippedVerticesItems[s] = x1;
+						clippedVerticesItems[s + 1] = y1;
+						clippedVerticesItems[s + 2] = light.r;
+						clippedVerticesItems[s + 3] = light.g;
+						clippedVerticesItems[s + 4] = light.b;
+						clippedVerticesItems[s + 5] = light.a;
+						if (!twoColor) {
+							clippedVerticesItems[s + 6] = u1;
+							clippedVerticesItems[s + 7] = v1;
+							clippedVerticesItems[s + 8] = x2;
+							clippedVerticesItems[s + 9] = y2;
+							clippedVerticesItems[s + 10] = light.r;
+							clippedVerticesItems[s + 11] = light.g;
+							clippedVerticesItems[s + 12] = light.b;
+							clippedVerticesItems[s + 13] = light.a;
+							clippedVerticesItems[s + 14] = u2;
+							clippedVerticesItems[s + 15] = v2;
+							clippedVerticesItems[s + 16] = x3;
+							clippedVerticesItems[s + 17] = y3;
+							clippedVerticesItems[s + 18] = light.r;
+							clippedVerticesItems[s + 19] = light.g;
+							clippedVerticesItems[s + 20] = light.b;
+							clippedVerticesItems[s + 21] = light.a;
+							clippedVerticesItems[s + 22] = u3;
+							clippedVerticesItems[s + 23] = v3;
+						}
+						else {
+							clippedVerticesItems[s + 6] = u1;
+							clippedVerticesItems[s + 7] = v1;
+							clippedVerticesItems[s + 8] = dark.r;
+							clippedVerticesItems[s + 9] = dark.g;
+							clippedVerticesItems[s + 10] = dark.b;
+							clippedVerticesItems[s + 11] = dark.a;
+							clippedVerticesItems[s + 12] = x2;
+							clippedVerticesItems[s + 13] = y2;
+							clippedVerticesItems[s + 14] = light.r;
+							clippedVerticesItems[s + 15] = light.g;
+							clippedVerticesItems[s + 16] = light.b;
+							clippedVerticesItems[s + 17] = light.a;
+							clippedVerticesItems[s + 18] = u2;
+							clippedVerticesItems[s + 19] = v2;
+							clippedVerticesItems[s + 20] = dark.r;
+							clippedVerticesItems[s + 21] = dark.g;
+							clippedVerticesItems[s + 22] = dark.b;
+							clippedVerticesItems[s + 23] = dark.a;
+							clippedVerticesItems[s + 24] = x3;
+							clippedVerticesItems[s + 25] = y3;
+							clippedVerticesItems[s + 26] = light.r;
+							clippedVerticesItems[s + 27] = light.g;
+							clippedVerticesItems[s + 28] = light.b;
+							clippedVerticesItems[s + 29] = light.a;
+							clippedVerticesItems[s + 30] = u3;
+							clippedVerticesItems[s + 31] = v3;
+							clippedVerticesItems[s + 32] = dark.r;
+							clippedVerticesItems[s + 33] = dark.g;
+							clippedVerticesItems[s + 34] = dark.b;
+							clippedVerticesItems[s + 35] = dark.a;
+						}
+						s = clippedTriangles.length;
+						var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3);
+						clippedTrianglesItems[s] = index;
+						clippedTrianglesItems[s + 1] = (index + 1);
+						clippedTrianglesItems[s + 2] = (index + 2);
+						index += 3;
+						continue outer;
+					}
+				}
+			}
+		};
+		SkeletonClipping.prototype.clip = function (x1, y1, x2, y2, x3, y3, clippingArea, output) {
+			var originalOutput = output;
+			var clipped = false;
+			var input = null;
+			if (clippingArea.length % 4 >= 2) {
+				input = output;
+				output = this.scratch;
+			}
+			else
+				input = this.scratch;
+			input.length = 0;
+			input.push(x1);
+			input.push(y1);
+			input.push(x2);
+			input.push(y2);
+			input.push(x3);
+			input.push(y3);
+			input.push(x1);
+			input.push(y1);
+			output.length = 0;
+			var clippingVertices = clippingArea;
+			var clippingVerticesLast = clippingArea.length - 4;
+			for (var i = 0;; i += 2) {
+				var edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1];
+				var edgeX2 = clippingVertices[i + 2], edgeY2 = clippingVertices[i + 3];
+				var deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2;
+				var inputVertices = input;
+				var inputVerticesLength = input.length - 2, outputStart = output.length;
+				for (var ii = 0; ii < inputVerticesLength; ii += 2) {
+					var inputX = inputVertices[ii], inputY = inputVertices[ii + 1];
+					var inputX2 = inputVertices[ii + 2], inputY2 = inputVertices[ii + 3];
+					var side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0;
+					if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0) {
+						if (side2) {
+							output.push(inputX2);
+							output.push(inputY2);
+							continue;
+						}
+						var c0 = inputY2 - inputY, c2 = inputX2 - inputX;
+						var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
+						output.push(edgeX + (edgeX2 - edgeX) * ua);
+						output.push(edgeY + (edgeY2 - edgeY) * ua);
+					}
+					else if (side2) {
+						var c0 = inputY2 - inputY, c2 = inputX2 - inputX;
+						var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
+						output.push(edgeX + (edgeX2 - edgeX) * ua);
+						output.push(edgeY + (edgeY2 - edgeY) * ua);
+						output.push(inputX2);
+						output.push(inputY2);
+					}
+					clipped = true;
+				}
+				if (outputStart == output.length) {
+					originalOutput.length = 0;
+					return true;
+				}
+				output.push(output[0]);
+				output.push(output[1]);
+				if (i == clippingVerticesLast)
+					break;
+				var temp = output;
+				output = input;
+				output.length = 0;
+				input = temp;
+			}
+			if (originalOutput != output) {
+				originalOutput.length = 0;
+				for (var i = 0, n = output.length - 2; i < n; i++)
+					originalOutput[i] = output[i];
+			}
+			else
+				originalOutput.length = originalOutput.length - 2;
+			return clipped;
+		};
+		SkeletonClipping.makeClockwise = function (polygon) {
+			var vertices = polygon;
+			var verticeslength = polygon.length;
+			var area = vertices[verticeslength - 2] * vertices[1] - vertices[0] * vertices[verticeslength - 1], p1x = 0, p1y = 0, p2x = 0, p2y = 0;
+			for (var i = 0, n = verticeslength - 3; i < n; i += 2) {
+				p1x = vertices[i];
+				p1y = vertices[i + 1];
+				p2x = vertices[i + 2];
+				p2y = vertices[i + 3];
+				area += p1x * p2y - p2x * p1y;
+			}
+			if (area < 0)
+				return;
+			for (var i = 0, lastX = verticeslength - 2, n = verticeslength >> 1; i < n; i += 2) {
+				var x = vertices[i], y = vertices[i + 1];
+				var other = lastX - i;
+				vertices[i] = vertices[other];
+				vertices[i + 1] = vertices[other + 1];
+				vertices[other] = x;
+				vertices[other + 1] = y;
+			}
+		};
+		return SkeletonClipping;
+	}());
+	spine.SkeletonClipping = SkeletonClipping;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var SkeletonData = (function () {
 		function SkeletonData() {
@@ -4556,7 +5051,7 @@ var spine;
 							throw new Error("Slot not found: " + slotName);
 						var slotMap = skinMap[slotName];
 						for (var entryName in slotMap) {
-							var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName);
+							var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName, skeletonData);
 							if (attachment != null)
 								skin.addAttachment(slotIndex, entryName, attachment);
 						}
@@ -4596,7 +5091,7 @@ var spine;
 			}
 			return skeletonData;
 		};
-		SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name) {
+		SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name, skeletonData) {
 			var scale = this.scale;
 			name = this.getValue(map, "name", name);
 			var type = this.getValue(map, "type", "region");
@@ -4683,6 +5178,24 @@ var spine;
 						point.color.setFromString(color);
 					return point;
 				}
+				case "clipping": {
+					var clip = this.attachmentLoader.newClippingAttachment(skin, name);
+					if (clip == null)
+						return null;
+					var end = this.getValue(map, "end", null);
+					if (end != null) {
+						var slot = skeletonData.findSlot(end);
+						if (slot == null)
+							throw new Error("Clipping end slot not found: " + end);
+						clip.endSlot = slot;
+					}
+					var vertexCount = map.vertexCount;
+					this.readVertices(map, clip, vertexCount << 1);
+					var color = this.getValue(map, "color", null);
+					if (color != null)
+						clip.color.setFromString(color);
+					return clip;
+				}
 			}
 			return null;
 		};
@@ -5797,6 +6310,17 @@ var spine;
 				return array;
 			}
 		};
+		Utils.newShortArray = function (size) {
+			if (Utils.SUPPORTS_TYPED_ARRAYS) {
+				return new Int16Array(size);
+			}
+			else {
+				var array = new Array(size);
+				for (var i = 0; i < array.length; i++)
+					array[i] = 0;
+				return array;
+			}
+		};
 		Utils.toFloatArray = function (array) {
 			return Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array;
 		};

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
spine-ts/build/spine-canvas.js.map


+ 45 - 1
spine-ts/build/spine-core.d.ts

@@ -383,6 +383,7 @@ declare module spine {
 		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
 		newPathAttachment(skin: Skin, name: string): PathAttachment;
 		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
 	}
 }
 declare module spine {
@@ -406,6 +407,7 @@ declare module spine {
 		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
 		newPathAttachment(skin: Skin, name: string): PathAttachment;
 		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
 	}
 }
 declare module spine {
@@ -424,6 +426,13 @@ declare module spine {
 		constructor(name: string);
 	}
 }
+declare module spine {
+	class ClippingAttachment extends VertexAttachment {
+		endSlot: SlotData;
+		color: Color;
+		constructor(name: string);
+	}
+}
 declare module spine {
 	class MeshAttachment extends VertexAttachment {
 		region: TextureRegion;
@@ -607,6 +616,21 @@ declare module spine {
 		getOrder(): number;
 	}
 }
+declare module spine {
+	class ConvexDecomposer {
+		private convexPolygons;
+		private convexPolygonsIndices;
+		private indicesArray;
+		private isConcaveArray;
+		private triangles;
+		private polygonPool;
+		private polygonIndicesPool;
+		decompose(input: ArrayLike<number>): Array<Array<number>>;
+		private static isConcave(index, vertexCount, vertices, indices);
+		private static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y);
+		private static winding(p1x, p1y, p2x, p2y, p3x, p3y);
+	}
+}
 declare module spine {
 	class Event {
 		data: EventData;
@@ -802,6 +826,25 @@ declare module spine {
 		getHeight(): number;
 	}
 }
+declare module spine {
+	class SkeletonClipping {
+		private decomposer;
+		private clippingPolygon;
+		private clipOutput;
+		clippedVertices: number[];
+		clippedTriangles: number[];
+		private scratch;
+		private clipAttachment;
+		private clippingPolygons;
+		clipStart(slot: Slot, clip: ClippingAttachment): void;
+		clipEndWithSlot(slot: Slot): void;
+		clipEnd(): void;
+		isClipping(): boolean;
+		clipTriangles(vertices: ArrayLike<number>, verticesLength: number, triangles: ArrayLike<number>, trianglesLength: number, uvs: ArrayLike<number>, light: Color, dark: Color, twoColor: boolean): void;
+		clip(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, clippingArea: Array<number>, output: Array<number>): boolean;
+		static makeClockwise(polygon: ArrayLike<number>): void;
+	}
+}
 declare module spine {
 	class SkeletonData {
 		name: string;
@@ -840,7 +883,7 @@ declare module spine {
 		private linkedMeshes;
 		constructor(attachmentLoader: AttachmentLoader);
 		readSkeletonData(json: string | any): SkeletonData;
-		readAttachment(map: any, skin: Skin, slotIndex: number, name: string): Attachment;
+		readAttachment(map: any, skin: Skin, slotIndex: number, name: string, skeletonData: SkeletonData): Attachment;
 		readVertices(map: any, attachment: VertexAttachment, verticesLength: number): void;
 		readAnimation(map: any, name: string, skeletonData: SkeletonData): void;
 		readCurve(map: any, timeline: CurveTimeline, frameIndex: number): void;
@@ -1058,6 +1101,7 @@ declare module spine {
 		static ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
 		static newArray<T>(size: number, defaultValue: T): Array<T>;
 		static newFloatArray(size: number): ArrayLike<number>;
+		static newShortArray(size: number): ArrayLike<number>;
 		static toFloatArray(array: Array<number>): number[] | Float32Array;
 	}
 	class DebugUtils {

+ 526 - 2
spine-ts/build/spine-core.js

@@ -1922,6 +1922,9 @@ var spine;
 		AtlasAttachmentLoader.prototype.newPointAttachment = function (skin, name) {
 			return new spine.PointAttachment(name);
 		};
+		AtlasAttachmentLoader.prototype.newClippingAttachment = function (skin, name) {
+			return new spine.ClippingAttachment(name);
+		};
 		return AtlasAttachmentLoader;
 	}());
 	spine.AtlasAttachmentLoader = AtlasAttachmentLoader;
@@ -2034,6 +2037,18 @@ var spine;
 	spine.BoundingBoxAttachment = BoundingBoxAttachment;
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var ClippingAttachment = (function (_super) {
+		__extends(ClippingAttachment, _super);
+		function ClippingAttachment(name) {
+			_super.call(this, name);
+			this.color = new spine.Color(0.2275, 0.2275, 0.8078, 1);
+		}
+		return ClippingAttachment;
+	}(spine.VertexAttachment));
+	spine.ClippingAttachment = ClippingAttachment;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var MeshAttachment = (function (_super) {
 		__extends(MeshAttachment, _super);
@@ -2577,6 +2592,207 @@ var spine;
 	var TransformMode = spine.TransformMode;
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var ConvexDecomposer = (function () {
+		function ConvexDecomposer() {
+			this.convexPolygons = new Array();
+			this.convexPolygonsIndices = new Array();
+			this.indicesArray = new Array();
+			this.isConcaveArray = new Array();
+			this.triangles = new Array();
+			this.polygonPool = new spine.Pool(function () {
+				return new Array();
+			});
+			this.polygonIndicesPool = new spine.Pool(function () {
+				return new Array();
+			});
+		}
+		ConvexDecomposer.prototype.decompose = function (input) {
+			var vertices = input;
+			var vertexCount = input.length >> 1;
+			var indices = this.indicesArray;
+			indices.length = 0;
+			for (var i = 0; i < vertexCount; i++)
+				indices[i] = i;
+			var isConcave = this.isConcaveArray;
+			isConcave.length = 0;
+			for (var i = 0, n = vertexCount; i < n; ++i)
+				isConcave[i] = ConvexDecomposer.isConcave(i, vertexCount, vertices, indices);
+			var triangles = this.triangles;
+			triangles.length = 0;
+			while (vertexCount > 3) {
+				var previous = vertexCount - 1, i = 0, next = 1;
+				while (true) {
+					outer: if (!isConcave[i]) {
+						var p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1;
+						var p1x = vertices[p1], p1y = vertices[p1 + 1];
+						var p2x = vertices[p2], p2y = vertices[p2 + 1];
+						var p3x = vertices[p3], p3y = vertices[p3 + 1];
+						for (var ii = (next + 1) % vertexCount; ii != previous; ii = (ii + 1) % vertexCount) {
+							if (!isConcave[ii])
+								continue;
+							var v = indices[ii] << 1;
+							var vx = vertices[v], vy = vertices[v + 1];
+							if (ConvexDecomposer.positiveArea(p3x, p3y, p1x, p1y, vx, vy)) {
+								if (ConvexDecomposer.positiveArea(p1x, p1y, p2x, p2y, vx, vy)) {
+									if (ConvexDecomposer.positiveArea(p2x, p2y, p3x, p3y, vx, vy))
+										break outer;
+								}
+							}
+						}
+						break;
+					}
+					if (next == 0) {
+						do {
+							if (!isConcave[i])
+								break;
+							i--;
+						} while (i > 0);
+						break;
+					}
+					previous = i;
+					i = next;
+					next = (next + 1) % vertexCount;
+				}
+				triangles.push(indices[(vertexCount + i - 1) % vertexCount]);
+				triangles.push(indices[i]);
+				triangles.push(indices[(i + 1) % vertexCount]);
+				indices.splice(i, 1);
+				isConcave.splice(i, 1);
+				vertexCount--;
+				var previousIndex = (vertexCount + i - 1) % vertexCount;
+				var nextIndex = i == vertexCount ? 0 : i;
+				isConcave[previousIndex] = ConvexDecomposer.isConcave(previousIndex, vertexCount, vertices, indices);
+				isConcave[nextIndex] = ConvexDecomposer.isConcave(nextIndex, vertexCount, vertices, indices);
+			}
+			if (vertexCount == 3) {
+				triangles.push(indices[2]);
+				triangles.push(indices[0]);
+				triangles.push(indices[1]);
+			}
+			var convexPolygons = this.convexPolygons;
+			this.polygonPool.freeAll(convexPolygons);
+			convexPolygons.length = 0;
+			var convexPolygonsIndices = this.convexPolygonsIndices;
+			this.polygonIndicesPool.freeAll(convexPolygonsIndices);
+			convexPolygonsIndices.length = 0;
+			var polygonIndices = this.polygonIndicesPool.obtain();
+			polygonIndices.length = 0;
+			var polygon = this.polygonPool.obtain();
+			polygon.length = 0;
+			var fanBaseIndex = -1, lastWinding = 0;
+			for (var i = 0, n = triangles.length; i < n; i += 3) {
+				var t1 = triangles[i] << 1, t2 = triangles[i + 1] << 1, t3 = triangles[i + 2] << 1;
+				var x1 = vertices[t1], y1 = vertices[t1 + 1];
+				var x2 = vertices[t2], y2 = vertices[t2 + 1];
+				var x3 = vertices[t3], y3 = vertices[t3 + 1];
+				var merged = false;
+				if (fanBaseIndex == t1) {
+					var o = polygon.length - 4;
+					var winding1 = ConvexDecomposer.winding(polygon[o], polygon[o + 1], polygon[o + 2], polygon[o + 3], x3, y3);
+					var winding2 = ConvexDecomposer.winding(x3, y3, polygon[0], polygon[1], polygon[2], polygon[3]);
+					if (winding1 == lastWinding && winding2 == lastWinding) {
+						polygon.push(x3);
+						polygon.push(y3);
+						polygonIndices.push(t3);
+						merged = true;
+					}
+				}
+				if (!merged) {
+					if (polygon.length > 0) {
+						convexPolygons.push(polygon);
+						convexPolygonsIndices.push(polygonIndices);
+					}
+					polygon = this.polygonPool.obtain();
+					polygon.length = 0;
+					polygon.push(x1);
+					polygon.push(y1);
+					polygon.push(x2);
+					polygon.push(y2);
+					polygon.push(x3);
+					polygon.push(y3);
+					polygonIndices = this.polygonIndicesPool.obtain();
+					polygonIndices.length = 0;
+					polygonIndices.push(t1);
+					polygonIndices.push(t2);
+					polygonIndices.push(t3);
+					lastWinding = ConvexDecomposer.winding(x1, y1, x2, y2, x3, y3);
+					fanBaseIndex = t1;
+				}
+			}
+			if (polygon.length > 0) {
+				convexPolygons.push(polygon);
+				convexPolygonsIndices.push(polygonIndices);
+			}
+			for (var i = 0, n = convexPolygons.length; i < n; i++) {
+				polygonIndices = convexPolygonsIndices[i];
+				if (polygonIndices.length == 0)
+					continue;
+				var firstIndex = polygonIndices[0];
+				var lastIndex = polygonIndices[polygonIndices.length - 1];
+				polygon = convexPolygons[i];
+				var o = polygon.length - 4;
+				var prevPrevX = polygon[o], prevPrevY = polygon[o + 1];
+				var prevX = polygon[o + 2], prevY = polygon[o + 3];
+				var firstX = polygon[0], firstY = polygon[1];
+				var secondX = polygon[2], secondY = polygon[3];
+				var winding = ConvexDecomposer.winding(prevPrevX, prevPrevY, prevX, prevY, firstX, firstY);
+				for (var ii = 0; ii < n; ii++) {
+					if (ii == i)
+						continue;
+					var otherIndices = convexPolygonsIndices[ii];
+					if (otherIndices.length != 3)
+						continue;
+					var otherFirstIndex = otherIndices[0];
+					var otherSecondIndex = otherIndices[1];
+					var otherLastIndex = otherIndices[2];
+					var otherPoly = convexPolygons[ii];
+					var x3 = otherPoly[otherPoly.length - 2], y3 = otherPoly[otherPoly.length - 1];
+					if (otherFirstIndex != firstIndex || otherSecondIndex != lastIndex)
+						continue;
+					var winding1 = ConvexDecomposer.winding(prevPrevX, prevPrevY, prevX, prevY, x3, y3);
+					var winding2 = ConvexDecomposer.winding(x3, y3, firstX, firstY, secondX, secondY);
+					if (winding1 == winding && winding2 == winding) {
+						otherPoly.length = 0;
+						otherIndices.length = 0;
+						polygon.push(x3);
+						polygon.push(y3);
+						polygonIndices.push(otherLastIndex);
+						prevPrevX = prevX;
+						prevPrevY = prevY;
+						prevX = x3;
+						prevY = y3;
+						ii = 0;
+					}
+				}
+			}
+			for (var i = convexPolygons.length - 1; i >= 0; i--) {
+				polygon = convexPolygons[i];
+				if (polygon.length == 0) {
+					convexPolygons.splice(i, 1);
+					this.polygonPool.free(polygon);
+				}
+			}
+			return convexPolygons;
+		};
+		ConvexDecomposer.isConcave = function (index, vertexCount, vertices, indices) {
+			var previous = indices[(vertexCount + index - 1) % vertexCount] << 1;
+			var current = indices[index] << 1;
+			var next = indices[(index + 1) % vertexCount] << 1;
+			return !this.positiveArea(vertices[previous], vertices[previous + 1], vertices[current], vertices[current + 1], vertices[next], vertices[next + 1]);
+		};
+		ConvexDecomposer.positiveArea = function (p1x, p1y, p2x, p2y, p3x, p3y) {
+			return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0;
+		};
+		ConvexDecomposer.winding = function (p1x, p1y, p2x, p2y, p3x, p3y) {
+			var px = p2x - p1x, py = p2y - p1y;
+			return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1;
+		};
+		return ConvexDecomposer;
+	}());
+	spine.ConvexDecomposer = ConvexDecomposer;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var Event = (function () {
 		function Event(time, data) {
@@ -3945,6 +4161,285 @@ var spine;
 	spine.SkeletonBounds = SkeletonBounds;
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var SkeletonClipping = (function () {
+		function SkeletonClipping() {
+			this.decomposer = new spine.ConvexDecomposer();
+			this.clippingPolygon = new Array();
+			this.clipOutput = new Array();
+			this.clippedVertices = new Array();
+			this.clippedTriangles = new Array();
+			this.scratch = new Array();
+		}
+		SkeletonClipping.prototype.clipStart = function (slot, clip) {
+			if (this.clipAttachment != null)
+				return;
+			this.clipAttachment = clip;
+			var n = clip.worldVerticesLength;
+			var vertices = spine.Utils.setArraySize(this.clippingPolygon, n);
+			clip.computeWorldVertices(slot, 0, n, vertices, 0, 2);
+			var clippingPolygon = this.clippingPolygon;
+			SkeletonClipping.makeClockwise(clippingPolygon);
+			var clippingPolygons = this.clippingPolygons = this.decomposer.decompose(clippingPolygon);
+			for (var i = 0, n_1 = clippingPolygons.length; i < n_1; i++) {
+				var polygon = clippingPolygons[i];
+				SkeletonClipping.makeClockwise(polygon);
+				polygon.push(polygon[0]);
+				polygon.push(polygon[1]);
+			}
+		};
+		SkeletonClipping.prototype.clipEndWithSlot = function (slot) {
+			if (this.clipAttachment != null && this.clipAttachment.endSlot == slot.data)
+				this.clipEnd();
+		};
+		SkeletonClipping.prototype.clipEnd = function () {
+			if (this.clipAttachment == null)
+				return;
+			this.clipAttachment = null;
+			this.clippingPolygons = null;
+			this.clippedVertices.length = 0;
+			this.clippedTriangles.length = 0;
+			this.clippingPolygon.length = 0;
+		};
+		SkeletonClipping.prototype.isClipping = function () {
+			return this.clipAttachment != null;
+		};
+		SkeletonClipping.prototype.clipTriangles = function (vertices, verticesLength, triangles, trianglesLength, uvs, light, dark, twoColor) {
+			var clipOutput = this.clipOutput, clippedVertices = this.clippedVertices;
+			var clippedTriangles = this.clippedTriangles;
+			var polygons = this.clippingPolygons;
+			var polygonsCount = this.clippingPolygons.length;
+			var vertexSize = twoColor ? 12 : 8;
+			var index = 0;
+			clippedVertices.length = 0;
+			clippedTriangles.length = 0;
+			outer: for (var i = 0; i < trianglesLength; i += 3) {
+				var vertexOffset = triangles[i] << 1;
+				var x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1];
+				var u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1];
+				vertexOffset = triangles[i + 1] << 1;
+				var x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1];
+				var u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1];
+				vertexOffset = triangles[i + 2] << 1;
+				var x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1];
+				var u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1];
+				for (var p = 0; p < polygonsCount; p++) {
+					var s = clippedVertices.length;
+					if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) {
+						var clipOutputLength = clipOutput.length;
+						if (clipOutputLength == 0)
+							continue;
+						var d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1;
+						var d = 1 / (d0 * d2 + d1 * (y1 - y3));
+						var clipOutputCount = clipOutputLength >> 1;
+						var clipOutputItems = this.clipOutput;
+						var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + clipOutputCount * vertexSize);
+						for (var ii = 0; ii < clipOutputLength; ii += 2) {
+							var x = clipOutputItems[ii], y = clipOutputItems[ii + 1];
+							clippedVerticesItems[s] = x;
+							clippedVerticesItems[s + 1] = y;
+							clippedVerticesItems[s + 2] = light.r;
+							clippedVerticesItems[s + 3] = light.g;
+							clippedVerticesItems[s + 4] = light.b;
+							clippedVerticesItems[s + 5] = light.a;
+							var c0 = x - x3, c1 = y - y3;
+							var a = (d0 * c0 + d1 * c1) * d;
+							var b = (d4 * c0 + d2 * c1) * d;
+							var c = 1 - a - b;
+							clippedVerticesItems[s + 6] = u1 * a + u2 * b + u3 * c;
+							clippedVerticesItems[s + 7] = v1 * a + v2 * b + v3 * c;
+							if (twoColor) {
+								clippedVerticesItems[s + 8] = dark.r;
+								clippedVerticesItems[s + 8] = dark.g;
+								clippedVerticesItems[s + 10] = dark.b;
+								clippedVerticesItems[s + 11] = dark.a;
+							}
+							s += vertexSize;
+						}
+						s = clippedTriangles.length;
+						var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2));
+						clipOutputCount--;
+						for (var ii = 1; ii < clipOutputCount; ii++) {
+							clippedTrianglesItems[s] = index;
+							clippedTrianglesItems[s + 1] = (index + ii);
+							clippedTrianglesItems[s + 2] = (index + ii + 1);
+							s += 3;
+						}
+						index += clipOutputCount + 1;
+					}
+					else {
+						var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + 3 * vertexSize);
+						clippedVerticesItems[s] = x1;
+						clippedVerticesItems[s + 1] = y1;
+						clippedVerticesItems[s + 2] = light.r;
+						clippedVerticesItems[s + 3] = light.g;
+						clippedVerticesItems[s + 4] = light.b;
+						clippedVerticesItems[s + 5] = light.a;
+						if (!twoColor) {
+							clippedVerticesItems[s + 6] = u1;
+							clippedVerticesItems[s + 7] = v1;
+							clippedVerticesItems[s + 8] = x2;
+							clippedVerticesItems[s + 9] = y2;
+							clippedVerticesItems[s + 10] = light.r;
+							clippedVerticesItems[s + 11] = light.g;
+							clippedVerticesItems[s + 12] = light.b;
+							clippedVerticesItems[s + 13] = light.a;
+							clippedVerticesItems[s + 14] = u2;
+							clippedVerticesItems[s + 15] = v2;
+							clippedVerticesItems[s + 16] = x3;
+							clippedVerticesItems[s + 17] = y3;
+							clippedVerticesItems[s + 18] = light.r;
+							clippedVerticesItems[s + 19] = light.g;
+							clippedVerticesItems[s + 20] = light.b;
+							clippedVerticesItems[s + 21] = light.a;
+							clippedVerticesItems[s + 22] = u3;
+							clippedVerticesItems[s + 23] = v3;
+						}
+						else {
+							clippedVerticesItems[s + 6] = u1;
+							clippedVerticesItems[s + 7] = v1;
+							clippedVerticesItems[s + 8] = dark.r;
+							clippedVerticesItems[s + 9] = dark.g;
+							clippedVerticesItems[s + 10] = dark.b;
+							clippedVerticesItems[s + 11] = dark.a;
+							clippedVerticesItems[s + 12] = x2;
+							clippedVerticesItems[s + 13] = y2;
+							clippedVerticesItems[s + 14] = light.r;
+							clippedVerticesItems[s + 15] = light.g;
+							clippedVerticesItems[s + 16] = light.b;
+							clippedVerticesItems[s + 17] = light.a;
+							clippedVerticesItems[s + 18] = u2;
+							clippedVerticesItems[s + 19] = v2;
+							clippedVerticesItems[s + 20] = dark.r;
+							clippedVerticesItems[s + 21] = dark.g;
+							clippedVerticesItems[s + 22] = dark.b;
+							clippedVerticesItems[s + 23] = dark.a;
+							clippedVerticesItems[s + 24] = x3;
+							clippedVerticesItems[s + 25] = y3;
+							clippedVerticesItems[s + 26] = light.r;
+							clippedVerticesItems[s + 27] = light.g;
+							clippedVerticesItems[s + 28] = light.b;
+							clippedVerticesItems[s + 29] = light.a;
+							clippedVerticesItems[s + 30] = u3;
+							clippedVerticesItems[s + 31] = v3;
+							clippedVerticesItems[s + 32] = dark.r;
+							clippedVerticesItems[s + 33] = dark.g;
+							clippedVerticesItems[s + 34] = dark.b;
+							clippedVerticesItems[s + 35] = dark.a;
+						}
+						s = clippedTriangles.length;
+						var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3);
+						clippedTrianglesItems[s] = index;
+						clippedTrianglesItems[s + 1] = (index + 1);
+						clippedTrianglesItems[s + 2] = (index + 2);
+						index += 3;
+						continue outer;
+					}
+				}
+			}
+		};
+		SkeletonClipping.prototype.clip = function (x1, y1, x2, y2, x3, y3, clippingArea, output) {
+			var originalOutput = output;
+			var clipped = false;
+			var input = null;
+			if (clippingArea.length % 4 >= 2) {
+				input = output;
+				output = this.scratch;
+			}
+			else
+				input = this.scratch;
+			input.length = 0;
+			input.push(x1);
+			input.push(y1);
+			input.push(x2);
+			input.push(y2);
+			input.push(x3);
+			input.push(y3);
+			input.push(x1);
+			input.push(y1);
+			output.length = 0;
+			var clippingVertices = clippingArea;
+			var clippingVerticesLast = clippingArea.length - 4;
+			for (var i = 0;; i += 2) {
+				var edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1];
+				var edgeX2 = clippingVertices[i + 2], edgeY2 = clippingVertices[i + 3];
+				var deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2;
+				var inputVertices = input;
+				var inputVerticesLength = input.length - 2, outputStart = output.length;
+				for (var ii = 0; ii < inputVerticesLength; ii += 2) {
+					var inputX = inputVertices[ii], inputY = inputVertices[ii + 1];
+					var inputX2 = inputVertices[ii + 2], inputY2 = inputVertices[ii + 3];
+					var side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0;
+					if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0) {
+						if (side2) {
+							output.push(inputX2);
+							output.push(inputY2);
+							continue;
+						}
+						var c0 = inputY2 - inputY, c2 = inputX2 - inputX;
+						var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
+						output.push(edgeX + (edgeX2 - edgeX) * ua);
+						output.push(edgeY + (edgeY2 - edgeY) * ua);
+					}
+					else if (side2) {
+						var c0 = inputY2 - inputY, c2 = inputX2 - inputX;
+						var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
+						output.push(edgeX + (edgeX2 - edgeX) * ua);
+						output.push(edgeY + (edgeY2 - edgeY) * ua);
+						output.push(inputX2);
+						output.push(inputY2);
+					}
+					clipped = true;
+				}
+				if (outputStart == output.length) {
+					originalOutput.length = 0;
+					return true;
+				}
+				output.push(output[0]);
+				output.push(output[1]);
+				if (i == clippingVerticesLast)
+					break;
+				var temp = output;
+				output = input;
+				output.length = 0;
+				input = temp;
+			}
+			if (originalOutput != output) {
+				originalOutput.length = 0;
+				for (var i = 0, n = output.length - 2; i < n; i++)
+					originalOutput[i] = output[i];
+			}
+			else
+				originalOutput.length = originalOutput.length - 2;
+			return clipped;
+		};
+		SkeletonClipping.makeClockwise = function (polygon) {
+			var vertices = polygon;
+			var verticeslength = polygon.length;
+			var area = vertices[verticeslength - 2] * vertices[1] - vertices[0] * vertices[verticeslength - 1], p1x = 0, p1y = 0, p2x = 0, p2y = 0;
+			for (var i = 0, n = verticeslength - 3; i < n; i += 2) {
+				p1x = vertices[i];
+				p1y = vertices[i + 1];
+				p2x = vertices[i + 2];
+				p2y = vertices[i + 3];
+				area += p1x * p2y - p2x * p1y;
+			}
+			if (area < 0)
+				return;
+			for (var i = 0, lastX = verticeslength - 2, n = verticeslength >> 1; i < n; i += 2) {
+				var x = vertices[i], y = vertices[i + 1];
+				var other = lastX - i;
+				vertices[i] = vertices[other];
+				vertices[i + 1] = vertices[other + 1];
+				vertices[other] = x;
+				vertices[other + 1] = y;
+			}
+		};
+		return SkeletonClipping;
+	}());
+	spine.SkeletonClipping = SkeletonClipping;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var SkeletonData = (function () {
 		function SkeletonData() {
@@ -4236,7 +4731,7 @@ var spine;
 							throw new Error("Slot not found: " + slotName);
 						var slotMap = skinMap[slotName];
 						for (var entryName in slotMap) {
-							var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName);
+							var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName, skeletonData);
 							if (attachment != null)
 								skin.addAttachment(slotIndex, entryName, attachment);
 						}
@@ -4276,7 +4771,7 @@ var spine;
 			}
 			return skeletonData;
 		};
-		SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name) {
+		SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name, skeletonData) {
 			var scale = this.scale;
 			name = this.getValue(map, "name", name);
 			var type = this.getValue(map, "type", "region");
@@ -4363,6 +4858,24 @@ var spine;
 						point.color.setFromString(color);
 					return point;
 				}
+				case "clipping": {
+					var clip = this.attachmentLoader.newClippingAttachment(skin, name);
+					if (clip == null)
+						return null;
+					var end = this.getValue(map, "end", null);
+					if (end != null) {
+						var slot = skeletonData.findSlot(end);
+						if (slot == null)
+							throw new Error("Clipping end slot not found: " + end);
+						clip.endSlot = slot;
+					}
+					var vertexCount = map.vertexCount;
+					this.readVertices(map, clip, vertexCount << 1);
+					var color = this.getValue(map, "color", null);
+					if (color != null)
+						clip.color.setFromString(color);
+					return clip;
+				}
 			}
 			return null;
 		};
@@ -5543,6 +6056,17 @@ var spine;
 				return array;
 			}
 		};
+		Utils.newShortArray = function (size) {
+			if (Utils.SUPPORTS_TYPED_ARRAYS) {
+				return new Int16Array(size);
+			}
+			else {
+				var array = new Array(size);
+				for (var i = 0; i < array.length; i++)
+					array[i] = 0;
+				return array;
+			}
+		};
 		Utils.toFloatArray = function (array) {
 			return Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array;
 		};

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
spine-ts/build/spine-core.js.map


+ 45 - 1
spine-ts/build/spine-threejs.d.ts

@@ -383,6 +383,7 @@ declare module spine {
 		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
 		newPathAttachment(skin: Skin, name: string): PathAttachment;
 		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
 	}
 }
 declare module spine {
@@ -406,6 +407,7 @@ declare module spine {
 		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
 		newPathAttachment(skin: Skin, name: string): PathAttachment;
 		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
 	}
 }
 declare module spine {
@@ -424,6 +426,13 @@ declare module spine {
 		constructor(name: string);
 	}
 }
+declare module spine {
+	class ClippingAttachment extends VertexAttachment {
+		endSlot: SlotData;
+		color: Color;
+		constructor(name: string);
+	}
+}
 declare module spine {
 	class MeshAttachment extends VertexAttachment {
 		region: TextureRegion;
@@ -607,6 +616,21 @@ declare module spine {
 		getOrder(): number;
 	}
 }
+declare module spine {
+	class ConvexDecomposer {
+		private convexPolygons;
+		private convexPolygonsIndices;
+		private indicesArray;
+		private isConcaveArray;
+		private triangles;
+		private polygonPool;
+		private polygonIndicesPool;
+		decompose(input: ArrayLike<number>): Array<Array<number>>;
+		private static isConcave(index, vertexCount, vertices, indices);
+		private static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y);
+		private static winding(p1x, p1y, p2x, p2y, p3x, p3y);
+	}
+}
 declare module spine {
 	class Event {
 		data: EventData;
@@ -802,6 +826,25 @@ declare module spine {
 		getHeight(): number;
 	}
 }
+declare module spine {
+	class SkeletonClipping {
+		private decomposer;
+		private clippingPolygon;
+		private clipOutput;
+		clippedVertices: number[];
+		clippedTriangles: number[];
+		private scratch;
+		private clipAttachment;
+		private clippingPolygons;
+		clipStart(slot: Slot, clip: ClippingAttachment): void;
+		clipEndWithSlot(slot: Slot): void;
+		clipEnd(): void;
+		isClipping(): boolean;
+		clipTriangles(vertices: ArrayLike<number>, verticesLength: number, triangles: ArrayLike<number>, trianglesLength: number, uvs: ArrayLike<number>, light: Color, dark: Color, twoColor: boolean): void;
+		clip(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, clippingArea: Array<number>, output: Array<number>): boolean;
+		static makeClockwise(polygon: ArrayLike<number>): void;
+	}
+}
 declare module spine {
 	class SkeletonData {
 		name: string;
@@ -840,7 +883,7 @@ declare module spine {
 		private linkedMeshes;
 		constructor(attachmentLoader: AttachmentLoader);
 		readSkeletonData(json: string | any): SkeletonData;
-		readAttachment(map: any, skin: Skin, slotIndex: number, name: string): Attachment;
+		readAttachment(map: any, skin: Skin, slotIndex: number, name: string, skeletonData: SkeletonData): Attachment;
 		readVertices(map: any, attachment: VertexAttachment, verticesLength: number): void;
 		readAnimation(map: any, name: string, skeletonData: SkeletonData): void;
 		readCurve(map: any, timeline: CurveTimeline, frameIndex: number): void;
@@ -1058,6 +1101,7 @@ declare module spine {
 		static ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
 		static newArray<T>(size: number, defaultValue: T): Array<T>;
 		static newFloatArray(size: number): ArrayLike<number>;
+		static newShortArray(size: number): ArrayLike<number>;
 		static toFloatArray(array: Array<number>): number[] | Float32Array;
 	}
 	class DebugUtils {

+ 526 - 2
spine-ts/build/spine-threejs.js

@@ -1922,6 +1922,9 @@ var spine;
 		AtlasAttachmentLoader.prototype.newPointAttachment = function (skin, name) {
 			return new spine.PointAttachment(name);
 		};
+		AtlasAttachmentLoader.prototype.newClippingAttachment = function (skin, name) {
+			return new spine.ClippingAttachment(name);
+		};
 		return AtlasAttachmentLoader;
 	}());
 	spine.AtlasAttachmentLoader = AtlasAttachmentLoader;
@@ -2034,6 +2037,18 @@ var spine;
 	spine.BoundingBoxAttachment = BoundingBoxAttachment;
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var ClippingAttachment = (function (_super) {
+		__extends(ClippingAttachment, _super);
+		function ClippingAttachment(name) {
+			_super.call(this, name);
+			this.color = new spine.Color(0.2275, 0.2275, 0.8078, 1);
+		}
+		return ClippingAttachment;
+	}(spine.VertexAttachment));
+	spine.ClippingAttachment = ClippingAttachment;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var MeshAttachment = (function (_super) {
 		__extends(MeshAttachment, _super);
@@ -2577,6 +2592,207 @@ var spine;
 	var TransformMode = spine.TransformMode;
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var ConvexDecomposer = (function () {
+		function ConvexDecomposer() {
+			this.convexPolygons = new Array();
+			this.convexPolygonsIndices = new Array();
+			this.indicesArray = new Array();
+			this.isConcaveArray = new Array();
+			this.triangles = new Array();
+			this.polygonPool = new spine.Pool(function () {
+				return new Array();
+			});
+			this.polygonIndicesPool = new spine.Pool(function () {
+				return new Array();
+			});
+		}
+		ConvexDecomposer.prototype.decompose = function (input) {
+			var vertices = input;
+			var vertexCount = input.length >> 1;
+			var indices = this.indicesArray;
+			indices.length = 0;
+			for (var i = 0; i < vertexCount; i++)
+				indices[i] = i;
+			var isConcave = this.isConcaveArray;
+			isConcave.length = 0;
+			for (var i = 0, n = vertexCount; i < n; ++i)
+				isConcave[i] = ConvexDecomposer.isConcave(i, vertexCount, vertices, indices);
+			var triangles = this.triangles;
+			triangles.length = 0;
+			while (vertexCount > 3) {
+				var previous = vertexCount - 1, i = 0, next = 1;
+				while (true) {
+					outer: if (!isConcave[i]) {
+						var p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1;
+						var p1x = vertices[p1], p1y = vertices[p1 + 1];
+						var p2x = vertices[p2], p2y = vertices[p2 + 1];
+						var p3x = vertices[p3], p3y = vertices[p3 + 1];
+						for (var ii = (next + 1) % vertexCount; ii != previous; ii = (ii + 1) % vertexCount) {
+							if (!isConcave[ii])
+								continue;
+							var v = indices[ii] << 1;
+							var vx = vertices[v], vy = vertices[v + 1];
+							if (ConvexDecomposer.positiveArea(p3x, p3y, p1x, p1y, vx, vy)) {
+								if (ConvexDecomposer.positiveArea(p1x, p1y, p2x, p2y, vx, vy)) {
+									if (ConvexDecomposer.positiveArea(p2x, p2y, p3x, p3y, vx, vy))
+										break outer;
+								}
+							}
+						}
+						break;
+					}
+					if (next == 0) {
+						do {
+							if (!isConcave[i])
+								break;
+							i--;
+						} while (i > 0);
+						break;
+					}
+					previous = i;
+					i = next;
+					next = (next + 1) % vertexCount;
+				}
+				triangles.push(indices[(vertexCount + i - 1) % vertexCount]);
+				triangles.push(indices[i]);
+				triangles.push(indices[(i + 1) % vertexCount]);
+				indices.splice(i, 1);
+				isConcave.splice(i, 1);
+				vertexCount--;
+				var previousIndex = (vertexCount + i - 1) % vertexCount;
+				var nextIndex = i == vertexCount ? 0 : i;
+				isConcave[previousIndex] = ConvexDecomposer.isConcave(previousIndex, vertexCount, vertices, indices);
+				isConcave[nextIndex] = ConvexDecomposer.isConcave(nextIndex, vertexCount, vertices, indices);
+			}
+			if (vertexCount == 3) {
+				triangles.push(indices[2]);
+				triangles.push(indices[0]);
+				triangles.push(indices[1]);
+			}
+			var convexPolygons = this.convexPolygons;
+			this.polygonPool.freeAll(convexPolygons);
+			convexPolygons.length = 0;
+			var convexPolygonsIndices = this.convexPolygonsIndices;
+			this.polygonIndicesPool.freeAll(convexPolygonsIndices);
+			convexPolygonsIndices.length = 0;
+			var polygonIndices = this.polygonIndicesPool.obtain();
+			polygonIndices.length = 0;
+			var polygon = this.polygonPool.obtain();
+			polygon.length = 0;
+			var fanBaseIndex = -1, lastWinding = 0;
+			for (var i = 0, n = triangles.length; i < n; i += 3) {
+				var t1 = triangles[i] << 1, t2 = triangles[i + 1] << 1, t3 = triangles[i + 2] << 1;
+				var x1 = vertices[t1], y1 = vertices[t1 + 1];
+				var x2 = vertices[t2], y2 = vertices[t2 + 1];
+				var x3 = vertices[t3], y3 = vertices[t3 + 1];
+				var merged = false;
+				if (fanBaseIndex == t1) {
+					var o = polygon.length - 4;
+					var winding1 = ConvexDecomposer.winding(polygon[o], polygon[o + 1], polygon[o + 2], polygon[o + 3], x3, y3);
+					var winding2 = ConvexDecomposer.winding(x3, y3, polygon[0], polygon[1], polygon[2], polygon[3]);
+					if (winding1 == lastWinding && winding2 == lastWinding) {
+						polygon.push(x3);
+						polygon.push(y3);
+						polygonIndices.push(t3);
+						merged = true;
+					}
+				}
+				if (!merged) {
+					if (polygon.length > 0) {
+						convexPolygons.push(polygon);
+						convexPolygonsIndices.push(polygonIndices);
+					}
+					polygon = this.polygonPool.obtain();
+					polygon.length = 0;
+					polygon.push(x1);
+					polygon.push(y1);
+					polygon.push(x2);
+					polygon.push(y2);
+					polygon.push(x3);
+					polygon.push(y3);
+					polygonIndices = this.polygonIndicesPool.obtain();
+					polygonIndices.length = 0;
+					polygonIndices.push(t1);
+					polygonIndices.push(t2);
+					polygonIndices.push(t3);
+					lastWinding = ConvexDecomposer.winding(x1, y1, x2, y2, x3, y3);
+					fanBaseIndex = t1;
+				}
+			}
+			if (polygon.length > 0) {
+				convexPolygons.push(polygon);
+				convexPolygonsIndices.push(polygonIndices);
+			}
+			for (var i = 0, n = convexPolygons.length; i < n; i++) {
+				polygonIndices = convexPolygonsIndices[i];
+				if (polygonIndices.length == 0)
+					continue;
+				var firstIndex = polygonIndices[0];
+				var lastIndex = polygonIndices[polygonIndices.length - 1];
+				polygon = convexPolygons[i];
+				var o = polygon.length - 4;
+				var prevPrevX = polygon[o], prevPrevY = polygon[o + 1];
+				var prevX = polygon[o + 2], prevY = polygon[o + 3];
+				var firstX = polygon[0], firstY = polygon[1];
+				var secondX = polygon[2], secondY = polygon[3];
+				var winding = ConvexDecomposer.winding(prevPrevX, prevPrevY, prevX, prevY, firstX, firstY);
+				for (var ii = 0; ii < n; ii++) {
+					if (ii == i)
+						continue;
+					var otherIndices = convexPolygonsIndices[ii];
+					if (otherIndices.length != 3)
+						continue;
+					var otherFirstIndex = otherIndices[0];
+					var otherSecondIndex = otherIndices[1];
+					var otherLastIndex = otherIndices[2];
+					var otherPoly = convexPolygons[ii];
+					var x3 = otherPoly[otherPoly.length - 2], y3 = otherPoly[otherPoly.length - 1];
+					if (otherFirstIndex != firstIndex || otherSecondIndex != lastIndex)
+						continue;
+					var winding1 = ConvexDecomposer.winding(prevPrevX, prevPrevY, prevX, prevY, x3, y3);
+					var winding2 = ConvexDecomposer.winding(x3, y3, firstX, firstY, secondX, secondY);
+					if (winding1 == winding && winding2 == winding) {
+						otherPoly.length = 0;
+						otherIndices.length = 0;
+						polygon.push(x3);
+						polygon.push(y3);
+						polygonIndices.push(otherLastIndex);
+						prevPrevX = prevX;
+						prevPrevY = prevY;
+						prevX = x3;
+						prevY = y3;
+						ii = 0;
+					}
+				}
+			}
+			for (var i = convexPolygons.length - 1; i >= 0; i--) {
+				polygon = convexPolygons[i];
+				if (polygon.length == 0) {
+					convexPolygons.splice(i, 1);
+					this.polygonPool.free(polygon);
+				}
+			}
+			return convexPolygons;
+		};
+		ConvexDecomposer.isConcave = function (index, vertexCount, vertices, indices) {
+			var previous = indices[(vertexCount + index - 1) % vertexCount] << 1;
+			var current = indices[index] << 1;
+			var next = indices[(index + 1) % vertexCount] << 1;
+			return !this.positiveArea(vertices[previous], vertices[previous + 1], vertices[current], vertices[current + 1], vertices[next], vertices[next + 1]);
+		};
+		ConvexDecomposer.positiveArea = function (p1x, p1y, p2x, p2y, p3x, p3y) {
+			return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0;
+		};
+		ConvexDecomposer.winding = function (p1x, p1y, p2x, p2y, p3x, p3y) {
+			var px = p2x - p1x, py = p2y - p1y;
+			return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1;
+		};
+		return ConvexDecomposer;
+	}());
+	spine.ConvexDecomposer = ConvexDecomposer;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var Event = (function () {
 		function Event(time, data) {
@@ -3945,6 +4161,285 @@ var spine;
 	spine.SkeletonBounds = SkeletonBounds;
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var SkeletonClipping = (function () {
+		function SkeletonClipping() {
+			this.decomposer = new spine.ConvexDecomposer();
+			this.clippingPolygon = new Array();
+			this.clipOutput = new Array();
+			this.clippedVertices = new Array();
+			this.clippedTriangles = new Array();
+			this.scratch = new Array();
+		}
+		SkeletonClipping.prototype.clipStart = function (slot, clip) {
+			if (this.clipAttachment != null)
+				return;
+			this.clipAttachment = clip;
+			var n = clip.worldVerticesLength;
+			var vertices = spine.Utils.setArraySize(this.clippingPolygon, n);
+			clip.computeWorldVertices(slot, 0, n, vertices, 0, 2);
+			var clippingPolygon = this.clippingPolygon;
+			SkeletonClipping.makeClockwise(clippingPolygon);
+			var clippingPolygons = this.clippingPolygons = this.decomposer.decompose(clippingPolygon);
+			for (var i = 0, n_1 = clippingPolygons.length; i < n_1; i++) {
+				var polygon = clippingPolygons[i];
+				SkeletonClipping.makeClockwise(polygon);
+				polygon.push(polygon[0]);
+				polygon.push(polygon[1]);
+			}
+		};
+		SkeletonClipping.prototype.clipEndWithSlot = function (slot) {
+			if (this.clipAttachment != null && this.clipAttachment.endSlot == slot.data)
+				this.clipEnd();
+		};
+		SkeletonClipping.prototype.clipEnd = function () {
+			if (this.clipAttachment == null)
+				return;
+			this.clipAttachment = null;
+			this.clippingPolygons = null;
+			this.clippedVertices.length = 0;
+			this.clippedTriangles.length = 0;
+			this.clippingPolygon.length = 0;
+		};
+		SkeletonClipping.prototype.isClipping = function () {
+			return this.clipAttachment != null;
+		};
+		SkeletonClipping.prototype.clipTriangles = function (vertices, verticesLength, triangles, trianglesLength, uvs, light, dark, twoColor) {
+			var clipOutput = this.clipOutput, clippedVertices = this.clippedVertices;
+			var clippedTriangles = this.clippedTriangles;
+			var polygons = this.clippingPolygons;
+			var polygonsCount = this.clippingPolygons.length;
+			var vertexSize = twoColor ? 12 : 8;
+			var index = 0;
+			clippedVertices.length = 0;
+			clippedTriangles.length = 0;
+			outer: for (var i = 0; i < trianglesLength; i += 3) {
+				var vertexOffset = triangles[i] << 1;
+				var x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1];
+				var u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1];
+				vertexOffset = triangles[i + 1] << 1;
+				var x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1];
+				var u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1];
+				vertexOffset = triangles[i + 2] << 1;
+				var x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1];
+				var u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1];
+				for (var p = 0; p < polygonsCount; p++) {
+					var s = clippedVertices.length;
+					if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) {
+						var clipOutputLength = clipOutput.length;
+						if (clipOutputLength == 0)
+							continue;
+						var d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1;
+						var d = 1 / (d0 * d2 + d1 * (y1 - y3));
+						var clipOutputCount = clipOutputLength >> 1;
+						var clipOutputItems = this.clipOutput;
+						var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + clipOutputCount * vertexSize);
+						for (var ii = 0; ii < clipOutputLength; ii += 2) {
+							var x = clipOutputItems[ii], y = clipOutputItems[ii + 1];
+							clippedVerticesItems[s] = x;
+							clippedVerticesItems[s + 1] = y;
+							clippedVerticesItems[s + 2] = light.r;
+							clippedVerticesItems[s + 3] = light.g;
+							clippedVerticesItems[s + 4] = light.b;
+							clippedVerticesItems[s + 5] = light.a;
+							var c0 = x - x3, c1 = y - y3;
+							var a = (d0 * c0 + d1 * c1) * d;
+							var b = (d4 * c0 + d2 * c1) * d;
+							var c = 1 - a - b;
+							clippedVerticesItems[s + 6] = u1 * a + u2 * b + u3 * c;
+							clippedVerticesItems[s + 7] = v1 * a + v2 * b + v3 * c;
+							if (twoColor) {
+								clippedVerticesItems[s + 8] = dark.r;
+								clippedVerticesItems[s + 8] = dark.g;
+								clippedVerticesItems[s + 10] = dark.b;
+								clippedVerticesItems[s + 11] = dark.a;
+							}
+							s += vertexSize;
+						}
+						s = clippedTriangles.length;
+						var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2));
+						clipOutputCount--;
+						for (var ii = 1; ii < clipOutputCount; ii++) {
+							clippedTrianglesItems[s] = index;
+							clippedTrianglesItems[s + 1] = (index + ii);
+							clippedTrianglesItems[s + 2] = (index + ii + 1);
+							s += 3;
+						}
+						index += clipOutputCount + 1;
+					}
+					else {
+						var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + 3 * vertexSize);
+						clippedVerticesItems[s] = x1;
+						clippedVerticesItems[s + 1] = y1;
+						clippedVerticesItems[s + 2] = light.r;
+						clippedVerticesItems[s + 3] = light.g;
+						clippedVerticesItems[s + 4] = light.b;
+						clippedVerticesItems[s + 5] = light.a;
+						if (!twoColor) {
+							clippedVerticesItems[s + 6] = u1;
+							clippedVerticesItems[s + 7] = v1;
+							clippedVerticesItems[s + 8] = x2;
+							clippedVerticesItems[s + 9] = y2;
+							clippedVerticesItems[s + 10] = light.r;
+							clippedVerticesItems[s + 11] = light.g;
+							clippedVerticesItems[s + 12] = light.b;
+							clippedVerticesItems[s + 13] = light.a;
+							clippedVerticesItems[s + 14] = u2;
+							clippedVerticesItems[s + 15] = v2;
+							clippedVerticesItems[s + 16] = x3;
+							clippedVerticesItems[s + 17] = y3;
+							clippedVerticesItems[s + 18] = light.r;
+							clippedVerticesItems[s + 19] = light.g;
+							clippedVerticesItems[s + 20] = light.b;
+							clippedVerticesItems[s + 21] = light.a;
+							clippedVerticesItems[s + 22] = u3;
+							clippedVerticesItems[s + 23] = v3;
+						}
+						else {
+							clippedVerticesItems[s + 6] = u1;
+							clippedVerticesItems[s + 7] = v1;
+							clippedVerticesItems[s + 8] = dark.r;
+							clippedVerticesItems[s + 9] = dark.g;
+							clippedVerticesItems[s + 10] = dark.b;
+							clippedVerticesItems[s + 11] = dark.a;
+							clippedVerticesItems[s + 12] = x2;
+							clippedVerticesItems[s + 13] = y2;
+							clippedVerticesItems[s + 14] = light.r;
+							clippedVerticesItems[s + 15] = light.g;
+							clippedVerticesItems[s + 16] = light.b;
+							clippedVerticesItems[s + 17] = light.a;
+							clippedVerticesItems[s + 18] = u2;
+							clippedVerticesItems[s + 19] = v2;
+							clippedVerticesItems[s + 20] = dark.r;
+							clippedVerticesItems[s + 21] = dark.g;
+							clippedVerticesItems[s + 22] = dark.b;
+							clippedVerticesItems[s + 23] = dark.a;
+							clippedVerticesItems[s + 24] = x3;
+							clippedVerticesItems[s + 25] = y3;
+							clippedVerticesItems[s + 26] = light.r;
+							clippedVerticesItems[s + 27] = light.g;
+							clippedVerticesItems[s + 28] = light.b;
+							clippedVerticesItems[s + 29] = light.a;
+							clippedVerticesItems[s + 30] = u3;
+							clippedVerticesItems[s + 31] = v3;
+							clippedVerticesItems[s + 32] = dark.r;
+							clippedVerticesItems[s + 33] = dark.g;
+							clippedVerticesItems[s + 34] = dark.b;
+							clippedVerticesItems[s + 35] = dark.a;
+						}
+						s = clippedTriangles.length;
+						var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3);
+						clippedTrianglesItems[s] = index;
+						clippedTrianglesItems[s + 1] = (index + 1);
+						clippedTrianglesItems[s + 2] = (index + 2);
+						index += 3;
+						continue outer;
+					}
+				}
+			}
+		};
+		SkeletonClipping.prototype.clip = function (x1, y1, x2, y2, x3, y3, clippingArea, output) {
+			var originalOutput = output;
+			var clipped = false;
+			var input = null;
+			if (clippingArea.length % 4 >= 2) {
+				input = output;
+				output = this.scratch;
+			}
+			else
+				input = this.scratch;
+			input.length = 0;
+			input.push(x1);
+			input.push(y1);
+			input.push(x2);
+			input.push(y2);
+			input.push(x3);
+			input.push(y3);
+			input.push(x1);
+			input.push(y1);
+			output.length = 0;
+			var clippingVertices = clippingArea;
+			var clippingVerticesLast = clippingArea.length - 4;
+			for (var i = 0;; i += 2) {
+				var edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1];
+				var edgeX2 = clippingVertices[i + 2], edgeY2 = clippingVertices[i + 3];
+				var deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2;
+				var inputVertices = input;
+				var inputVerticesLength = input.length - 2, outputStart = output.length;
+				for (var ii = 0; ii < inputVerticesLength; ii += 2) {
+					var inputX = inputVertices[ii], inputY = inputVertices[ii + 1];
+					var inputX2 = inputVertices[ii + 2], inputY2 = inputVertices[ii + 3];
+					var side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0;
+					if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0) {
+						if (side2) {
+							output.push(inputX2);
+							output.push(inputY2);
+							continue;
+						}
+						var c0 = inputY2 - inputY, c2 = inputX2 - inputX;
+						var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
+						output.push(edgeX + (edgeX2 - edgeX) * ua);
+						output.push(edgeY + (edgeY2 - edgeY) * ua);
+					}
+					else if (side2) {
+						var c0 = inputY2 - inputY, c2 = inputX2 - inputX;
+						var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
+						output.push(edgeX + (edgeX2 - edgeX) * ua);
+						output.push(edgeY + (edgeY2 - edgeY) * ua);
+						output.push(inputX2);
+						output.push(inputY2);
+					}
+					clipped = true;
+				}
+				if (outputStart == output.length) {
+					originalOutput.length = 0;
+					return true;
+				}
+				output.push(output[0]);
+				output.push(output[1]);
+				if (i == clippingVerticesLast)
+					break;
+				var temp = output;
+				output = input;
+				output.length = 0;
+				input = temp;
+			}
+			if (originalOutput != output) {
+				originalOutput.length = 0;
+				for (var i = 0, n = output.length - 2; i < n; i++)
+					originalOutput[i] = output[i];
+			}
+			else
+				originalOutput.length = originalOutput.length - 2;
+			return clipped;
+		};
+		SkeletonClipping.makeClockwise = function (polygon) {
+			var vertices = polygon;
+			var verticeslength = polygon.length;
+			var area = vertices[verticeslength - 2] * vertices[1] - vertices[0] * vertices[verticeslength - 1], p1x = 0, p1y = 0, p2x = 0, p2y = 0;
+			for (var i = 0, n = verticeslength - 3; i < n; i += 2) {
+				p1x = vertices[i];
+				p1y = vertices[i + 1];
+				p2x = vertices[i + 2];
+				p2y = vertices[i + 3];
+				area += p1x * p2y - p2x * p1y;
+			}
+			if (area < 0)
+				return;
+			for (var i = 0, lastX = verticeslength - 2, n = verticeslength >> 1; i < n; i += 2) {
+				var x = vertices[i], y = vertices[i + 1];
+				var other = lastX - i;
+				vertices[i] = vertices[other];
+				vertices[i + 1] = vertices[other + 1];
+				vertices[other] = x;
+				vertices[other + 1] = y;
+			}
+		};
+		return SkeletonClipping;
+	}());
+	spine.SkeletonClipping = SkeletonClipping;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var SkeletonData = (function () {
 		function SkeletonData() {
@@ -4236,7 +4731,7 @@ var spine;
 							throw new Error("Slot not found: " + slotName);
 						var slotMap = skinMap[slotName];
 						for (var entryName in slotMap) {
-							var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName);
+							var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName, skeletonData);
 							if (attachment != null)
 								skin.addAttachment(slotIndex, entryName, attachment);
 						}
@@ -4276,7 +4771,7 @@ var spine;
 			}
 			return skeletonData;
 		};
-		SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name) {
+		SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name, skeletonData) {
 			var scale = this.scale;
 			name = this.getValue(map, "name", name);
 			var type = this.getValue(map, "type", "region");
@@ -4363,6 +4858,24 @@ var spine;
 						point.color.setFromString(color);
 					return point;
 				}
+				case "clipping": {
+					var clip = this.attachmentLoader.newClippingAttachment(skin, name);
+					if (clip == null)
+						return null;
+					var end = this.getValue(map, "end", null);
+					if (end != null) {
+						var slot = skeletonData.findSlot(end);
+						if (slot == null)
+							throw new Error("Clipping end slot not found: " + end);
+						clip.endSlot = slot;
+					}
+					var vertexCount = map.vertexCount;
+					this.readVertices(map, clip, vertexCount << 1);
+					var color = this.getValue(map, "color", null);
+					if (color != null)
+						clip.color.setFromString(color);
+					return clip;
+				}
 			}
 			return null;
 		};
@@ -5543,6 +6056,17 @@ var spine;
 				return array;
 			}
 		};
+		Utils.newShortArray = function (size) {
+			if (Utils.SUPPORTS_TYPED_ARRAYS) {
+				return new Int16Array(size);
+			}
+			else {
+				var array = new Array(size);
+				for (var i = 0; i < array.length; i++)
+					array[i] = 0;
+				return array;
+			}
+		};
 		Utils.toFloatArray = function (array) {
 			return Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array;
 		};

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
spine-ts/build/spine-threejs.js.map


+ 1445 - 1444
spine-ts/build/spine-webgl.d.ts

@@ -1,1554 +1,1555 @@
 declare module spine {
-    class Animation {
-        name: string;
-        timelines: Array<Timeline>;
-        duration: number;
-        constructor(name: string, timelines: Array<Timeline>, duration: number);
-        apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-        static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
-        static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
-    }
-    interface Timeline {
-        apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-        getPropertyId(): number;
-    }
-    enum TimelineType {
-        rotate = 0,
-        translate = 1,
-        scale = 2,
-        shear = 3,
-        attachment = 4,
-        color = 5,
-        deform = 6,
-        event = 7,
-        drawOrder = 8,
-        ikConstraint = 9,
-        transformConstraint = 10,
-        pathConstraintPosition = 11,
-        pathConstraintSpacing = 12,
-        pathConstraintMix = 13,
-        twoColor = 14,
-    }
-    abstract class CurveTimeline implements Timeline {
-        static LINEAR: number;
-        static STEPPED: number;
-        static BEZIER: number;
-        static BEZIER_SIZE: number;
-        private curves;
-        abstract getPropertyId(): number;
-        constructor(frameCount: number);
-        getFrameCount(): number;
-        setLinear(frameIndex: number): void;
-        setStepped(frameIndex: number): void;
-        getCurveType(frameIndex: number): number;
-        setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
-        getCurvePercent(frameIndex: number, percent: number): number;
-        abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-    }
-    class RotateTimeline extends CurveTimeline {
-        static ENTRIES: number;
-        static PREV_TIME: number;
-        static PREV_ROTATION: number;
-        static ROTATION: number;
-        boneIndex: number;
-        frames: ArrayLike<number>;
-        constructor(frameCount: number);
-        getPropertyId(): number;
-        setFrame(frameIndex: number, time: number, degrees: number): void;
-        apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-    }
-    class TranslateTimeline extends CurveTimeline {
-        static ENTRIES: number;
-        static PREV_TIME: number;
-        static PREV_X: number;
-        static PREV_Y: number;
-        static X: number;
-        static Y: number;
-        boneIndex: number;
-        frames: ArrayLike<number>;
-        constructor(frameCount: number);
-        getPropertyId(): number;
-        setFrame(frameIndex: number, time: number, x: number, y: number): void;
-        apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-    }
-    class ScaleTimeline extends TranslateTimeline {
-        constructor(frameCount: number);
-        getPropertyId(): number;
-        apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-    }
-    class ShearTimeline extends TranslateTimeline {
-        constructor(frameCount: number);
-        getPropertyId(): number;
-        apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-    }
-    class ColorTimeline extends CurveTimeline {
-        static ENTRIES: number;
-        static PREV_TIME: number;
-        static PREV_R: number;
-        static PREV_G: number;
-        static PREV_B: number;
-        static PREV_A: number;
-        static R: number;
-        static G: number;
-        static B: number;
-        static A: number;
-        slotIndex: number;
-        frames: ArrayLike<number>;
-        constructor(frameCount: number);
-        getPropertyId(): number;
-        setFrame(frameIndex: number, time: number, r: number, g: number, b: number, a: number): void;
-        apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-    }
-    class TwoColorTimeline extends CurveTimeline {
-        static ENTRIES: number;
-        static PREV_TIME: number;
-        static PREV_R: number;
-        static PREV_G: number;
-        static PREV_B: number;
-        static PREV_A: number;
-        static PREV_R2: number;
-        static PREV_G2: number;
-        static PREV_B2: number;
-        static R: number;
-        static G: number;
-        static B: number;
-        static A: number;
-        static R2: number;
-        static G2: number;
-        static B2: number;
-        slotIndex: number;
-        frames: ArrayLike<number>;
-        constructor(frameCount: number);
-        getPropertyId(): number;
-        setFrame(frameIndex: number, time: number, r: number, g: number, b: number, a: number, r2: number, g2: number, b2: number): void;
-        apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-    }
-    class AttachmentTimeline implements Timeline {
-        slotIndex: number;
-        frames: ArrayLike<number>;
-        attachmentNames: Array<string>;
-        constructor(frameCount: number);
-        getPropertyId(): number;
-        getFrameCount(): number;
-        setFrame(frameIndex: number, time: number, attachmentName: string): void;
-        apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-    }
-    class DeformTimeline extends CurveTimeline {
-        slotIndex: number;
-        attachment: VertexAttachment;
-        frames: ArrayLike<number>;
-        frameVertices: Array<ArrayLike<number>>;
-        constructor(frameCount: number);
-        getPropertyId(): number;
-        setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
-        apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-    }
-    class EventTimeline implements Timeline {
-        frames: ArrayLike<number>;
-        events: Array<Event>;
-        constructor(frameCount: number);
-        getPropertyId(): number;
-        getFrameCount(): number;
-        setFrame(frameIndex: number, event: Event): void;
-        apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-    }
-    class DrawOrderTimeline implements Timeline {
-        frames: ArrayLike<number>;
-        drawOrders: Array<Array<number>>;
-        constructor(frameCount: number);
-        getPropertyId(): number;
-        getFrameCount(): number;
-        setFrame(frameIndex: number, time: number, drawOrder: Array<number>): void;
-        apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-    }
-    class IkConstraintTimeline extends CurveTimeline {
-        static ENTRIES: number;
-        static PREV_TIME: number;
-        static PREV_MIX: number;
-        static PREV_BEND_DIRECTION: number;
-        static MIX: number;
-        static BEND_DIRECTION: number;
-        ikConstraintIndex: number;
-        frames: ArrayLike<number>;
-        constructor(frameCount: number);
-        getPropertyId(): number;
-        setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void;
-        apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-    }
-    class TransformConstraintTimeline extends CurveTimeline {
-        static ENTRIES: number;
-        static PREV_TIME: number;
-        static PREV_ROTATE: number;
-        static PREV_TRANSLATE: number;
-        static PREV_SCALE: number;
-        static PREV_SHEAR: number;
-        static ROTATE: number;
-        static TRANSLATE: number;
-        static SCALE: number;
-        static SHEAR: number;
-        transformConstraintIndex: number;
-        frames: ArrayLike<number>;
-        constructor(frameCount: number);
-        getPropertyId(): number;
-        setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number, scaleMix: number, shearMix: number): void;
-        apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-    }
-    class PathConstraintPositionTimeline extends CurveTimeline {
-        static ENTRIES: number;
-        static PREV_TIME: number;
-        static PREV_VALUE: number;
-        static VALUE: number;
-        pathConstraintIndex: number;
-        frames: ArrayLike<number>;
-        constructor(frameCount: number);
-        getPropertyId(): number;
-        setFrame(frameIndex: number, time: number, value: number): void;
-        apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-    }
-    class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
-        constructor(frameCount: number);
-        getPropertyId(): number;
-        apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-    }
-    class PathConstraintMixTimeline extends CurveTimeline {
-        static ENTRIES: number;
-        static PREV_TIME: number;
-        static PREV_ROTATE: number;
-        static PREV_TRANSLATE: number;
-        static ROTATE: number;
-        static TRANSLATE: number;
-        pathConstraintIndex: number;
-        frames: ArrayLike<number>;
-        constructor(frameCount: number);
-        getPropertyId(): number;
-        setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
-        apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
-    }
+	class Animation {
+		name: string;
+		timelines: Array<Timeline>;
+		duration: number;
+		constructor(name: string, timelines: Array<Timeline>, duration: number);
+		apply(skeleton: Skeleton, lastTime: number, time: number, loop: boolean, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+		static binarySearch(values: ArrayLike<number>, target: number, step?: number): number;
+		static linearSearch(values: ArrayLike<number>, target: number, step: number): number;
+	}
+	interface Timeline {
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+		getPropertyId(): number;
+	}
+	enum TimelineType {
+		rotate = 0,
+		translate = 1,
+		scale = 2,
+		shear = 3,
+		attachment = 4,
+		color = 5,
+		deform = 6,
+		event = 7,
+		drawOrder = 8,
+		ikConstraint = 9,
+		transformConstraint = 10,
+		pathConstraintPosition = 11,
+		pathConstraintSpacing = 12,
+		pathConstraintMix = 13,
+		twoColor = 14,
+	}
+	abstract class CurveTimeline implements Timeline {
+		static LINEAR: number;
+		static STEPPED: number;
+		static BEZIER: number;
+		static BEZIER_SIZE: number;
+		private curves;
+		abstract getPropertyId(): number;
+		constructor(frameCount: number);
+		getFrameCount(): number;
+		setLinear(frameIndex: number): void;
+		setStepped(frameIndex: number): void;
+		getCurveType(frameIndex: number): number;
+		setCurve(frameIndex: number, cx1: number, cy1: number, cx2: number, cy2: number): void;
+		getCurvePercent(frameIndex: number, percent: number): number;
+		abstract apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+	}
+	class RotateTimeline extends CurveTimeline {
+		static ENTRIES: number;
+		static PREV_TIME: number;
+		static PREV_ROTATION: number;
+		static ROTATION: number;
+		boneIndex: number;
+		frames: ArrayLike<number>;
+		constructor(frameCount: number);
+		getPropertyId(): number;
+		setFrame(frameIndex: number, time: number, degrees: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+	}
+	class TranslateTimeline extends CurveTimeline {
+		static ENTRIES: number;
+		static PREV_TIME: number;
+		static PREV_X: number;
+		static PREV_Y: number;
+		static X: number;
+		static Y: number;
+		boneIndex: number;
+		frames: ArrayLike<number>;
+		constructor(frameCount: number);
+		getPropertyId(): number;
+		setFrame(frameIndex: number, time: number, x: number, y: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+	}
+	class ScaleTimeline extends TranslateTimeline {
+		constructor(frameCount: number);
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+	}
+	class ShearTimeline extends TranslateTimeline {
+		constructor(frameCount: number);
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+	}
+	class ColorTimeline extends CurveTimeline {
+		static ENTRIES: number;
+		static PREV_TIME: number;
+		static PREV_R: number;
+		static PREV_G: number;
+		static PREV_B: number;
+		static PREV_A: number;
+		static R: number;
+		static G: number;
+		static B: number;
+		static A: number;
+		slotIndex: number;
+		frames: ArrayLike<number>;
+		constructor(frameCount: number);
+		getPropertyId(): number;
+		setFrame(frameIndex: number, time: number, r: number, g: number, b: number, a: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+	}
+	class TwoColorTimeline extends CurveTimeline {
+		static ENTRIES: number;
+		static PREV_TIME: number;
+		static PREV_R: number;
+		static PREV_G: number;
+		static PREV_B: number;
+		static PREV_A: number;
+		static PREV_R2: number;
+		static PREV_G2: number;
+		static PREV_B2: number;
+		static R: number;
+		static G: number;
+		static B: number;
+		static A: number;
+		static R2: number;
+		static G2: number;
+		static B2: number;
+		slotIndex: number;
+		frames: ArrayLike<number>;
+		constructor(frameCount: number);
+		getPropertyId(): number;
+		setFrame(frameIndex: number, time: number, r: number, g: number, b: number, a: number, r2: number, g2: number, b2: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+	}
+	class AttachmentTimeline implements Timeline {
+		slotIndex: number;
+		frames: ArrayLike<number>;
+		attachmentNames: Array<string>;
+		constructor(frameCount: number);
+		getPropertyId(): number;
+		getFrameCount(): number;
+		setFrame(frameIndex: number, time: number, attachmentName: string): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+	}
+	class DeformTimeline extends CurveTimeline {
+		slotIndex: number;
+		attachment: VertexAttachment;
+		frames: ArrayLike<number>;
+		frameVertices: Array<ArrayLike<number>>;
+		constructor(frameCount: number);
+		getPropertyId(): number;
+		setFrame(frameIndex: number, time: number, vertices: ArrayLike<number>): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+	}
+	class EventTimeline implements Timeline {
+		frames: ArrayLike<number>;
+		events: Array<Event>;
+		constructor(frameCount: number);
+		getPropertyId(): number;
+		getFrameCount(): number;
+		setFrame(frameIndex: number, event: Event): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+	}
+	class DrawOrderTimeline implements Timeline {
+		frames: ArrayLike<number>;
+		drawOrders: Array<Array<number>>;
+		constructor(frameCount: number);
+		getPropertyId(): number;
+		getFrameCount(): number;
+		setFrame(frameIndex: number, time: number, drawOrder: Array<number>): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+	}
+	class IkConstraintTimeline extends CurveTimeline {
+		static ENTRIES: number;
+		static PREV_TIME: number;
+		static PREV_MIX: number;
+		static PREV_BEND_DIRECTION: number;
+		static MIX: number;
+		static BEND_DIRECTION: number;
+		ikConstraintIndex: number;
+		frames: ArrayLike<number>;
+		constructor(frameCount: number);
+		getPropertyId(): number;
+		setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+	}
+	class TransformConstraintTimeline extends CurveTimeline {
+		static ENTRIES: number;
+		static PREV_TIME: number;
+		static PREV_ROTATE: number;
+		static PREV_TRANSLATE: number;
+		static PREV_SCALE: number;
+		static PREV_SHEAR: number;
+		static ROTATE: number;
+		static TRANSLATE: number;
+		static SCALE: number;
+		static SHEAR: number;
+		transformConstraintIndex: number;
+		frames: ArrayLike<number>;
+		constructor(frameCount: number);
+		getPropertyId(): number;
+		setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number, scaleMix: number, shearMix: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+	}
+	class PathConstraintPositionTimeline extends CurveTimeline {
+		static ENTRIES: number;
+		static PREV_TIME: number;
+		static PREV_VALUE: number;
+		static VALUE: number;
+		pathConstraintIndex: number;
+		frames: ArrayLike<number>;
+		constructor(frameCount: number);
+		getPropertyId(): number;
+		setFrame(frameIndex: number, time: number, value: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+	}
+	class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline {
+		constructor(frameCount: number);
+		getPropertyId(): number;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+	}
+	class PathConstraintMixTimeline extends CurveTimeline {
+		static ENTRIES: number;
+		static PREV_TIME: number;
+		static PREV_ROTATE: number;
+		static PREV_TRANSLATE: number;
+		static ROTATE: number;
+		static TRANSLATE: number;
+		pathConstraintIndex: number;
+		frames: ArrayLike<number>;
+		constructor(frameCount: number);
+		getPropertyId(): number;
+		setFrame(frameIndex: number, time: number, rotateMix: number, translateMix: number): void;
+		apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, setupPose: boolean, mixingOut: boolean): void;
+	}
 }
 declare module spine {
-    class AnimationState {
-        static emptyAnimation: Animation;
-        data: AnimationStateData;
-        tracks: TrackEntry[];
-        events: Event[];
-        listeners: AnimationStateListener2[];
-        queue: EventQueue;
-        propertyIDs: IntSet;
-        animationsChanged: boolean;
-        multipleMixing: boolean;
-        timeScale: number;
-        trackEntryPool: Pool<TrackEntry>;
-        constructor(data: AnimationStateData);
-        update(delta: number): void;
-        updateMixingFrom(entry: TrackEntry, delta: number): void;
-        apply(skeleton: Skeleton): void;
-        applyMixingFrom(entry: TrackEntry, skeleton: Skeleton): number;
-        applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
-        queueEvents(entry: TrackEntry, animationTime: number): void;
-        clearTracks(): void;
-        clearTrack(trackIndex: number): void;
-        setCurrent(index: number, current: TrackEntry, interrupt: boolean): void;
-        setAnimation(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
-        setAnimationWith(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
-        addAnimation(trackIndex: number, animationName: string, loop: boolean, delay: number): TrackEntry;
-        addAnimationWith(trackIndex: number, animation: Animation, loop: boolean, delay: number): TrackEntry;
-        setEmptyAnimation(trackIndex: number, mixDuration: number): TrackEntry;
-        addEmptyAnimation(trackIndex: number, mixDuration: number, delay: number): TrackEntry;
-        setEmptyAnimations(mixDuration: number): void;
-        expandToIndex(index: number): TrackEntry;
-        trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry): TrackEntry;
-        disposeNext(entry: TrackEntry): void;
-        _animationsChanged(): void;
-        setTimelinesFirst(entry: TrackEntry): void;
-        checkTimelinesFirst(entry: TrackEntry): void;
-        checkTimelinesUsage(entry: TrackEntry, usageArray: Array<boolean>): void;
-        getCurrent(trackIndex: number): TrackEntry;
-        addListener(listener: AnimationStateListener2): void;
-        removeListener(listener: AnimationStateListener2): void;
-        clearListeners(): void;
-        clearListenerNotifications(): void;
-    }
-    class TrackEntry {
-        animation: Animation;
-        next: TrackEntry;
-        mixingFrom: TrackEntry;
-        listener: AnimationStateListener2;
-        trackIndex: number;
-        loop: boolean;
-        eventThreshold: number;
-        attachmentThreshold: number;
-        drawOrderThreshold: number;
-        animationStart: number;
-        animationEnd: number;
-        animationLast: number;
-        nextAnimationLast: number;
-        delay: number;
-        trackTime: number;
-        trackLast: number;
-        nextTrackLast: number;
-        trackEnd: number;
-        timeScale: number;
-        alpha: number;
-        mixTime: number;
-        mixDuration: number;
-        mixAlpha: number;
-        timelinesFirst: boolean[];
-        timelinesLast: boolean[];
-        timelinesRotation: number[];
-        reset(): void;
-        getAnimationTime(): number;
-        setAnimationLast(animationLast: number): void;
-        isComplete(): boolean;
-        resetRotationDirections(): void;
-    }
-    class EventQueue {
-        objects: Array<any>;
-        drainDisabled: boolean;
-        animState: AnimationState;
-        constructor(animState: AnimationState);
-        start(entry: TrackEntry): void;
-        interrupt(entry: TrackEntry): void;
-        end(entry: TrackEntry): void;
-        dispose(entry: TrackEntry): void;
-        complete(entry: TrackEntry): void;
-        event(entry: TrackEntry, event: Event): void;
-        drain(): void;
-        clear(): void;
-    }
-    enum EventType {
-        start = 0,
-        interrupt = 1,
-        end = 2,
-        dispose = 3,
-        complete = 4,
-        event = 5,
-    }
-    interface AnimationStateListener2 {
-        start(entry: TrackEntry): void;
-        interrupt(entry: TrackEntry): void;
-        end(entry: TrackEntry): void;
-        dispose(entry: TrackEntry): void;
-        complete(entry: TrackEntry): void;
-        event(entry: TrackEntry, event: Event): void;
-    }
-    abstract class AnimationStateAdapter2 implements AnimationStateListener2 {
-        start(entry: TrackEntry): void;
-        interrupt(entry: TrackEntry): void;
-        end(entry: TrackEntry): void;
-        dispose(entry: TrackEntry): void;
-        complete(entry: TrackEntry): void;
-        event(entry: TrackEntry, event: Event): void;
-    }
+	class AnimationState {
+		static emptyAnimation: Animation;
+		data: AnimationStateData;
+		tracks: TrackEntry[];
+		events: Event[];
+		listeners: AnimationStateListener2[];
+		queue: EventQueue;
+		propertyIDs: IntSet;
+		animationsChanged: boolean;
+		multipleMixing: boolean;
+		timeScale: number;
+		trackEntryPool: Pool<TrackEntry>;
+		constructor(data: AnimationStateData);
+		update(delta: number): void;
+		updateMixingFrom(entry: TrackEntry, delta: number): void;
+		apply(skeleton: Skeleton): void;
+		applyMixingFrom(entry: TrackEntry, skeleton: Skeleton): number;
+		applyRotateTimeline(timeline: Timeline, skeleton: Skeleton, time: number, alpha: number, setupPose: boolean, timelinesRotation: Array<number>, i: number, firstFrame: boolean): void;
+		queueEvents(entry: TrackEntry, animationTime: number): void;
+		clearTracks(): void;
+		clearTrack(trackIndex: number): void;
+		setCurrent(index: number, current: TrackEntry, interrupt: boolean): void;
+		setAnimation(trackIndex: number, animationName: string, loop: boolean): TrackEntry;
+		setAnimationWith(trackIndex: number, animation: Animation, loop: boolean): TrackEntry;
+		addAnimation(trackIndex: number, animationName: string, loop: boolean, delay: number): TrackEntry;
+		addAnimationWith(trackIndex: number, animation: Animation, loop: boolean, delay: number): TrackEntry;
+		setEmptyAnimation(trackIndex: number, mixDuration: number): TrackEntry;
+		addEmptyAnimation(trackIndex: number, mixDuration: number, delay: number): TrackEntry;
+		setEmptyAnimations(mixDuration: number): void;
+		expandToIndex(index: number): TrackEntry;
+		trackEntry(trackIndex: number, animation: Animation, loop: boolean, last: TrackEntry): TrackEntry;
+		disposeNext(entry: TrackEntry): void;
+		_animationsChanged(): void;
+		setTimelinesFirst(entry: TrackEntry): void;
+		checkTimelinesFirst(entry: TrackEntry): void;
+		checkTimelinesUsage(entry: TrackEntry, usageArray: Array<boolean>): void;
+		getCurrent(trackIndex: number): TrackEntry;
+		addListener(listener: AnimationStateListener2): void;
+		removeListener(listener: AnimationStateListener2): void;
+		clearListeners(): void;
+		clearListenerNotifications(): void;
+	}
+	class TrackEntry {
+		animation: Animation;
+		next: TrackEntry;
+		mixingFrom: TrackEntry;
+		listener: AnimationStateListener2;
+		trackIndex: number;
+		loop: boolean;
+		eventThreshold: number;
+		attachmentThreshold: number;
+		drawOrderThreshold: number;
+		animationStart: number;
+		animationEnd: number;
+		animationLast: number;
+		nextAnimationLast: number;
+		delay: number;
+		trackTime: number;
+		trackLast: number;
+		nextTrackLast: number;
+		trackEnd: number;
+		timeScale: number;
+		alpha: number;
+		mixTime: number;
+		mixDuration: number;
+		mixAlpha: number;
+		timelinesFirst: boolean[];
+		timelinesLast: boolean[];
+		timelinesRotation: number[];
+		reset(): void;
+		getAnimationTime(): number;
+		setAnimationLast(animationLast: number): void;
+		isComplete(): boolean;
+		resetRotationDirections(): void;
+	}
+	class EventQueue {
+		objects: Array<any>;
+		drainDisabled: boolean;
+		animState: AnimationState;
+		constructor(animState: AnimationState);
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
+		drain(): void;
+		clear(): void;
+	}
+	enum EventType {
+		start = 0,
+		interrupt = 1,
+		end = 2,
+		dispose = 3,
+		complete = 4,
+		event = 5,
+	}
+	interface AnimationStateListener2 {
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
+	}
+	abstract class AnimationStateAdapter2 implements AnimationStateListener2 {
+		start(entry: TrackEntry): void;
+		interrupt(entry: TrackEntry): void;
+		end(entry: TrackEntry): void;
+		dispose(entry: TrackEntry): void;
+		complete(entry: TrackEntry): void;
+		event(entry: TrackEntry, event: Event): void;
+	}
 }
 declare module spine {
-    class AnimationStateData {
-        skeletonData: SkeletonData;
-        animationToMixTime: Map<number>;
-        defaultMix: number;
-        constructor(skeletonData: SkeletonData);
-        setMix(fromName: string, toName: string, duration: number): void;
-        setMixWith(from: Animation, to: Animation, duration: number): void;
-        getMix(from: Animation, to: Animation): number;
-    }
+	class AnimationStateData {
+		skeletonData: SkeletonData;
+		animationToMixTime: Map<number>;
+		defaultMix: number;
+		constructor(skeletonData: SkeletonData);
+		setMix(fromName: string, toName: string, duration: number): void;
+		setMixWith(from: Animation, to: Animation, duration: number): void;
+		getMix(from: Animation, to: Animation): number;
+	}
 }
 declare module spine {
-    class AssetManager implements Disposable {
-        private pathPrefix;
-        private textureLoader;
-        private assets;
-        private errors;
-        private toLoad;
-        private loaded;
-        constructor(textureLoader: (image: HTMLImageElement) => any, pathPrefix?: string);
-        loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, error: string) => void): void;
-        loadTexture(path: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
-        loadTextureData(path: string, data: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
-        get(path: string): any;
-        remove(path: string): void;
-        removeAll(): void;
-        isLoadingComplete(): boolean;
-        getToLoad(): number;
-        getLoaded(): number;
-        dispose(): void;
-        hasErrors(): boolean;
-        getErrors(): Map<string>;
-    }
+	class AssetManager implements Disposable {
+		private pathPrefix;
+		private textureLoader;
+		private assets;
+		private errors;
+		private toLoad;
+		private loaded;
+		constructor(textureLoader: (image: HTMLImageElement) => any, pathPrefix?: string);
+		loadText(path: string, success?: (path: string, text: string) => void, error?: (path: string, error: string) => void): void;
+		loadTexture(path: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
+		loadTextureData(path: string, data: string, success?: (path: string, image: HTMLImageElement) => void, error?: (path: string, error: string) => void): void;
+		get(path: string): any;
+		remove(path: string): void;
+		removeAll(): void;
+		isLoadingComplete(): boolean;
+		getToLoad(): number;
+		getLoaded(): number;
+		dispose(): void;
+		hasErrors(): boolean;
+		getErrors(): Map<string>;
+	}
 }
 declare module spine {
-    class AtlasAttachmentLoader implements AttachmentLoader {
-        atlas: TextureAtlas;
-        constructor(atlas: TextureAtlas);
-        newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
-        newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
-        newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
-        newPathAttachment(skin: Skin, name: string): PathAttachment;
-        newPointAttachment(skin: Skin, name: string): PointAttachment;
-        newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
-    }
+	class AtlasAttachmentLoader implements AttachmentLoader {
+		atlas: TextureAtlas;
+		constructor(atlas: TextureAtlas);
+		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
+		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
+		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
+		newPathAttachment(skin: Skin, name: string): PathAttachment;
+		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
+	}
 }
 declare module spine {
-    abstract class Attachment {
-        name: string;
-        constructor(name: string);
-    }
-    abstract class VertexAttachment extends Attachment {
-        bones: Array<number>;
-        vertices: ArrayLike<number>;
-        worldVerticesLength: number;
-        constructor(name: string);
-        computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
-        applyDeform(sourceAttachment: VertexAttachment): boolean;
-    }
+	abstract class Attachment {
+		name: string;
+		constructor(name: string);
+	}
+	abstract class VertexAttachment extends Attachment {
+		bones: Array<number>;
+		vertices: ArrayLike<number>;
+		worldVerticesLength: number;
+		constructor(name: string);
+		computeWorldVertices(slot: Slot, start: number, count: number, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
+		applyDeform(sourceAttachment: VertexAttachment): boolean;
+	}
 }
 declare module spine {
-    interface AttachmentLoader {
-        newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
-        newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
-        newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
-        newPathAttachment(skin: Skin, name: string): PathAttachment;
-        newPointAttachment(skin: Skin, name: string): PointAttachment;
-        newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
-    }
+	interface AttachmentLoader {
+		newRegionAttachment(skin: Skin, name: string, path: string): RegionAttachment;
+		newMeshAttachment(skin: Skin, name: string, path: string): MeshAttachment;
+		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
+		newPathAttachment(skin: Skin, name: string): PathAttachment;
+		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
+	}
 }
 declare module spine {
-    enum AttachmentType {
-        Region = 0,
-        BoundingBox = 1,
-        Mesh = 2,
-        LinkedMesh = 3,
-        Path = 4,
-        Point = 5,
-    }
+	enum AttachmentType {
+		Region = 0,
+		BoundingBox = 1,
+		Mesh = 2,
+		LinkedMesh = 3,
+		Path = 4,
+		Point = 5,
+	}
 }
 declare module spine {
-    class BoundingBoxAttachment extends VertexAttachment {
-        color: Color;
-        constructor(name: string);
-    }
+	class BoundingBoxAttachment extends VertexAttachment {
+		color: Color;
+		constructor(name: string);
+	}
 }
 declare module spine {
-    class ClippingAttachment extends VertexAttachment {
-        endSlot: SlotData;
-        color: Color;
-        constructor(name: string);
-    }
+	class ClippingAttachment extends VertexAttachment {
+		endSlot: SlotData;
+		color: Color;
+		constructor(name: string);
+	}
 }
 declare module spine {
-    class MeshAttachment extends VertexAttachment {
-        region: TextureRegion;
-        path: string;
-        regionUVs: ArrayLike<number>;
-        uvs: ArrayLike<number>;
-        triangles: Array<number>;
-        color: Color;
-        hullLength: number;
-        private parentMesh;
-        inheritDeform: boolean;
-        tempColor: Color;
-        constructor(name: string);
-        updateUVs(): void;
-        applyDeform(sourceAttachment: VertexAttachment): boolean;
-        getParentMesh(): MeshAttachment;
-        setParentMesh(parentMesh: MeshAttachment): void;
-    }
+	class MeshAttachment extends VertexAttachment {
+		region: TextureRegion;
+		path: string;
+		regionUVs: ArrayLike<number>;
+		uvs: ArrayLike<number>;
+		triangles: Array<number>;
+		color: Color;
+		hullLength: number;
+		private parentMesh;
+		inheritDeform: boolean;
+		tempColor: Color;
+		constructor(name: string);
+		updateUVs(): void;
+		applyDeform(sourceAttachment: VertexAttachment): boolean;
+		getParentMesh(): MeshAttachment;
+		setParentMesh(parentMesh: MeshAttachment): void;
+	}
 }
 declare module spine {
-    class PathAttachment extends VertexAttachment {
-        lengths: Array<number>;
-        closed: boolean;
-        constantSpeed: boolean;
-        color: Color;
-        constructor(name: string);
-    }
+	class PathAttachment extends VertexAttachment {
+		lengths: Array<number>;
+		closed: boolean;
+		constantSpeed: boolean;
+		color: Color;
+		constructor(name: string);
+	}
 }
 declare module spine {
-    class PointAttachment extends VertexAttachment {
-        x: number;
-        y: number;
-        rotation: number;
-        color: Color;
-        constructor(name: string);
-        computeWorldPosition(bone: Bone, point: Vector2): Vector2;
-        computeWorldRotation(bone: Bone): number;
-    }
+	class PointAttachment extends VertexAttachment {
+		x: number;
+		y: number;
+		rotation: number;
+		color: Color;
+		constructor(name: string);
+		computeWorldPosition(bone: Bone, point: Vector2): Vector2;
+		computeWorldRotation(bone: Bone): number;
+	}
 }
 declare module spine {
-    class RegionAttachment extends Attachment {
-        static OX1: number;
-        static OY1: number;
-        static OX2: number;
-        static OY2: number;
-        static OX3: number;
-        static OY3: number;
-        static OX4: number;
-        static OY4: number;
-        static X1: number;
-        static Y1: number;
-        static C1R: number;
-        static C1G: number;
-        static C1B: number;
-        static C1A: number;
-        static U1: number;
-        static V1: number;
-        static X2: number;
-        static Y2: number;
-        static C2R: number;
-        static C2G: number;
-        static C2B: number;
-        static C2A: number;
-        static U2: number;
-        static V2: number;
-        static X3: number;
-        static Y3: number;
-        static C3R: number;
-        static C3G: number;
-        static C3B: number;
-        static C3A: number;
-        static U3: number;
-        static V3: number;
-        static X4: number;
-        static Y4: number;
-        static C4R: number;
-        static C4G: number;
-        static C4B: number;
-        static C4A: number;
-        static U4: number;
-        static V4: number;
-        x: number;
-        y: number;
-        scaleX: number;
-        scaleY: number;
-        rotation: number;
-        width: number;
-        height: number;
-        color: Color;
-        path: string;
-        rendererObject: any;
-        region: TextureRegion;
-        offset: ArrayLike<number>;
-        uvs: ArrayLike<number>;
-        tempColor: Color;
-        constructor(name: string);
-        updateOffset(): void;
-        setRegion(region: TextureRegion): void;
-        computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
-    }
+	class RegionAttachment extends Attachment {
+		static OX1: number;
+		static OY1: number;
+		static OX2: number;
+		static OY2: number;
+		static OX3: number;
+		static OY3: number;
+		static OX4: number;
+		static OY4: number;
+		static X1: number;
+		static Y1: number;
+		static C1R: number;
+		static C1G: number;
+		static C1B: number;
+		static C1A: number;
+		static U1: number;
+		static V1: number;
+		static X2: number;
+		static Y2: number;
+		static C2R: number;
+		static C2G: number;
+		static C2B: number;
+		static C2A: number;
+		static U2: number;
+		static V2: number;
+		static X3: number;
+		static Y3: number;
+		static C3R: number;
+		static C3G: number;
+		static C3B: number;
+		static C3A: number;
+		static U3: number;
+		static V3: number;
+		static X4: number;
+		static Y4: number;
+		static C4R: number;
+		static C4G: number;
+		static C4B: number;
+		static C4A: number;
+		static U4: number;
+		static V4: number;
+		x: number;
+		y: number;
+		scaleX: number;
+		scaleY: number;
+		rotation: number;
+		width: number;
+		height: number;
+		color: Color;
+		path: string;
+		rendererObject: any;
+		region: TextureRegion;
+		offset: ArrayLike<number>;
+		uvs: ArrayLike<number>;
+		tempColor: Color;
+		constructor(name: string);
+		updateOffset(): void;
+		setRegion(region: TextureRegion): void;
+		computeWorldVertices(bone: Bone, worldVertices: ArrayLike<number>, offset: number, stride: number): void;
+	}
 }
 declare module spine {
-    enum BlendMode {
-        Normal = 0,
-        Additive = 1,
-        Multiply = 2,
-        Screen = 3,
-    }
+	enum BlendMode {
+		Normal = 0,
+		Additive = 1,
+		Multiply = 2,
+		Screen = 3,
+	}
 }
 declare module spine {
-    class Bone implements Updatable {
-        data: BoneData;
-        skeleton: Skeleton;
-        parent: Bone;
-        children: Bone[];
-        x: number;
-        y: number;
-        rotation: number;
-        scaleX: number;
-        scaleY: number;
-        shearX: number;
-        shearY: number;
-        ax: number;
-        ay: number;
-        arotation: number;
-        ascaleX: number;
-        ascaleY: number;
-        ashearX: number;
-        ashearY: number;
-        appliedValid: boolean;
-        a: number;
-        b: number;
-        worldX: number;
-        c: number;
-        d: number;
-        worldY: number;
-        sorted: boolean;
-        constructor(data: BoneData, skeleton: Skeleton, parent: Bone);
-        update(): void;
-        updateWorldTransform(): void;
-        updateWorldTransformWith(x: number, y: number, rotation: number, scaleX: number, scaleY: number, shearX: number, shearY: number): void;
-        setToSetupPose(): void;
-        getWorldRotationX(): number;
-        getWorldRotationY(): number;
-        getWorldScaleX(): number;
-        getWorldScaleY(): number;
-        updateAppliedTransform(): void;
-        worldToLocal(world: Vector2): Vector2;
-        localToWorld(local: Vector2): Vector2;
-        worldToLocalRotation(worldRotation: number): number;
-        localToWorldRotation(localRotation: number): number;
-        rotateWorld(degrees: number): void;
-    }
+	class Bone implements Updatable {
+		data: BoneData;
+		skeleton: Skeleton;
+		parent: Bone;
+		children: Bone[];
+		x: number;
+		y: number;
+		rotation: number;
+		scaleX: number;
+		scaleY: number;
+		shearX: number;
+		shearY: number;
+		ax: number;
+		ay: number;
+		arotation: number;
+		ascaleX: number;
+		ascaleY: number;
+		ashearX: number;
+		ashearY: number;
+		appliedValid: boolean;
+		a: number;
+		b: number;
+		worldX: number;
+		c: number;
+		d: number;
+		worldY: number;
+		sorted: boolean;
+		constructor(data: BoneData, skeleton: Skeleton, parent: Bone);
+		update(): void;
+		updateWorldTransform(): void;
+		updateWorldTransformWith(x: number, y: number, rotation: number, scaleX: number, scaleY: number, shearX: number, shearY: number): void;
+		setToSetupPose(): void;
+		getWorldRotationX(): number;
+		getWorldRotationY(): number;
+		getWorldScaleX(): number;
+		getWorldScaleY(): number;
+		updateAppliedTransform(): void;
+		worldToLocal(world: Vector2): Vector2;
+		localToWorld(local: Vector2): Vector2;
+		worldToLocalRotation(worldRotation: number): number;
+		localToWorldRotation(localRotation: number): number;
+		rotateWorld(degrees: number): void;
+	}
 }
 declare module spine {
-    class BoneData {
-        index: number;
-        name: string;
-        parent: BoneData;
-        length: number;
-        x: number;
-        y: number;
-        rotation: number;
-        scaleX: number;
-        scaleY: number;
-        shearX: number;
-        shearY: number;
-        transformMode: TransformMode;
-        constructor(index: number, name: string, parent: BoneData);
-    }
-    enum TransformMode {
-        Normal = 0,
-        OnlyTranslation = 1,
-        NoRotationOrReflection = 2,
-        NoScale = 3,
-        NoScaleOrReflection = 4,
-    }
+	class BoneData {
+		index: number;
+		name: string;
+		parent: BoneData;
+		length: number;
+		x: number;
+		y: number;
+		rotation: number;
+		scaleX: number;
+		scaleY: number;
+		shearX: number;
+		shearY: number;
+		transformMode: TransformMode;
+		constructor(index: number, name: string, parent: BoneData);
+	}
+	enum TransformMode {
+		Normal = 0,
+		OnlyTranslation = 1,
+		NoRotationOrReflection = 2,
+		NoScale = 3,
+		NoScaleOrReflection = 4,
+	}
 }
 declare module spine {
-    interface Constraint extends Updatable {
-        getOrder(): number;
-    }
+	interface Constraint extends Updatable {
+		getOrder(): number;
+	}
 }
 declare module spine {
-    class ConvexDecomposer {
-        private convexPolygons;
-        private convexPolygonsIndices;
-        private indicesArray;
-        private isConcaveArray;
-        private triangles;
-        private polygonPool;
-        private polygonIndicesPool;
-        decompose(input: ArrayLike<number>): Array<Array<number>>;
-        private static isConcave(index, vertexCount, vertices, indices);
-        private static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y);
-        private static winding(p1x, p1y, p2x, p2y, p3x, p3y);
-    }
+	class ConvexDecomposer {
+		private convexPolygons;
+		private convexPolygonsIndices;
+		private indicesArray;
+		private isConcaveArray;
+		private triangles;
+		private polygonPool;
+		private polygonIndicesPool;
+		decompose(input: ArrayLike<number>): Array<Array<number>>;
+		private static isConcave(index, vertexCount, vertices, indices);
+		private static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y);
+		private static winding(p1x, p1y, p2x, p2y, p3x, p3y);
+	}
 }
 declare module spine {
-    class Event {
-        data: EventData;
-        intValue: number;
-        floatValue: number;
-        stringValue: string;
-        time: number;
-        constructor(time: number, data: EventData);
-    }
+	class Event {
+		data: EventData;
+		intValue: number;
+		floatValue: number;
+		stringValue: string;
+		time: number;
+		constructor(time: number, data: EventData);
+	}
 }
 declare module spine {
-    class EventData {
-        name: string;
-        intValue: number;
-        floatValue: number;
-        stringValue: string;
-        constructor(name: string);
-    }
+	class EventData {
+		name: string;
+		intValue: number;
+		floatValue: number;
+		stringValue: string;
+		constructor(name: string);
+	}
 }
 declare module spine {
-    class IkConstraint implements Constraint {
-        data: IkConstraintData;
-        bones: Array<Bone>;
-        target: Bone;
-        mix: number;
-        bendDirection: number;
-        constructor(data: IkConstraintData, skeleton: Skeleton);
-        getOrder(): number;
-        apply(): void;
-        update(): void;
-        apply1(bone: Bone, targetX: number, targetY: number, alpha: number): void;
-        apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, alpha: number): void;
-    }
+	class IkConstraint implements Constraint {
+		data: IkConstraintData;
+		bones: Array<Bone>;
+		target: Bone;
+		mix: number;
+		bendDirection: number;
+		constructor(data: IkConstraintData, skeleton: Skeleton);
+		getOrder(): number;
+		apply(): void;
+		update(): void;
+		apply1(bone: Bone, targetX: number, targetY: number, alpha: number): void;
+		apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, alpha: number): void;
+	}
 }
 declare module spine {
-    class IkConstraintData {
-        name: string;
-        order: number;
-        bones: BoneData[];
-        target: BoneData;
-        bendDirection: number;
-        mix: number;
-        constructor(name: string);
-    }
+	class IkConstraintData {
+		name: string;
+		order: number;
+		bones: BoneData[];
+		target: BoneData;
+		bendDirection: number;
+		mix: number;
+		constructor(name: string);
+	}
 }
 declare module spine {
-    class PathConstraint implements Constraint {
-        static NONE: number;
-        static BEFORE: number;
-        static AFTER: number;
-        data: PathConstraintData;
-        bones: Array<Bone>;
-        target: Slot;
-        position: number;
-        spacing: number;
-        rotateMix: number;
-        translateMix: number;
-        spaces: number[];
-        positions: number[];
-        world: number[];
-        curves: number[];
-        lengths: number[];
-        segments: number[];
-        constructor(data: PathConstraintData, skeleton: Skeleton);
-        apply(): void;
-        update(): void;
-        computeWorldPositions(path: PathAttachment, spacesCount: number, tangents: boolean, percentPosition: boolean, percentSpacing: boolean): number[];
-        addBeforePosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number): void;
-        addAfterPosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number): void;
-        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): void;
-        getOrder(): number;
-    }
+	class PathConstraint implements Constraint {
+		static NONE: number;
+		static BEFORE: number;
+		static AFTER: number;
+		data: PathConstraintData;
+		bones: Array<Bone>;
+		target: Slot;
+		position: number;
+		spacing: number;
+		rotateMix: number;
+		translateMix: number;
+		spaces: number[];
+		positions: number[];
+		world: number[];
+		curves: number[];
+		lengths: number[];
+		segments: number[];
+		constructor(data: PathConstraintData, skeleton: Skeleton);
+		apply(): void;
+		update(): void;
+		computeWorldPositions(path: PathAttachment, spacesCount: number, tangents: boolean, percentPosition: boolean, percentSpacing: boolean): number[];
+		addBeforePosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number): void;
+		addAfterPosition(p: number, temp: Array<number>, i: number, out: Array<number>, o: number): void;
+		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): void;
+		getOrder(): number;
+	}
 }
 declare module spine {
-    class PathConstraintData {
-        name: string;
-        order: number;
-        bones: BoneData[];
-        target: SlotData;
-        positionMode: PositionMode;
-        spacingMode: SpacingMode;
-        rotateMode: RotateMode;
-        offsetRotation: number;
-        position: number;
-        spacing: number;
-        rotateMix: number;
-        translateMix: number;
-        constructor(name: string);
-    }
-    enum PositionMode {
-        Fixed = 0,
-        Percent = 1,
-    }
-    enum SpacingMode {
-        Length = 0,
-        Fixed = 1,
-        Percent = 2,
-    }
-    enum RotateMode {
-        Tangent = 0,
-        Chain = 1,
-        ChainScale = 2,
-    }
+	class PathConstraintData {
+		name: string;
+		order: number;
+		bones: BoneData[];
+		target: SlotData;
+		positionMode: PositionMode;
+		spacingMode: SpacingMode;
+		rotateMode: RotateMode;
+		offsetRotation: number;
+		position: number;
+		spacing: number;
+		rotateMix: number;
+		translateMix: number;
+		constructor(name: string);
+	}
+	enum PositionMode {
+		Fixed = 0,
+		Percent = 1,
+	}
+	enum SpacingMode {
+		Length = 0,
+		Fixed = 1,
+		Percent = 2,
+	}
+	enum RotateMode {
+		Tangent = 0,
+		Chain = 1,
+		ChainScale = 2,
+	}
 }
 declare module spine {
-    class SharedAssetManager implements Disposable {
-        private pathPrefix;
-        private clientAssets;
-        private queuedAssets;
-        private rawAssets;
-        private errors;
-        constructor(pathPrefix?: string);
-        private queueAsset(clientId, textureLoader, path);
-        loadText(clientId: string, path: string): void;
-        loadJson(clientId: string, path: string): void;
-        loadTexture(clientId: string, textureLoader: (image: HTMLImageElement) => any, path: string): void;
-        get(clientId: string, path: string): any;
-        private updateClientAssets(clientAssets);
-        isLoadingComplete(clientId: string): boolean;
-        dispose(): void;
-        hasErrors(): boolean;
-        getErrors(): Map<string>;
-    }
+	class SharedAssetManager implements Disposable {
+		private pathPrefix;
+		private clientAssets;
+		private queuedAssets;
+		private rawAssets;
+		private errors;
+		constructor(pathPrefix?: string);
+		private queueAsset(clientId, textureLoader, path);
+		loadText(clientId: string, path: string): void;
+		loadJson(clientId: string, path: string): void;
+		loadTexture(clientId: string, textureLoader: (image: HTMLImageElement) => any, path: string): void;
+		get(clientId: string, path: string): any;
+		private updateClientAssets(clientAssets);
+		isLoadingComplete(clientId: string): boolean;
+		dispose(): void;
+		hasErrors(): boolean;
+		getErrors(): Map<string>;
+	}
 }
 declare module spine {
-    class Skeleton {
-        data: SkeletonData;
-        bones: Array<Bone>;
-        slots: Array<Slot>;
-        drawOrder: Array<Slot>;
-        ikConstraints: Array<IkConstraint>;
-        transformConstraints: Array<TransformConstraint>;
-        pathConstraints: Array<PathConstraint>;
-        _updateCache: Updatable[];
-        updateCacheReset: Updatable[];
-        skin: Skin;
-        color: Color;
-        time: number;
-        flipX: boolean;
-        flipY: boolean;
-        x: number;
-        y: number;
-        constructor(data: SkeletonData);
-        updateCache(): void;
-        sortIkConstraint(constraint: IkConstraint): void;
-        sortPathConstraint(constraint: PathConstraint): void;
-        sortTransformConstraint(constraint: TransformConstraint): void;
-        sortPathConstraintAttachment(skin: Skin, slotIndex: number, slotBone: Bone): void;
-        sortPathConstraintAttachmentWith(attachment: Attachment, slotBone: Bone): void;
-        sortBone(bone: Bone): void;
-        sortReset(bones: Array<Bone>): void;
-        updateWorldTransform(): void;
-        setToSetupPose(): void;
-        setBonesToSetupPose(): void;
-        setSlotsToSetupPose(): void;
-        getRootBone(): Bone;
-        findBone(boneName: string): Bone;
-        findBoneIndex(boneName: string): number;
-        findSlot(slotName: string): Slot;
-        findSlotIndex(slotName: string): number;
-        setSkinByName(skinName: string): void;
-        setSkin(newSkin: Skin): void;
-        getAttachmentByName(slotName: string, attachmentName: string): Attachment;
-        getAttachment(slotIndex: number, attachmentName: string): Attachment;
-        setAttachment(slotName: string, attachmentName: string): void;
-        findIkConstraint(constraintName: string): IkConstraint;
-        findTransformConstraint(constraintName: string): TransformConstraint;
-        findPathConstraint(constraintName: string): PathConstraint;
-        getBounds(offset: Vector2, size: Vector2, temp: Array<number>): void;
-        update(delta: number): void;
-    }
+	class Skeleton {
+		data: SkeletonData;
+		bones: Array<Bone>;
+		slots: Array<Slot>;
+		drawOrder: Array<Slot>;
+		ikConstraints: Array<IkConstraint>;
+		transformConstraints: Array<TransformConstraint>;
+		pathConstraints: Array<PathConstraint>;
+		_updateCache: Updatable[];
+		updateCacheReset: Updatable[];
+		skin: Skin;
+		color: Color;
+		time: number;
+		flipX: boolean;
+		flipY: boolean;
+		x: number;
+		y: number;
+		constructor(data: SkeletonData);
+		updateCache(): void;
+		sortIkConstraint(constraint: IkConstraint): void;
+		sortPathConstraint(constraint: PathConstraint): void;
+		sortTransformConstraint(constraint: TransformConstraint): void;
+		sortPathConstraintAttachment(skin: Skin, slotIndex: number, slotBone: Bone): void;
+		sortPathConstraintAttachmentWith(attachment: Attachment, slotBone: Bone): void;
+		sortBone(bone: Bone): void;
+		sortReset(bones: Array<Bone>): void;
+		updateWorldTransform(): void;
+		setToSetupPose(): void;
+		setBonesToSetupPose(): void;
+		setSlotsToSetupPose(): void;
+		getRootBone(): Bone;
+		findBone(boneName: string): Bone;
+		findBoneIndex(boneName: string): number;
+		findSlot(slotName: string): Slot;
+		findSlotIndex(slotName: string): number;
+		setSkinByName(skinName: string): void;
+		setSkin(newSkin: Skin): void;
+		getAttachmentByName(slotName: string, attachmentName: string): Attachment;
+		getAttachment(slotIndex: number, attachmentName: string): Attachment;
+		setAttachment(slotName: string, attachmentName: string): void;
+		findIkConstraint(constraintName: string): IkConstraint;
+		findTransformConstraint(constraintName: string): TransformConstraint;
+		findPathConstraint(constraintName: string): PathConstraint;
+		getBounds(offset: Vector2, size: Vector2, temp: Array<number>): void;
+		update(delta: number): void;
+	}
 }
 declare module spine {
-    class SkeletonBounds {
-        minX: number;
-        minY: number;
-        maxX: number;
-        maxY: number;
-        boundingBoxes: BoundingBoxAttachment[];
-        polygons: ArrayLike<number>[];
-        private polygonPool;
-        update(skeleton: Skeleton, updateAabb: boolean): void;
-        aabbCompute(): void;
-        aabbContainsPoint(x: number, y: number): boolean;
-        aabbIntersectsSegment(x1: number, y1: number, x2: number, y2: number): boolean;
-        aabbIntersectsSkeleton(bounds: SkeletonBounds): boolean;
-        containsPoint(x: number, y: number): BoundingBoxAttachment;
-        containsPointPolygon(polygon: ArrayLike<number>, x: number, y: number): boolean;
-        intersectsSegment(x1: number, y1: number, x2: number, y2: number): BoundingBoxAttachment;
-        intersectsSegmentPolygon(polygon: ArrayLike<number>, x1: number, y1: number, x2: number, y2: number): boolean;
-        getPolygon(boundingBox: BoundingBoxAttachment): ArrayLike<number>;
-        getWidth(): number;
-        getHeight(): number;
-    }
+	class SkeletonBounds {
+		minX: number;
+		minY: number;
+		maxX: number;
+		maxY: number;
+		boundingBoxes: BoundingBoxAttachment[];
+		polygons: ArrayLike<number>[];
+		private polygonPool;
+		update(skeleton: Skeleton, updateAabb: boolean): void;
+		aabbCompute(): void;
+		aabbContainsPoint(x: number, y: number): boolean;
+		aabbIntersectsSegment(x1: number, y1: number, x2: number, y2: number): boolean;
+		aabbIntersectsSkeleton(bounds: SkeletonBounds): boolean;
+		containsPoint(x: number, y: number): BoundingBoxAttachment;
+		containsPointPolygon(polygon: ArrayLike<number>, x: number, y: number): boolean;
+		intersectsSegment(x1: number, y1: number, x2: number, y2: number): BoundingBoxAttachment;
+		intersectsSegmentPolygon(polygon: ArrayLike<number>, x1: number, y1: number, x2: number, y2: number): boolean;
+		getPolygon(boundingBox: BoundingBoxAttachment): ArrayLike<number>;
+		getWidth(): number;
+		getHeight(): number;
+	}
 }
 declare module spine {
-    class SkeletonClipping {
-        private decomposer;
-        private clippingPolygon;
-        private clipOutput;
-        private clippedVertices;
-        private clippedTriangles;
-        private scratch;
-        private clipAttachment;
-        private clippingPolygons;
-        clipStart(slot: Slot, clip: ClippingAttachment): void;
-        clipEndWithSlot(slot: Slot): void;
-        clipEnd(): void;
-        isClipping(): boolean;
-        clipTriangles(vertices: ArrayLike<number>, verticesLength: number, triangles: ArrayLike<number>, trianglesLength: number, uvs: ArrayLike<number>, light: Color, dark: Color, twoColor: boolean): void;
-        clip(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, clippingArea: Array<number>, output: Array<number>): boolean;
-        static makeClockwise(polygon: ArrayLike<number>): void;
-    }
+	class SkeletonClipping {
+		private decomposer;
+		private clippingPolygon;
+		private clipOutput;
+		clippedVertices: number[];
+		clippedTriangles: number[];
+		private scratch;
+		private clipAttachment;
+		private clippingPolygons;
+		clipStart(slot: Slot, clip: ClippingAttachment): void;
+		clipEndWithSlot(slot: Slot): void;
+		clipEnd(): void;
+		isClipping(): boolean;
+		clipTriangles(vertices: ArrayLike<number>, verticesLength: number, triangles: ArrayLike<number>, trianglesLength: number, uvs: ArrayLike<number>, light: Color, dark: Color, twoColor: boolean): void;
+		clip(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, clippingArea: Array<number>, output: Array<number>): boolean;
+		static makeClockwise(polygon: ArrayLike<number>): void;
+	}
 }
 declare module spine {
-    class SkeletonData {
-        name: string;
-        bones: BoneData[];
-        slots: SlotData[];
-        skins: Skin[];
-        defaultSkin: Skin;
-        events: EventData[];
-        animations: Animation[];
-        ikConstraints: IkConstraintData[];
-        transformConstraints: TransformConstraintData[];
-        pathConstraints: PathConstraintData[];
-        width: number;
-        height: number;
-        version: string;
-        hash: string;
-        fps: number;
-        imagesPath: string;
-        findBone(boneName: string): BoneData;
-        findBoneIndex(boneName: string): number;
-        findSlot(slotName: string): SlotData;
-        findSlotIndex(slotName: string): number;
-        findSkin(skinName: string): Skin;
-        findEvent(eventDataName: string): EventData;
-        findAnimation(animationName: string): Animation;
-        findIkConstraint(constraintName: string): IkConstraintData;
-        findTransformConstraint(constraintName: string): TransformConstraintData;
-        findPathConstraint(constraintName: string): PathConstraintData;
-        findPathConstraintIndex(pathConstraintName: string): number;
-    }
+	class SkeletonData {
+		name: string;
+		bones: BoneData[];
+		slots: SlotData[];
+		skins: Skin[];
+		defaultSkin: Skin;
+		events: EventData[];
+		animations: Animation[];
+		ikConstraints: IkConstraintData[];
+		transformConstraints: TransformConstraintData[];
+		pathConstraints: PathConstraintData[];
+		width: number;
+		height: number;
+		version: string;
+		hash: string;
+		fps: number;
+		imagesPath: string;
+		findBone(boneName: string): BoneData;
+		findBoneIndex(boneName: string): number;
+		findSlot(slotName: string): SlotData;
+		findSlotIndex(slotName: string): number;
+		findSkin(skinName: string): Skin;
+		findEvent(eventDataName: string): EventData;
+		findAnimation(animationName: string): Animation;
+		findIkConstraint(constraintName: string): IkConstraintData;
+		findTransformConstraint(constraintName: string): TransformConstraintData;
+		findPathConstraint(constraintName: string): PathConstraintData;
+		findPathConstraintIndex(pathConstraintName: string): number;
+	}
 }
 declare module spine {
-    class SkeletonJson {
-        attachmentLoader: AttachmentLoader;
-        scale: number;
-        private linkedMeshes;
-        constructor(attachmentLoader: AttachmentLoader);
-        readSkeletonData(json: string | any): SkeletonData;
-        readAttachment(map: any, skin: Skin, slotIndex: number, name: string, skeletonData: SkeletonData): Attachment;
-        readVertices(map: any, attachment: VertexAttachment, verticesLength: number): void;
-        readAnimation(map: any, name: string, skeletonData: SkeletonData): void;
-        readCurve(map: any, timeline: CurveTimeline, frameIndex: number): void;
-        getValue(map: any, prop: string, defaultValue: any): any;
-        static blendModeFromString(str: string): BlendMode;
-        static positionModeFromString(str: string): PositionMode;
-        static spacingModeFromString(str: string): SpacingMode;
-        static rotateModeFromString(str: string): RotateMode;
-        static transformModeFromString(str: string): TransformMode;
-    }
+	class SkeletonJson {
+		attachmentLoader: AttachmentLoader;
+		scale: number;
+		private linkedMeshes;
+		constructor(attachmentLoader: AttachmentLoader);
+		readSkeletonData(json: string | any): SkeletonData;
+		readAttachment(map: any, skin: Skin, slotIndex: number, name: string, skeletonData: SkeletonData): Attachment;
+		readVertices(map: any, attachment: VertexAttachment, verticesLength: number): void;
+		readAnimation(map: any, name: string, skeletonData: SkeletonData): void;
+		readCurve(map: any, timeline: CurveTimeline, frameIndex: number): void;
+		getValue(map: any, prop: string, defaultValue: any): any;
+		static blendModeFromString(str: string): BlendMode;
+		static positionModeFromString(str: string): PositionMode;
+		static spacingModeFromString(str: string): SpacingMode;
+		static rotateModeFromString(str: string): RotateMode;
+		static transformModeFromString(str: string): TransformMode;
+	}
 }
 declare module spine {
-    class Skin {
-        name: string;
-        attachments: Map<Attachment>[];
-        constructor(name: string);
-        addAttachment(slotIndex: number, name: string, attachment: Attachment): void;
-        getAttachment(slotIndex: number, name: string): Attachment;
-        attachAll(skeleton: Skeleton, oldSkin: Skin): void;
-    }
+	class Skin {
+		name: string;
+		attachments: Map<Attachment>[];
+		constructor(name: string);
+		addAttachment(slotIndex: number, name: string, attachment: Attachment): void;
+		getAttachment(slotIndex: number, name: string): Attachment;
+		attachAll(skeleton: Skeleton, oldSkin: Skin): void;
+	}
 }
 declare module spine {
-    class Slot {
-        data: SlotData;
-        bone: Bone;
-        color: Color;
-        darkColor: Color;
-        private attachment;
-        private attachmentTime;
-        attachmentVertices: number[];
-        constructor(data: SlotData, bone: Bone);
-        getAttachment(): Attachment;
-        setAttachment(attachment: Attachment): void;
-        setAttachmentTime(time: number): void;
-        getAttachmentTime(): number;
-        setToSetupPose(): void;
-    }
+	class Slot {
+		data: SlotData;
+		bone: Bone;
+		color: Color;
+		darkColor: Color;
+		private attachment;
+		private attachmentTime;
+		attachmentVertices: number[];
+		constructor(data: SlotData, bone: Bone);
+		getAttachment(): Attachment;
+		setAttachment(attachment: Attachment): void;
+		setAttachmentTime(time: number): void;
+		getAttachmentTime(): number;
+		setToSetupPose(): void;
+	}
 }
 declare module spine {
-    class SlotData {
-        index: number;
-        name: string;
-        boneData: BoneData;
-        color: Color;
-        darkColor: Color;
-        attachmentName: string;
-        blendMode: BlendMode;
-        constructor(index: number, name: string, boneData: BoneData);
-    }
+	class SlotData {
+		index: number;
+		name: string;
+		boneData: BoneData;
+		color: Color;
+		darkColor: Color;
+		attachmentName: string;
+		blendMode: BlendMode;
+		constructor(index: number, name: string, boneData: BoneData);
+	}
 }
 declare module spine {
-    abstract class Texture {
-        protected _image: HTMLImageElement;
-        constructor(image: HTMLImageElement);
-        getImage(): HTMLImageElement;
-        abstract setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
-        abstract setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
-        abstract dispose(): void;
-        static filterFromString(text: string): TextureFilter;
-        static wrapFromString(text: string): TextureWrap;
-    }
-    enum TextureFilter {
-        Nearest = 9728,
-        Linear = 9729,
-        MipMap = 9987,
-        MipMapNearestNearest = 9984,
-        MipMapLinearNearest = 9985,
-        MipMapNearestLinear = 9986,
-        MipMapLinearLinear = 9987,
-    }
-    enum TextureWrap {
-        MirroredRepeat = 33648,
-        ClampToEdge = 33071,
-        Repeat = 10497,
-    }
-    class TextureRegion {
-        renderObject: any;
-        u: number;
-        v: number;
-        u2: number;
-        v2: number;
-        width: number;
-        height: number;
-        rotate: boolean;
-        offsetX: number;
-        offsetY: number;
-        originalWidth: number;
-        originalHeight: number;
-    }
+	abstract class Texture {
+		protected _image: HTMLImageElement;
+		constructor(image: HTMLImageElement);
+		getImage(): HTMLImageElement;
+		abstract setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
+		abstract setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
+		abstract dispose(): void;
+		static filterFromString(text: string): TextureFilter;
+		static wrapFromString(text: string): TextureWrap;
+	}
+	enum TextureFilter {
+		Nearest = 9728,
+		Linear = 9729,
+		MipMap = 9987,
+		MipMapNearestNearest = 9984,
+		MipMapLinearNearest = 9985,
+		MipMapNearestLinear = 9986,
+		MipMapLinearLinear = 9987,
+	}
+	enum TextureWrap {
+		MirroredRepeat = 33648,
+		ClampToEdge = 33071,
+		Repeat = 10497,
+	}
+	class TextureRegion {
+		renderObject: any;
+		u: number;
+		v: number;
+		u2: number;
+		v2: number;
+		width: number;
+		height: number;
+		rotate: boolean;
+		offsetX: number;
+		offsetY: number;
+		originalWidth: number;
+		originalHeight: number;
+	}
 }
 declare module spine {
-    class TextureAtlas implements Disposable {
-        pages: TextureAtlasPage[];
-        regions: TextureAtlasRegion[];
-        constructor(atlasText: string, textureLoader: (path: string) => any);
-        private load(atlasText, textureLoader);
-        findRegion(name: string): TextureAtlasRegion;
-        dispose(): void;
-    }
-    class TextureAtlasPage {
-        name: string;
-        minFilter: TextureFilter;
-        magFilter: TextureFilter;
-        uWrap: TextureWrap;
-        vWrap: TextureWrap;
-        texture: Texture;
-        width: number;
-        height: number;
-    }
-    class TextureAtlasRegion extends TextureRegion {
-        page: TextureAtlasPage;
-        name: string;
-        x: number;
-        y: number;
-        index: number;
-        rotate: boolean;
-        texture: Texture;
-    }
+	class TextureAtlas implements Disposable {
+		pages: TextureAtlasPage[];
+		regions: TextureAtlasRegion[];
+		constructor(atlasText: string, textureLoader: (path: string) => any);
+		private load(atlasText, textureLoader);
+		findRegion(name: string): TextureAtlasRegion;
+		dispose(): void;
+	}
+	class TextureAtlasPage {
+		name: string;
+		minFilter: TextureFilter;
+		magFilter: TextureFilter;
+		uWrap: TextureWrap;
+		vWrap: TextureWrap;
+		texture: Texture;
+		width: number;
+		height: number;
+	}
+	class TextureAtlasRegion extends TextureRegion {
+		page: TextureAtlasPage;
+		name: string;
+		x: number;
+		y: number;
+		index: number;
+		rotate: boolean;
+		texture: Texture;
+	}
 }
 declare module spine {
-    class TransformConstraint implements Constraint {
-        data: TransformConstraintData;
-        bones: Array<Bone>;
-        target: Bone;
-        rotateMix: number;
-        translateMix: number;
-        scaleMix: number;
-        shearMix: number;
-        temp: Vector2;
-        constructor(data: TransformConstraintData, skeleton: Skeleton);
-        apply(): void;
-        update(): void;
-        applyAbsoluteWorld(): void;
-        applyRelativeWorld(): void;
-        applyAbsoluteLocal(): void;
-        applyRelativeLocal(): void;
-        getOrder(): number;
-    }
+	class TransformConstraint implements Constraint {
+		data: TransformConstraintData;
+		bones: Array<Bone>;
+		target: Bone;
+		rotateMix: number;
+		translateMix: number;
+		scaleMix: number;
+		shearMix: number;
+		temp: Vector2;
+		constructor(data: TransformConstraintData, skeleton: Skeleton);
+		apply(): void;
+		update(): void;
+		applyAbsoluteWorld(): void;
+		applyRelativeWorld(): void;
+		applyAbsoluteLocal(): void;
+		applyRelativeLocal(): void;
+		getOrder(): number;
+	}
 }
 declare module spine {
-    class TransformConstraintData {
-        name: string;
-        order: number;
-        bones: BoneData[];
-        target: BoneData;
-        rotateMix: number;
-        translateMix: number;
-        scaleMix: number;
-        shearMix: number;
-        offsetRotation: number;
-        offsetX: number;
-        offsetY: number;
-        offsetScaleX: number;
-        offsetScaleY: number;
-        offsetShearY: number;
-        relative: boolean;
-        local: boolean;
-        constructor(name: string);
-    }
+	class TransformConstraintData {
+		name: string;
+		order: number;
+		bones: BoneData[];
+		target: BoneData;
+		rotateMix: number;
+		translateMix: number;
+		scaleMix: number;
+		shearMix: number;
+		offsetRotation: number;
+		offsetX: number;
+		offsetY: number;
+		offsetScaleX: number;
+		offsetScaleY: number;
+		offsetShearY: number;
+		relative: boolean;
+		local: boolean;
+		constructor(name: string);
+	}
 }
 declare module spine {
-    interface Updatable {
-        update(): void;
-    }
+	interface Updatable {
+		update(): void;
+	}
 }
 declare module spine {
-    interface Map<T> {
-        [key: string]: T;
-    }
-    class IntSet {
-        array: number[];
-        add(value: number): boolean;
-        contains(value: number): boolean;
-        remove(value: number): void;
-        clear(): void;
-    }
-    interface Disposable {
-        dispose(): void;
-    }
-    class Color {
-        r: number;
-        g: number;
-        b: number;
-        a: number;
-        static WHITE: Color;
-        static RED: Color;
-        static GREEN: Color;
-        static BLUE: Color;
-        static MAGENTA: Color;
-        constructor(r?: number, g?: number, b?: number, a?: number);
-        set(r: number, g: number, b: number, a: number): this;
-        setFromColor(c: Color): this;
-        setFromString(hex: string): this;
-        add(r: number, g: number, b: number, a: number): this;
-        clamp(): this;
-    }
-    class MathUtils {
-        static PI: number;
-        static PI2: number;
-        static radiansToDegrees: number;
-        static radDeg: number;
-        static degreesToRadians: number;
-        static degRad: number;
-        static clamp(value: number, min: number, max: number): number;
-        static cosDeg(degrees: number): number;
-        static sinDeg(degrees: number): number;
-        static signum(value: number): number;
-        static toInt(x: number): number;
-        static cbrt(x: number): number;
-    }
-    class Utils {
-        static SUPPORTS_TYPED_ARRAYS: boolean;
-        static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
-        static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
-        static ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
-        static newArray<T>(size: number, defaultValue: T): Array<T>;
-        static newFloatArray(size: number): ArrayLike<number>;
-        static newShortArray(size: number): ArrayLike<number>;
-        static toFloatArray(array: Array<number>): number[] | Float32Array;
-    }
-    class DebugUtils {
-        static logBones(skeleton: Skeleton): void;
-    }
-    class Pool<T> {
-        private items;
-        private instantiator;
-        constructor(instantiator: () => T);
-        obtain(): T;
-        free(item: T): void;
-        freeAll(items: ArrayLike<T>): void;
-        clear(): void;
-    }
-    class Vector2 {
-        x: number;
-        y: number;
-        constructor(x?: number, y?: number);
-        set(x: number, y: number): Vector2;
-        length(): number;
-        normalize(): this;
-    }
-    class TimeKeeper {
-        maxDelta: number;
-        framesPerSecond: number;
-        delta: number;
-        totalTime: number;
-        private lastTime;
-        private frameCount;
-        private frameTime;
-        update(): void;
-    }
-    interface ArrayLike<T> {
-        length: number;
-        [n: number]: T;
-    }
-    class WindowedMean {
-        values: Array<number>;
-        addedValues: number;
-        lastValue: number;
-        mean: number;
-        dirty: boolean;
-        constructor(windowSize?: number);
-        hasEnoughData(): boolean;
-        addValue(value: number): void;
-        getMean(): number;
-    }
+	interface Map<T> {
+		[key: string]: T;
+	}
+	class IntSet {
+		array: number[];
+		add(value: number): boolean;
+		contains(value: number): boolean;
+		remove(value: number): void;
+		clear(): void;
+	}
+	interface Disposable {
+		dispose(): void;
+	}
+	class Color {
+		r: number;
+		g: number;
+		b: number;
+		a: number;
+		static WHITE: Color;
+		static RED: Color;
+		static GREEN: Color;
+		static BLUE: Color;
+		static MAGENTA: Color;
+		constructor(r?: number, g?: number, b?: number, a?: number);
+		set(r: number, g: number, b: number, a: number): this;
+		setFromColor(c: Color): this;
+		setFromString(hex: string): this;
+		add(r: number, g: number, b: number, a: number): this;
+		clamp(): this;
+	}
+	class MathUtils {
+		static PI: number;
+		static PI2: number;
+		static radiansToDegrees: number;
+		static radDeg: number;
+		static degreesToRadians: number;
+		static degRad: number;
+		static clamp(value: number, min: number, max: number): number;
+		static cosDeg(degrees: number): number;
+		static sinDeg(degrees: number): number;
+		static signum(value: number): number;
+		static toInt(x: number): number;
+		static cbrt(x: number): number;
+	}
+	class Utils {
+		static SUPPORTS_TYPED_ARRAYS: boolean;
+		static arrayCopy<T>(source: ArrayLike<T>, sourceStart: number, dest: ArrayLike<T>, destStart: number, numElements: number): void;
+		static setArraySize<T>(array: Array<T>, size: number, value?: any): Array<T>;
+		static ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
+		static newArray<T>(size: number, defaultValue: T): Array<T>;
+		static newFloatArray(size: number): ArrayLike<number>;
+		static newShortArray(size: number): ArrayLike<number>;
+		static toFloatArray(array: Array<number>): number[] | Float32Array;
+	}
+	class DebugUtils {
+		static logBones(skeleton: Skeleton): void;
+	}
+	class Pool<T> {
+		private items;
+		private instantiator;
+		constructor(instantiator: () => T);
+		obtain(): T;
+		free(item: T): void;
+		freeAll(items: ArrayLike<T>): void;
+		clear(): void;
+	}
+	class Vector2 {
+		x: number;
+		y: number;
+		constructor(x?: number, y?: number);
+		set(x: number, y: number): Vector2;
+		length(): number;
+		normalize(): this;
+	}
+	class TimeKeeper {
+		maxDelta: number;
+		framesPerSecond: number;
+		delta: number;
+		totalTime: number;
+		private lastTime;
+		private frameCount;
+		private frameTime;
+		update(): void;
+	}
+	interface ArrayLike<T> {
+		length: number;
+		[n: number]: T;
+	}
+	class WindowedMean {
+		values: Array<number>;
+		addedValues: number;
+		lastValue: number;
+		mean: number;
+		dirty: boolean;
+		constructor(windowSize?: number);
+		hasEnoughData(): boolean;
+		addValue(value: number): void;
+		getMean(): number;
+	}
 }
 declare module spine.webgl {
-    class AssetManager extends spine.AssetManager {
-        constructor(gl: WebGLRenderingContext, pathPrefix?: string);
-    }
+	class AssetManager extends spine.AssetManager {
+		constructor(gl: WebGLRenderingContext, pathPrefix?: string);
+	}
 }
 declare module spine.webgl {
-    class OrthoCamera {
-        position: Vector3;
-        direction: Vector3;
-        up: Vector3;
-        near: number;
-        far: number;
-        zoom: number;
-        viewportWidth: number;
-        viewportHeight: number;
-        projectionView: Matrix4;
-        inverseProjectionView: Matrix4;
-        projection: Matrix4;
-        view: Matrix4;
-        private tmp;
-        constructor(viewportWidth: number, viewportHeight: number);
-        update(): void;
-        screenToWorld(screenCoords: Vector3, screenWidth: number, screenHeight: number): Vector3;
-        setViewport(viewportWidth: number, viewportHeight: number): void;
-    }
+	class OrthoCamera {
+		position: Vector3;
+		direction: Vector3;
+		up: Vector3;
+		near: number;
+		far: number;
+		zoom: number;
+		viewportWidth: number;
+		viewportHeight: number;
+		projectionView: Matrix4;
+		inverseProjectionView: Matrix4;
+		projection: Matrix4;
+		view: Matrix4;
+		private tmp;
+		constructor(viewportWidth: number, viewportHeight: number);
+		update(): void;
+		screenToWorld(screenCoords: Vector3, screenWidth: number, screenHeight: number): Vector3;
+		setViewport(viewportWidth: number, viewportHeight: number): void;
+	}
 }
 declare module spine.webgl {
-    class GLTexture extends Texture implements Disposable {
-        private gl;
-        private texture;
-        private boundUnit;
-        constructor(gl: WebGLRenderingContext, image: HTMLImageElement, useMipMaps?: boolean);
-        setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
-        setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
-        update(useMipMaps: boolean): void;
-        bind(unit?: number): void;
-        unbind(): void;
-        dispose(): void;
-    }
+	class GLTexture extends Texture implements Disposable {
+		private gl;
+		private texture;
+		private boundUnit;
+		constructor(gl: WebGLRenderingContext, image: HTMLImageElement, useMipMaps?: boolean);
+		setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
+		setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
+		update(useMipMaps: boolean): void;
+		bind(unit?: number): void;
+		unbind(): void;
+		dispose(): void;
+	}
 }
 declare module spine.webgl {
-    class Input {
-        element: HTMLElement;
-        lastX: number;
-        lastY: number;
-        buttonDown: boolean;
-        currTouch: Touch;
-        touchesPool: Pool<Touch>;
-        private listeners;
-        constructor(element: HTMLElement);
-        private setupCallbacks(element);
-        addListener(listener: InputListener): void;
-        removeListener(listener: InputListener): void;
-    }
-    class Touch {
-        identifier: number;
-        x: number;
-        y: number;
-        constructor(identifier: number, x: number, y: number);
-    }
-    interface InputListener {
-        down(x: number, y: number): void;
-        up(x: number, y: number): void;
-        moved(x: number, y: number): void;
-        dragged(x: number, y: number): void;
-    }
+	class Input {
+		element: HTMLElement;
+		lastX: number;
+		lastY: number;
+		buttonDown: boolean;
+		currTouch: Touch;
+		touchesPool: Pool<Touch>;
+		private listeners;
+		constructor(element: HTMLElement);
+		private setupCallbacks(element);
+		addListener(listener: InputListener): void;
+		removeListener(listener: InputListener): void;
+	}
+	class Touch {
+		identifier: number;
+		x: number;
+		y: number;
+		constructor(identifier: number, x: number, y: number);
+	}
+	interface InputListener {
+		down(x: number, y: number): void;
+		up(x: number, y: number): void;
+		moved(x: number, y: number): void;
+		dragged(x: number, y: number): void;
+	}
 }
 declare module spine.webgl {
-    class LoadingScreen {
-        static FADE_SECONDS: number;
-        private static loaded;
-        private static spinnerImg;
-        private static logoImg;
-        private renderer;
-        private logo;
-        private spinner;
-        private angle;
-        private fadeOut;
-        private timeKeeper;
-        backgroundColor: Color;
-        private tempColor;
-        private firstDraw;
-        private static SPINNER_DATA;
-        private static SPINE_LOGO_DATA;
-        constructor(renderer: SceneRenderer);
-        draw(complete?: boolean): void;
-    }
+	class LoadingScreen {
+		static FADE_SECONDS: number;
+		private static loaded;
+		private static spinnerImg;
+		private static logoImg;
+		private renderer;
+		private logo;
+		private spinner;
+		private angle;
+		private fadeOut;
+		private timeKeeper;
+		backgroundColor: Color;
+		private tempColor;
+		private firstDraw;
+		private static SPINNER_DATA;
+		private static SPINE_LOGO_DATA;
+		constructor(renderer: SceneRenderer);
+		draw(complete?: boolean): void;
+	}
 }
 declare module spine.webgl {
-    const M00: number;
-    const M01: number;
-    const M02: number;
-    const M03: number;
-    const M10: number;
-    const M11: number;
-    const M12: number;
-    const M13: number;
-    const M20: number;
-    const M21: number;
-    const M22: number;
-    const M23: number;
-    const M30: number;
-    const M31: number;
-    const M32: number;
-    const M33: number;
-    class Matrix4 {
-        temp: Float32Array;
-        values: Float32Array;
-        private static xAxis;
-        private static yAxis;
-        private static zAxis;
-        private static tmpMatrix;
-        constructor();
-        set(values: ArrayLike<number>): Matrix4;
-        transpose(): Matrix4;
-        identity(): Matrix4;
-        invert(): Matrix4;
-        determinant(): number;
-        translate(x: number, y: number, z: number): Matrix4;
-        copy(): Matrix4;
-        projection(near: number, far: number, fovy: number, aspectRatio: number): Matrix4;
-        ortho2d(x: number, y: number, width: number, height: number): Matrix4;
-        ortho(left: number, right: number, bottom: number, top: number, near: number, far: number): Matrix4;
-        multiply(matrix: Matrix4): Matrix4;
-        multiplyLeft(matrix: Matrix4): Matrix4;
-        lookAt(position: Vector3, direction: Vector3, up: Vector3): this;
-        static initTemps(): void;
-    }
+	const M00: number;
+	const M01: number;
+	const M02: number;
+	const M03: number;
+	const M10: number;
+	const M11: number;
+	const M12: number;
+	const M13: number;
+	const M20: number;
+	const M21: number;
+	const M22: number;
+	const M23: number;
+	const M30: number;
+	const M31: number;
+	const M32: number;
+	const M33: number;
+	class Matrix4 {
+		temp: Float32Array;
+		values: Float32Array;
+		private static xAxis;
+		private static yAxis;
+		private static zAxis;
+		private static tmpMatrix;
+		constructor();
+		set(values: ArrayLike<number>): Matrix4;
+		transpose(): Matrix4;
+		identity(): Matrix4;
+		invert(): Matrix4;
+		determinant(): number;
+		translate(x: number, y: number, z: number): Matrix4;
+		copy(): Matrix4;
+		projection(near: number, far: number, fovy: number, aspectRatio: number): Matrix4;
+		ortho2d(x: number, y: number, width: number, height: number): Matrix4;
+		ortho(left: number, right: number, bottom: number, top: number, near: number, far: number): Matrix4;
+		multiply(matrix: Matrix4): Matrix4;
+		multiplyLeft(matrix: Matrix4): Matrix4;
+		lookAt(position: Vector3, direction: Vector3, up: Vector3): this;
+		static initTemps(): void;
+	}
 }
 declare module spine.webgl {
-    class Mesh implements Disposable {
-        private attributes;
-        private gl;
-        private vertices;
-        private verticesBuffer;
-        private verticesLength;
-        private dirtyVertices;
-        private indices;
-        private indicesBuffer;
-        private indicesLength;
-        private dirtyIndices;
-        private elementsPerVertex;
-        getAttributes(): VertexAttribute[];
-        maxVertices(): number;
-        numVertices(): number;
-        setVerticesLength(length: number): void;
-        getVertices(): Float32Array;
-        maxIndices(): number;
-        numIndices(): number;
-        setIndicesLength(length: number): void;
-        getIndices(): Uint16Array;
-        getVertexSizeInFloats(): number;
-        constructor(gl: WebGLRenderingContext, attributes: VertexAttribute[], maxVertices: number, maxIndices: number);
-        setVertices(vertices: Array<number>): void;
-        setIndices(indices: Array<number>): void;
-        draw(shader: Shader, primitiveType: number): void;
-        drawWithOffset(shader: Shader, primitiveType: number, offset: number, count: number): void;
-        bind(shader: Shader): void;
-        unbind(shader: Shader): void;
-        private update();
-        dispose(): void;
-    }
-    class VertexAttribute {
-        name: string;
-        type: VertexAttributeType;
-        numElements: number;
-        constructor(name: string, type: VertexAttributeType, numElements: number);
-    }
-    class Position2Attribute extends VertexAttribute {
-        constructor();
-    }
-    class Position3Attribute extends VertexAttribute {
-        constructor();
-    }
-    class TexCoordAttribute extends VertexAttribute {
-        constructor(unit?: number);
-    }
-    class ColorAttribute extends VertexAttribute {
-        constructor();
-    }
-    class Color2Attribute extends VertexAttribute {
-        constructor();
-    }
-    enum VertexAttributeType {
-        Float = 0,
-    }
+	class Mesh implements Disposable {
+		private attributes;
+		private gl;
+		private vertices;
+		private verticesBuffer;
+		private verticesLength;
+		private dirtyVertices;
+		private indices;
+		private indicesBuffer;
+		private indicesLength;
+		private dirtyIndices;
+		private elementsPerVertex;
+		getAttributes(): VertexAttribute[];
+		maxVertices(): number;
+		numVertices(): number;
+		setVerticesLength(length: number): void;
+		getVertices(): Float32Array;
+		maxIndices(): number;
+		numIndices(): number;
+		setIndicesLength(length: number): void;
+		getIndices(): Uint16Array;
+		getVertexSizeInFloats(): number;
+		constructor(gl: WebGLRenderingContext, attributes: VertexAttribute[], maxVertices: number, maxIndices: number);
+		setVertices(vertices: Array<number>): void;
+		setIndices(indices: Array<number>): void;
+		draw(shader: Shader, primitiveType: number): void;
+		drawWithOffset(shader: Shader, primitiveType: number, offset: number, count: number): void;
+		bind(shader: Shader): void;
+		unbind(shader: Shader): void;
+		private update();
+		dispose(): void;
+	}
+	class VertexAttribute {
+		name: string;
+		type: VertexAttributeType;
+		numElements: number;
+		constructor(name: string, type: VertexAttributeType, numElements: number);
+	}
+	class Position2Attribute extends VertexAttribute {
+		constructor();
+	}
+	class Position3Attribute extends VertexAttribute {
+		constructor();
+	}
+	class TexCoordAttribute extends VertexAttribute {
+		constructor(unit?: number);
+	}
+	class ColorAttribute extends VertexAttribute {
+		constructor();
+	}
+	class Color2Attribute extends VertexAttribute {
+		constructor();
+	}
+	enum VertexAttributeType {
+		Float = 0,
+	}
 }
 declare module spine.webgl {
-    class PolygonBatcher implements Disposable {
-        private gl;
-        private drawCalls;
-        private isDrawing;
-        private mesh;
-        private shader;
-        private lastTexture;
-        private verticesLength;
-        private indicesLength;
-        private srcBlend;
-        private dstBlend;
-        constructor(gl: WebGLRenderingContext, twoColorTint?: boolean, maxVertices?: number);
-        begin(shader: Shader): void;
-        setBlendMode(srcBlend: number, dstBlend: number): void;
-        draw(texture: GLTexture, vertices: ArrayLike<number>, indices: Array<number>): void;
-        private flush();
-        end(): void;
-        getDrawCalls(): number;
-        dispose(): void;
-    }
+	class PolygonBatcher implements Disposable {
+		private gl;
+		private drawCalls;
+		private isDrawing;
+		private mesh;
+		private shader;
+		private lastTexture;
+		private verticesLength;
+		private indicesLength;
+		private srcBlend;
+		private dstBlend;
+		constructor(gl: WebGLRenderingContext, twoColorTint?: boolean, maxVertices?: number);
+		begin(shader: Shader): void;
+		setBlendMode(srcBlend: number, dstBlend: number): void;
+		draw(texture: GLTexture, vertices: ArrayLike<number>, indices: Array<number>): void;
+		private flush();
+		end(): void;
+		getDrawCalls(): number;
+		dispose(): void;
+	}
 }
 declare module spine.webgl {
-    class SceneRenderer implements Disposable {
-        gl: WebGLRenderingContext;
-        canvas: HTMLCanvasElement;
-        camera: OrthoCamera;
-        batcher: PolygonBatcher;
-        private twoColorTint;
-        private batcherShader;
-        private shapes;
-        private shapesShader;
-        private activeRenderer;
-        private skeletonRenderer;
-        private skeletonDebugRenderer;
-        private QUAD;
-        private QUAD_TRIANGLES;
-        private WHITE;
-        constructor(canvas: HTMLCanvasElement, gl: WebGLRenderingContext, twoColorTint?: boolean);
-        begin(): void;
-        drawSkeleton(skeleton: Skeleton, premultipliedAlpha?: boolean): void;
-        drawSkeletonDebug(skeleton: Skeleton, premultipliedAlpha?: boolean, ignoredBones?: Array<string>): void;
-        drawTexture(texture: GLTexture, x: number, y: number, width: number, height: number, color?: Color): void;
-        drawTextureRotated(texture: GLTexture, x: number, y: number, width: number, height: number, pivotX: number, pivotY: number, angle: number, color?: Color, premultipliedAlpha?: boolean): void;
-        drawRegion(region: TextureAtlasRegion, x: number, y: number, width: number, height: number, color?: Color, premultipliedAlpha?: boolean): void;
-        line(x: number, y: number, x2: number, y2: number, color?: Color, color2?: Color): void;
-        triangle(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, color?: Color, color2?: Color, color3?: Color): void;
-        quad(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number, color?: Color, color2?: Color, color3?: Color, color4?: Color): void;
-        rect(filled: boolean, x: number, y: number, width: number, height: number, color?: Color): void;
-        rectLine(filled: boolean, x1: number, y1: number, x2: number, y2: number, width: number, color?: Color): void;
-        polygon(polygonVertices: ArrayLike<number>, offset: number, count: number, color?: Color): void;
-        circle(filled: boolean, x: number, y: number, radius: number, color?: Color, segments?: number): void;
-        curve(x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color?: Color): void;
-        end(): void;
-        resize(resizeMode: ResizeMode): void;
-        private enableRenderer(renderer);
-        dispose(): void;
-    }
-    enum ResizeMode {
-        Stretch = 0,
-        Expand = 1,
-        Fit = 2,
-    }
+	class SceneRenderer implements Disposable {
+		gl: WebGLRenderingContext;
+		canvas: HTMLCanvasElement;
+		camera: OrthoCamera;
+		batcher: PolygonBatcher;
+		private twoColorTint;
+		private batcherShader;
+		private shapes;
+		private shapesShader;
+		private activeRenderer;
+		private skeletonRenderer;
+		private skeletonDebugRenderer;
+		private QUAD;
+		private QUAD_TRIANGLES;
+		private WHITE;
+		constructor(canvas: HTMLCanvasElement, gl: WebGLRenderingContext, twoColorTint?: boolean);
+		begin(): void;
+		drawSkeleton(skeleton: Skeleton, premultipliedAlpha?: boolean): void;
+		drawSkeletonDebug(skeleton: Skeleton, premultipliedAlpha?: boolean, ignoredBones?: Array<string>): void;
+		drawTexture(texture: GLTexture, x: number, y: number, width: number, height: number, color?: Color): void;
+		drawTextureRotated(texture: GLTexture, x: number, y: number, width: number, height: number, pivotX: number, pivotY: number, angle: number, color?: Color, premultipliedAlpha?: boolean): void;
+		drawRegion(region: TextureAtlasRegion, x: number, y: number, width: number, height: number, color?: Color, premultipliedAlpha?: boolean): void;
+		line(x: number, y: number, x2: number, y2: number, color?: Color, color2?: Color): void;
+		triangle(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, color?: Color, color2?: Color, color3?: Color): void;
+		quad(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number, color?: Color, color2?: Color, color3?: Color, color4?: Color): void;
+		rect(filled: boolean, x: number, y: number, width: number, height: number, color?: Color): void;
+		rectLine(filled: boolean, x1: number, y1: number, x2: number, y2: number, width: number, color?: Color): void;
+		polygon(polygonVertices: ArrayLike<number>, offset: number, count: number, color?: Color): void;
+		circle(filled: boolean, x: number, y: number, radius: number, color?: Color, segments?: number): void;
+		curve(x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color?: Color): void;
+		end(): void;
+		resize(resizeMode: ResizeMode): void;
+		private enableRenderer(renderer);
+		dispose(): void;
+	}
+	enum ResizeMode {
+		Stretch = 0,
+		Expand = 1,
+		Fit = 2,
+	}
 }
 declare module spine.webgl {
-    class Shader implements Disposable {
-        private vertexShader;
-        private fragmentShader;
-        static MVP_MATRIX: string;
-        static POSITION: string;
-        static COLOR: string;
-        static COLOR2: string;
-        static TEXCOORDS: string;
-        static SAMPLER: string;
-        private gl;
-        private vs;
-        private fs;
-        private program;
-        private tmp2x2;
-        private tmp3x3;
-        private tmp4x4;
-        getProgram(): WebGLProgram;
-        getVertexShader(): string;
-        getFragmentShader(): string;
-        constructor(gl: WebGLRenderingContext, vertexShader: string, fragmentShader: string);
-        private compile();
-        private compileShader(type, source);
-        private compileProgram(vs, fs);
-        bind(): void;
-        unbind(): void;
-        setUniformi(uniform: string, value: number): void;
-        setUniformf(uniform: string, value: number): void;
-        setUniform2f(uniform: string, value: number, value2: number): void;
-        setUniform3f(uniform: string, value: number, value2: number, value3: number): void;
-        setUniform4f(uniform: string, value: number, value2: number, value3: number, value4: number): void;
-        setUniform2x2f(uniform: string, value: ArrayLike<number>): void;
-        setUniform3x3f(uniform: string, value: ArrayLike<number>): void;
-        setUniform4x4f(uniform: string, value: ArrayLike<number>): void;
-        getUniformLocation(uniform: string): WebGLUniformLocation;
-        getAttributeLocation(attribute: string): number;
-        dispose(): void;
-        static newColoredTextured(gl: WebGLRenderingContext): Shader;
-        static newTwoColoredTextured(gl: WebGLRenderingContext): Shader;
-        static newColored(gl: WebGLRenderingContext): Shader;
-    }
+	class Shader implements Disposable {
+		private vertexShader;
+		private fragmentShader;
+		static MVP_MATRIX: string;
+		static POSITION: string;
+		static COLOR: string;
+		static COLOR2: string;
+		static TEXCOORDS: string;
+		static SAMPLER: string;
+		private gl;
+		private vs;
+		private fs;
+		private program;
+		private tmp2x2;
+		private tmp3x3;
+		private tmp4x4;
+		getProgram(): WebGLProgram;
+		getVertexShader(): string;
+		getFragmentShader(): string;
+		constructor(gl: WebGLRenderingContext, vertexShader: string, fragmentShader: string);
+		private compile();
+		private compileShader(type, source);
+		private compileProgram(vs, fs);
+		bind(): void;
+		unbind(): void;
+		setUniformi(uniform: string, value: number): void;
+		setUniformf(uniform: string, value: number): void;
+		setUniform2f(uniform: string, value: number, value2: number): void;
+		setUniform3f(uniform: string, value: number, value2: number, value3: number): void;
+		setUniform4f(uniform: string, value: number, value2: number, value3: number, value4: number): void;
+		setUniform2x2f(uniform: string, value: ArrayLike<number>): void;
+		setUniform3x3f(uniform: string, value: ArrayLike<number>): void;
+		setUniform4x4f(uniform: string, value: ArrayLike<number>): void;
+		getUniformLocation(uniform: string): WebGLUniformLocation;
+		getAttributeLocation(attribute: string): number;
+		dispose(): void;
+		static newColoredTextured(gl: WebGLRenderingContext): Shader;
+		static newTwoColoredTextured(gl: WebGLRenderingContext): Shader;
+		static newColored(gl: WebGLRenderingContext): Shader;
+	}
 }
 declare module spine.webgl {
-    class ShapeRenderer implements Disposable {
-        private gl;
-        private isDrawing;
-        private mesh;
-        private shapeType;
-        private color;
-        private shader;
-        private vertexIndex;
-        private tmp;
-        private srcBlend;
-        private dstBlend;
-        constructor(gl: WebGLRenderingContext, maxVertices?: number);
-        begin(shader: Shader): void;
-        setBlendMode(srcBlend: number, dstBlend: number): void;
-        setColor(color: Color): void;
-        setColorWith(r: number, g: number, b: number, a: number): void;
-        point(x: number, y: number, color?: Color): void;
-        line(x: number, y: number, x2: number, y2: number, color?: Color): void;
-        triangle(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, color?: Color, color2?: Color, color3?: Color): void;
-        quad(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number, color?: Color, color2?: Color, color3?: Color, color4?: Color): void;
-        rect(filled: boolean, x: number, y: number, width: number, height: number, color?: Color): void;
-        rectLine(filled: boolean, x1: number, y1: number, x2: number, y2: number, width: number, color?: Color): void;
-        x(x: number, y: number, size: number): void;
-        polygon(polygonVertices: ArrayLike<number>, offset: number, count: number, color?: Color): void;
-        circle(filled: boolean, x: number, y: number, radius: number, color?: Color, segments?: number): void;
-        curve(x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color?: Color): void;
-        private vertex(x, y, color);
-        end(): void;
-        private flush();
-        private check(shapeType, numVertices);
-        dispose(): void;
-    }
-    enum ShapeType {
-        Point,
-        Line,
-        Filled,
-    }
+	class ShapeRenderer implements Disposable {
+		private gl;
+		private isDrawing;
+		private mesh;
+		private shapeType;
+		private color;
+		private shader;
+		private vertexIndex;
+		private tmp;
+		private srcBlend;
+		private dstBlend;
+		constructor(gl: WebGLRenderingContext, maxVertices?: number);
+		begin(shader: Shader): void;
+		setBlendMode(srcBlend: number, dstBlend: number): void;
+		setColor(color: Color): void;
+		setColorWith(r: number, g: number, b: number, a: number): void;
+		point(x: number, y: number, color?: Color): void;
+		line(x: number, y: number, x2: number, y2: number, color?: Color): void;
+		triangle(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, color?: Color, color2?: Color, color3?: Color): void;
+		quad(filled: boolean, x: number, y: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number, color?: Color, color2?: Color, color3?: Color, color4?: Color): void;
+		rect(filled: boolean, x: number, y: number, width: number, height: number, color?: Color): void;
+		rectLine(filled: boolean, x1: number, y1: number, x2: number, y2: number, width: number, color?: Color): void;
+		x(x: number, y: number, size: number): void;
+		polygon(polygonVertices: ArrayLike<number>, offset: number, count: number, color?: Color): void;
+		circle(filled: boolean, x: number, y: number, radius: number, color?: Color, segments?: number): void;
+		curve(x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, segments: number, color?: Color): void;
+		private vertex(x, y, color);
+		end(): void;
+		private flush();
+		private check(shapeType, numVertices);
+		dispose(): void;
+	}
+	enum ShapeType {
+		Point,
+		Line,
+		Filled,
+	}
 }
 declare module spine.webgl {
-    class SkeletonDebugRenderer implements Disposable {
-        boneLineColor: Color;
-        boneOriginColor: Color;
-        attachmentLineColor: Color;
-        triangleLineColor: Color;
-        pathColor: Color;
-        aabbColor: Color;
-        drawBones: boolean;
-        drawRegionAttachments: boolean;
-        drawBoundingBoxes: boolean;
-        drawMeshHull: boolean;
-        drawMeshTriangles: boolean;
-        drawPaths: boolean;
-        drawSkeletonXY: boolean;
-        premultipliedAlpha: boolean;
-        scale: number;
-        boneWidth: number;
-        private gl;
-        private bounds;
-        private temp;
-        private vertices;
-        private static LIGHT_GRAY;
-        private static GREEN;
-        constructor(gl: WebGLRenderingContext);
-        draw(shapes: ShapeRenderer, skeleton: Skeleton, ignoredBones?: Array<string>): void;
-        dispose(): void;
-    }
+	class SkeletonDebugRenderer implements Disposable {
+		boneLineColor: Color;
+		boneOriginColor: Color;
+		attachmentLineColor: Color;
+		triangleLineColor: Color;
+		pathColor: Color;
+		clipColor: Color;
+		aabbColor: Color;
+		drawBones: boolean;
+		drawRegionAttachments: boolean;
+		drawBoundingBoxes: boolean;
+		drawMeshHull: boolean;
+		drawMeshTriangles: boolean;
+		drawPaths: boolean;
+		drawSkeletonXY: boolean;
+		drawClipping: boolean;
+		premultipliedAlpha: boolean;
+		scale: number;
+		boneWidth: number;
+		private gl;
+		private bounds;
+		private temp;
+		private vertices;
+		private static LIGHT_GRAY;
+		private static GREEN;
+		constructor(gl: WebGLRenderingContext);
+		draw(shapes: ShapeRenderer, skeleton: Skeleton, ignoredBones?: Array<string>): void;
+		dispose(): void;
+	}
 }
 declare module spine.webgl {
-    class SkeletonRenderer {
-        static QUAD_TRIANGLES: number[];
-        premultipliedAlpha: boolean;
-        private gl;
-        private tempColor;
-        private tempColor2;
-        private vertices;
-        private vertexSize;
-        private twoColorTint;
-        private renderable;
-        constructor(gl: WebGLRenderingContext, twoColorTint?: boolean);
-        draw(batcher: PolygonBatcher, skeleton: Skeleton): void;
-        private computeRegionVertices(slot, region, pma, twoColorTint?);
-        private computeMeshVertices(slot, mesh, pma, twoColorTint?);
-    }
+	class SkeletonRenderer {
+		static QUAD_TRIANGLES: number[];
+		premultipliedAlpha: boolean;
+		private gl;
+		private tempColor;
+		private tempColor2;
+		private vertices;
+		private vertexSize;
+		private twoColorTint;
+		private renderable;
+		private clipper;
+		constructor(gl: WebGLRenderingContext, twoColorTint?: boolean);
+		draw(batcher: PolygonBatcher, skeleton: Skeleton): void;
+	}
 }
 declare module spine.webgl {
-    class Vector3 {
-        x: number;
-        y: number;
-        z: number;
-        constructor(x?: number, y?: number, z?: number);
-        setFrom(v: Vector3): Vector3;
-        set(x: number, y: number, z: number): Vector3;
-        add(v: Vector3): Vector3;
-        sub(v: Vector3): Vector3;
-        scale(s: number): Vector3;
-        normalize(): Vector3;
-        cross(v: Vector3): Vector3;
-        multiply(matrix: Matrix4): Vector3;
-        project(matrix: Matrix4): Vector3;
-        dot(v: Vector3): number;
-        length(): number;
-        distance(v: Vector3): number;
-    }
+	class Vector3 {
+		x: number;
+		y: number;
+		z: number;
+		constructor(x?: number, y?: number, z?: number);
+		setFrom(v: Vector3): Vector3;
+		set(x: number, y: number, z: number): Vector3;
+		add(v: Vector3): Vector3;
+		sub(v: Vector3): Vector3;
+		scale(s: number): Vector3;
+		normalize(): Vector3;
+		cross(v: Vector3): Vector3;
+		multiply(matrix: Matrix4): Vector3;
+		project(matrix: Matrix4): Vector3;
+		dot(v: Vector3): number;
+		length(): number;
+		distance(v: Vector3): number;
+	}
 }
 declare module spine.webgl {
-    function getSourceGLBlendMode(gl: WebGLRenderingContext, blendMode: BlendMode, premultipliedAlpha?: boolean): number;
-    function getDestGLBlendMode(gl: WebGLRenderingContext, blendMode: BlendMode): number;
+	function getSourceGLBlendMode(gl: WebGLRenderingContext, blendMode: BlendMode, premultipliedAlpha?: boolean): number;
+	function getDestGLBlendMode(gl: WebGLRenderingContext, blendMode: BlendMode): number;
 }

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 6396 - 6488
spine-ts/build/spine-webgl.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
spine-ts/build/spine-webgl.js.map


+ 48 - 3
spine-ts/build/spine-widget.d.ts

@@ -383,6 +383,7 @@ declare module spine {
 		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
 		newPathAttachment(skin: Skin, name: string): PathAttachment;
 		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
 	}
 }
 declare module spine {
@@ -406,6 +407,7 @@ declare module spine {
 		newBoundingBoxAttachment(skin: Skin, name: string): BoundingBoxAttachment;
 		newPathAttachment(skin: Skin, name: string): PathAttachment;
 		newPointAttachment(skin: Skin, name: string): PointAttachment;
+		newClippingAttachment(skin: Skin, name: string): ClippingAttachment;
 	}
 }
 declare module spine {
@@ -424,6 +426,13 @@ declare module spine {
 		constructor(name: string);
 	}
 }
+declare module spine {
+	class ClippingAttachment extends VertexAttachment {
+		endSlot: SlotData;
+		color: Color;
+		constructor(name: string);
+	}
+}
 declare module spine {
 	class MeshAttachment extends VertexAttachment {
 		region: TextureRegion;
@@ -607,6 +616,21 @@ declare module spine {
 		getOrder(): number;
 	}
 }
+declare module spine {
+	class ConvexDecomposer {
+		private convexPolygons;
+		private convexPolygonsIndices;
+		private indicesArray;
+		private isConcaveArray;
+		private triangles;
+		private polygonPool;
+		private polygonIndicesPool;
+		decompose(input: ArrayLike<number>): Array<Array<number>>;
+		private static isConcave(index, vertexCount, vertices, indices);
+		private static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y);
+		private static winding(p1x, p1y, p2x, p2y, p3x, p3y);
+	}
+}
 declare module spine {
 	class Event {
 		data: EventData;
@@ -802,6 +826,25 @@ declare module spine {
 		getHeight(): number;
 	}
 }
+declare module spine {
+	class SkeletonClipping {
+		private decomposer;
+		private clippingPolygon;
+		private clipOutput;
+		clippedVertices: number[];
+		clippedTriangles: number[];
+		private scratch;
+		private clipAttachment;
+		private clippingPolygons;
+		clipStart(slot: Slot, clip: ClippingAttachment): void;
+		clipEndWithSlot(slot: Slot): void;
+		clipEnd(): void;
+		isClipping(): boolean;
+		clipTriangles(vertices: ArrayLike<number>, verticesLength: number, triangles: ArrayLike<number>, trianglesLength: number, uvs: ArrayLike<number>, light: Color, dark: Color, twoColor: boolean): void;
+		clip(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, clippingArea: Array<number>, output: Array<number>): boolean;
+		static makeClockwise(polygon: ArrayLike<number>): void;
+	}
+}
 declare module spine {
 	class SkeletonData {
 		name: string;
@@ -840,7 +883,7 @@ declare module spine {
 		private linkedMeshes;
 		constructor(attachmentLoader: AttachmentLoader);
 		readSkeletonData(json: string | any): SkeletonData;
-		readAttachment(map: any, skin: Skin, slotIndex: number, name: string): Attachment;
+		readAttachment(map: any, skin: Skin, slotIndex: number, name: string, skeletonData: SkeletonData): Attachment;
 		readVertices(map: any, attachment: VertexAttachment, verticesLength: number): void;
 		readAnimation(map: any, name: string, skeletonData: SkeletonData): void;
 		readCurve(map: any, timeline: CurveTimeline, frameIndex: number): void;
@@ -1058,6 +1101,7 @@ declare module spine {
 		static ensureArrayCapacity<T>(array: Array<T>, size: number, value?: any): Array<T>;
 		static newArray<T>(size: number, defaultValue: T): Array<T>;
 		static newFloatArray(size: number): ArrayLike<number>;
+		static newShortArray(size: number): ArrayLike<number>;
 		static toFloatArray(array: Array<number>): number[] | Float32Array;
 	}
 	class DebugUtils {
@@ -1445,6 +1489,7 @@ declare module spine.webgl {
 		attachmentLineColor: Color;
 		triangleLineColor: Color;
 		pathColor: Color;
+		clipColor: Color;
 		aabbColor: Color;
 		drawBones: boolean;
 		drawRegionAttachments: boolean;
@@ -1453,6 +1498,7 @@ declare module spine.webgl {
 		drawMeshTriangles: boolean;
 		drawPaths: boolean;
 		drawSkeletonXY: boolean;
+		drawClipping: boolean;
 		premultipliedAlpha: boolean;
 		scale: number;
 		boneWidth: number;
@@ -1478,10 +1524,9 @@ declare module spine.webgl {
 		private vertexSize;
 		private twoColorTint;
 		private renderable;
+		private clipper;
 		constructor(gl: WebGLRenderingContext, twoColorTint?: boolean);
 		draw(batcher: PolygonBatcher, skeleton: Skeleton): void;
-		private computeRegionVertices(slot, region, pma, twoColorTint?);
-		private computeMeshVertices(slot, mesh, pma, twoColorTint?);
 	}
 }
 declare module spine.webgl {

+ 634 - 135
spine-ts/build/spine-widget.js

@@ -1922,6 +1922,9 @@ var spine;
 		AtlasAttachmentLoader.prototype.newPointAttachment = function (skin, name) {
 			return new spine.PointAttachment(name);
 		};
+		AtlasAttachmentLoader.prototype.newClippingAttachment = function (skin, name) {
+			return new spine.ClippingAttachment(name);
+		};
 		return AtlasAttachmentLoader;
 	}());
 	spine.AtlasAttachmentLoader = AtlasAttachmentLoader;
@@ -2034,6 +2037,18 @@ var spine;
 	spine.BoundingBoxAttachment = BoundingBoxAttachment;
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var ClippingAttachment = (function (_super) {
+		__extends(ClippingAttachment, _super);
+		function ClippingAttachment(name) {
+			_super.call(this, name);
+			this.color = new spine.Color(0.2275, 0.2275, 0.8078, 1);
+		}
+		return ClippingAttachment;
+	}(spine.VertexAttachment));
+	spine.ClippingAttachment = ClippingAttachment;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var MeshAttachment = (function (_super) {
 		__extends(MeshAttachment, _super);
@@ -2577,6 +2592,207 @@ var spine;
 	var TransformMode = spine.TransformMode;
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var ConvexDecomposer = (function () {
+		function ConvexDecomposer() {
+			this.convexPolygons = new Array();
+			this.convexPolygonsIndices = new Array();
+			this.indicesArray = new Array();
+			this.isConcaveArray = new Array();
+			this.triangles = new Array();
+			this.polygonPool = new spine.Pool(function () {
+				return new Array();
+			});
+			this.polygonIndicesPool = new spine.Pool(function () {
+				return new Array();
+			});
+		}
+		ConvexDecomposer.prototype.decompose = function (input) {
+			var vertices = input;
+			var vertexCount = input.length >> 1;
+			var indices = this.indicesArray;
+			indices.length = 0;
+			for (var i = 0; i < vertexCount; i++)
+				indices[i] = i;
+			var isConcave = this.isConcaveArray;
+			isConcave.length = 0;
+			for (var i = 0, n = vertexCount; i < n; ++i)
+				isConcave[i] = ConvexDecomposer.isConcave(i, vertexCount, vertices, indices);
+			var triangles = this.triangles;
+			triangles.length = 0;
+			while (vertexCount > 3) {
+				var previous = vertexCount - 1, i = 0, next = 1;
+				while (true) {
+					outer: if (!isConcave[i]) {
+						var p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1;
+						var p1x = vertices[p1], p1y = vertices[p1 + 1];
+						var p2x = vertices[p2], p2y = vertices[p2 + 1];
+						var p3x = vertices[p3], p3y = vertices[p3 + 1];
+						for (var ii = (next + 1) % vertexCount; ii != previous; ii = (ii + 1) % vertexCount) {
+							if (!isConcave[ii])
+								continue;
+							var v = indices[ii] << 1;
+							var vx = vertices[v], vy = vertices[v + 1];
+							if (ConvexDecomposer.positiveArea(p3x, p3y, p1x, p1y, vx, vy)) {
+								if (ConvexDecomposer.positiveArea(p1x, p1y, p2x, p2y, vx, vy)) {
+									if (ConvexDecomposer.positiveArea(p2x, p2y, p3x, p3y, vx, vy))
+										break outer;
+								}
+							}
+						}
+						break;
+					}
+					if (next == 0) {
+						do {
+							if (!isConcave[i])
+								break;
+							i--;
+						} while (i > 0);
+						break;
+					}
+					previous = i;
+					i = next;
+					next = (next + 1) % vertexCount;
+				}
+				triangles.push(indices[(vertexCount + i - 1) % vertexCount]);
+				triangles.push(indices[i]);
+				triangles.push(indices[(i + 1) % vertexCount]);
+				indices.splice(i, 1);
+				isConcave.splice(i, 1);
+				vertexCount--;
+				var previousIndex = (vertexCount + i - 1) % vertexCount;
+				var nextIndex = i == vertexCount ? 0 : i;
+				isConcave[previousIndex] = ConvexDecomposer.isConcave(previousIndex, vertexCount, vertices, indices);
+				isConcave[nextIndex] = ConvexDecomposer.isConcave(nextIndex, vertexCount, vertices, indices);
+			}
+			if (vertexCount == 3) {
+				triangles.push(indices[2]);
+				triangles.push(indices[0]);
+				triangles.push(indices[1]);
+			}
+			var convexPolygons = this.convexPolygons;
+			this.polygonPool.freeAll(convexPolygons);
+			convexPolygons.length = 0;
+			var convexPolygonsIndices = this.convexPolygonsIndices;
+			this.polygonIndicesPool.freeAll(convexPolygonsIndices);
+			convexPolygonsIndices.length = 0;
+			var polygonIndices = this.polygonIndicesPool.obtain();
+			polygonIndices.length = 0;
+			var polygon = this.polygonPool.obtain();
+			polygon.length = 0;
+			var fanBaseIndex = -1, lastWinding = 0;
+			for (var i = 0, n = triangles.length; i < n; i += 3) {
+				var t1 = triangles[i] << 1, t2 = triangles[i + 1] << 1, t3 = triangles[i + 2] << 1;
+				var x1 = vertices[t1], y1 = vertices[t1 + 1];
+				var x2 = vertices[t2], y2 = vertices[t2 + 1];
+				var x3 = vertices[t3], y3 = vertices[t3 + 1];
+				var merged = false;
+				if (fanBaseIndex == t1) {
+					var o = polygon.length - 4;
+					var winding1 = ConvexDecomposer.winding(polygon[o], polygon[o + 1], polygon[o + 2], polygon[o + 3], x3, y3);
+					var winding2 = ConvexDecomposer.winding(x3, y3, polygon[0], polygon[1], polygon[2], polygon[3]);
+					if (winding1 == lastWinding && winding2 == lastWinding) {
+						polygon.push(x3);
+						polygon.push(y3);
+						polygonIndices.push(t3);
+						merged = true;
+					}
+				}
+				if (!merged) {
+					if (polygon.length > 0) {
+						convexPolygons.push(polygon);
+						convexPolygonsIndices.push(polygonIndices);
+					}
+					polygon = this.polygonPool.obtain();
+					polygon.length = 0;
+					polygon.push(x1);
+					polygon.push(y1);
+					polygon.push(x2);
+					polygon.push(y2);
+					polygon.push(x3);
+					polygon.push(y3);
+					polygonIndices = this.polygonIndicesPool.obtain();
+					polygonIndices.length = 0;
+					polygonIndices.push(t1);
+					polygonIndices.push(t2);
+					polygonIndices.push(t3);
+					lastWinding = ConvexDecomposer.winding(x1, y1, x2, y2, x3, y3);
+					fanBaseIndex = t1;
+				}
+			}
+			if (polygon.length > 0) {
+				convexPolygons.push(polygon);
+				convexPolygonsIndices.push(polygonIndices);
+			}
+			for (var i = 0, n = convexPolygons.length; i < n; i++) {
+				polygonIndices = convexPolygonsIndices[i];
+				if (polygonIndices.length == 0)
+					continue;
+				var firstIndex = polygonIndices[0];
+				var lastIndex = polygonIndices[polygonIndices.length - 1];
+				polygon = convexPolygons[i];
+				var o = polygon.length - 4;
+				var prevPrevX = polygon[o], prevPrevY = polygon[o + 1];
+				var prevX = polygon[o + 2], prevY = polygon[o + 3];
+				var firstX = polygon[0], firstY = polygon[1];
+				var secondX = polygon[2], secondY = polygon[3];
+				var winding = ConvexDecomposer.winding(prevPrevX, prevPrevY, prevX, prevY, firstX, firstY);
+				for (var ii = 0; ii < n; ii++) {
+					if (ii == i)
+						continue;
+					var otherIndices = convexPolygonsIndices[ii];
+					if (otherIndices.length != 3)
+						continue;
+					var otherFirstIndex = otherIndices[0];
+					var otherSecondIndex = otherIndices[1];
+					var otherLastIndex = otherIndices[2];
+					var otherPoly = convexPolygons[ii];
+					var x3 = otherPoly[otherPoly.length - 2], y3 = otherPoly[otherPoly.length - 1];
+					if (otherFirstIndex != firstIndex || otherSecondIndex != lastIndex)
+						continue;
+					var winding1 = ConvexDecomposer.winding(prevPrevX, prevPrevY, prevX, prevY, x3, y3);
+					var winding2 = ConvexDecomposer.winding(x3, y3, firstX, firstY, secondX, secondY);
+					if (winding1 == winding && winding2 == winding) {
+						otherPoly.length = 0;
+						otherIndices.length = 0;
+						polygon.push(x3);
+						polygon.push(y3);
+						polygonIndices.push(otherLastIndex);
+						prevPrevX = prevX;
+						prevPrevY = prevY;
+						prevX = x3;
+						prevY = y3;
+						ii = 0;
+					}
+				}
+			}
+			for (var i = convexPolygons.length - 1; i >= 0; i--) {
+				polygon = convexPolygons[i];
+				if (polygon.length == 0) {
+					convexPolygons.splice(i, 1);
+					this.polygonPool.free(polygon);
+				}
+			}
+			return convexPolygons;
+		};
+		ConvexDecomposer.isConcave = function (index, vertexCount, vertices, indices) {
+			var previous = indices[(vertexCount + index - 1) % vertexCount] << 1;
+			var current = indices[index] << 1;
+			var next = indices[(index + 1) % vertexCount] << 1;
+			return !this.positiveArea(vertices[previous], vertices[previous + 1], vertices[current], vertices[current + 1], vertices[next], vertices[next + 1]);
+		};
+		ConvexDecomposer.positiveArea = function (p1x, p1y, p2x, p2y, p3x, p3y) {
+			return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0;
+		};
+		ConvexDecomposer.winding = function (p1x, p1y, p2x, p2y, p3x, p3y) {
+			var px = p2x - p1x, py = p2y - p1y;
+			return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1;
+		};
+		return ConvexDecomposer;
+	}());
+	spine.ConvexDecomposer = ConvexDecomposer;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var Event = (function () {
 		function Event(time, data) {
@@ -3945,6 +4161,285 @@ var spine;
 	spine.SkeletonBounds = SkeletonBounds;
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var SkeletonClipping = (function () {
+		function SkeletonClipping() {
+			this.decomposer = new spine.ConvexDecomposer();
+			this.clippingPolygon = new Array();
+			this.clipOutput = new Array();
+			this.clippedVertices = new Array();
+			this.clippedTriangles = new Array();
+			this.scratch = new Array();
+		}
+		SkeletonClipping.prototype.clipStart = function (slot, clip) {
+			if (this.clipAttachment != null)
+				return;
+			this.clipAttachment = clip;
+			var n = clip.worldVerticesLength;
+			var vertices = spine.Utils.setArraySize(this.clippingPolygon, n);
+			clip.computeWorldVertices(slot, 0, n, vertices, 0, 2);
+			var clippingPolygon = this.clippingPolygon;
+			SkeletonClipping.makeClockwise(clippingPolygon);
+			var clippingPolygons = this.clippingPolygons = this.decomposer.decompose(clippingPolygon);
+			for (var i = 0, n_1 = clippingPolygons.length; i < n_1; i++) {
+				var polygon = clippingPolygons[i];
+				SkeletonClipping.makeClockwise(polygon);
+				polygon.push(polygon[0]);
+				polygon.push(polygon[1]);
+			}
+		};
+		SkeletonClipping.prototype.clipEndWithSlot = function (slot) {
+			if (this.clipAttachment != null && this.clipAttachment.endSlot == slot.data)
+				this.clipEnd();
+		};
+		SkeletonClipping.prototype.clipEnd = function () {
+			if (this.clipAttachment == null)
+				return;
+			this.clipAttachment = null;
+			this.clippingPolygons = null;
+			this.clippedVertices.length = 0;
+			this.clippedTriangles.length = 0;
+			this.clippingPolygon.length = 0;
+		};
+		SkeletonClipping.prototype.isClipping = function () {
+			return this.clipAttachment != null;
+		};
+		SkeletonClipping.prototype.clipTriangles = function (vertices, verticesLength, triangles, trianglesLength, uvs, light, dark, twoColor) {
+			var clipOutput = this.clipOutput, clippedVertices = this.clippedVertices;
+			var clippedTriangles = this.clippedTriangles;
+			var polygons = this.clippingPolygons;
+			var polygonsCount = this.clippingPolygons.length;
+			var vertexSize = twoColor ? 12 : 8;
+			var index = 0;
+			clippedVertices.length = 0;
+			clippedTriangles.length = 0;
+			outer: for (var i = 0; i < trianglesLength; i += 3) {
+				var vertexOffset = triangles[i] << 1;
+				var x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1];
+				var u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1];
+				vertexOffset = triangles[i + 1] << 1;
+				var x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1];
+				var u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1];
+				vertexOffset = triangles[i + 2] << 1;
+				var x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1];
+				var u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1];
+				for (var p = 0; p < polygonsCount; p++) {
+					var s = clippedVertices.length;
+					if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) {
+						var clipOutputLength = clipOutput.length;
+						if (clipOutputLength == 0)
+							continue;
+						var d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1;
+						var d = 1 / (d0 * d2 + d1 * (y1 - y3));
+						var clipOutputCount = clipOutputLength >> 1;
+						var clipOutputItems = this.clipOutput;
+						var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + clipOutputCount * vertexSize);
+						for (var ii = 0; ii < clipOutputLength; ii += 2) {
+							var x = clipOutputItems[ii], y = clipOutputItems[ii + 1];
+							clippedVerticesItems[s] = x;
+							clippedVerticesItems[s + 1] = y;
+							clippedVerticesItems[s + 2] = light.r;
+							clippedVerticesItems[s + 3] = light.g;
+							clippedVerticesItems[s + 4] = light.b;
+							clippedVerticesItems[s + 5] = light.a;
+							var c0 = x - x3, c1 = y - y3;
+							var a = (d0 * c0 + d1 * c1) * d;
+							var b = (d4 * c0 + d2 * c1) * d;
+							var c = 1 - a - b;
+							clippedVerticesItems[s + 6] = u1 * a + u2 * b + u3 * c;
+							clippedVerticesItems[s + 7] = v1 * a + v2 * b + v3 * c;
+							if (twoColor) {
+								clippedVerticesItems[s + 8] = dark.r;
+								clippedVerticesItems[s + 8] = dark.g;
+								clippedVerticesItems[s + 10] = dark.b;
+								clippedVerticesItems[s + 11] = dark.a;
+							}
+							s += vertexSize;
+						}
+						s = clippedTriangles.length;
+						var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2));
+						clipOutputCount--;
+						for (var ii = 1; ii < clipOutputCount; ii++) {
+							clippedTrianglesItems[s] = index;
+							clippedTrianglesItems[s + 1] = (index + ii);
+							clippedTrianglesItems[s + 2] = (index + ii + 1);
+							s += 3;
+						}
+						index += clipOutputCount + 1;
+					}
+					else {
+						var clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + 3 * vertexSize);
+						clippedVerticesItems[s] = x1;
+						clippedVerticesItems[s + 1] = y1;
+						clippedVerticesItems[s + 2] = light.r;
+						clippedVerticesItems[s + 3] = light.g;
+						clippedVerticesItems[s + 4] = light.b;
+						clippedVerticesItems[s + 5] = light.a;
+						if (!twoColor) {
+							clippedVerticesItems[s + 6] = u1;
+							clippedVerticesItems[s + 7] = v1;
+							clippedVerticesItems[s + 8] = x2;
+							clippedVerticesItems[s + 9] = y2;
+							clippedVerticesItems[s + 10] = light.r;
+							clippedVerticesItems[s + 11] = light.g;
+							clippedVerticesItems[s + 12] = light.b;
+							clippedVerticesItems[s + 13] = light.a;
+							clippedVerticesItems[s + 14] = u2;
+							clippedVerticesItems[s + 15] = v2;
+							clippedVerticesItems[s + 16] = x3;
+							clippedVerticesItems[s + 17] = y3;
+							clippedVerticesItems[s + 18] = light.r;
+							clippedVerticesItems[s + 19] = light.g;
+							clippedVerticesItems[s + 20] = light.b;
+							clippedVerticesItems[s + 21] = light.a;
+							clippedVerticesItems[s + 22] = u3;
+							clippedVerticesItems[s + 23] = v3;
+						}
+						else {
+							clippedVerticesItems[s + 6] = u1;
+							clippedVerticesItems[s + 7] = v1;
+							clippedVerticesItems[s + 8] = dark.r;
+							clippedVerticesItems[s + 9] = dark.g;
+							clippedVerticesItems[s + 10] = dark.b;
+							clippedVerticesItems[s + 11] = dark.a;
+							clippedVerticesItems[s + 12] = x2;
+							clippedVerticesItems[s + 13] = y2;
+							clippedVerticesItems[s + 14] = light.r;
+							clippedVerticesItems[s + 15] = light.g;
+							clippedVerticesItems[s + 16] = light.b;
+							clippedVerticesItems[s + 17] = light.a;
+							clippedVerticesItems[s + 18] = u2;
+							clippedVerticesItems[s + 19] = v2;
+							clippedVerticesItems[s + 20] = dark.r;
+							clippedVerticesItems[s + 21] = dark.g;
+							clippedVerticesItems[s + 22] = dark.b;
+							clippedVerticesItems[s + 23] = dark.a;
+							clippedVerticesItems[s + 24] = x3;
+							clippedVerticesItems[s + 25] = y3;
+							clippedVerticesItems[s + 26] = light.r;
+							clippedVerticesItems[s + 27] = light.g;
+							clippedVerticesItems[s + 28] = light.b;
+							clippedVerticesItems[s + 29] = light.a;
+							clippedVerticesItems[s + 30] = u3;
+							clippedVerticesItems[s + 31] = v3;
+							clippedVerticesItems[s + 32] = dark.r;
+							clippedVerticesItems[s + 33] = dark.g;
+							clippedVerticesItems[s + 34] = dark.b;
+							clippedVerticesItems[s + 35] = dark.a;
+						}
+						s = clippedTriangles.length;
+						var clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3);
+						clippedTrianglesItems[s] = index;
+						clippedTrianglesItems[s + 1] = (index + 1);
+						clippedTrianglesItems[s + 2] = (index + 2);
+						index += 3;
+						continue outer;
+					}
+				}
+			}
+		};
+		SkeletonClipping.prototype.clip = function (x1, y1, x2, y2, x3, y3, clippingArea, output) {
+			var originalOutput = output;
+			var clipped = false;
+			var input = null;
+			if (clippingArea.length % 4 >= 2) {
+				input = output;
+				output = this.scratch;
+			}
+			else
+				input = this.scratch;
+			input.length = 0;
+			input.push(x1);
+			input.push(y1);
+			input.push(x2);
+			input.push(y2);
+			input.push(x3);
+			input.push(y3);
+			input.push(x1);
+			input.push(y1);
+			output.length = 0;
+			var clippingVertices = clippingArea;
+			var clippingVerticesLast = clippingArea.length - 4;
+			for (var i = 0;; i += 2) {
+				var edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1];
+				var edgeX2 = clippingVertices[i + 2], edgeY2 = clippingVertices[i + 3];
+				var deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2;
+				var inputVertices = input;
+				var inputVerticesLength = input.length - 2, outputStart = output.length;
+				for (var ii = 0; ii < inputVerticesLength; ii += 2) {
+					var inputX = inputVertices[ii], inputY = inputVertices[ii + 1];
+					var inputX2 = inputVertices[ii + 2], inputY2 = inputVertices[ii + 3];
+					var side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0;
+					if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0) {
+						if (side2) {
+							output.push(inputX2);
+							output.push(inputY2);
+							continue;
+						}
+						var c0 = inputY2 - inputY, c2 = inputX2 - inputX;
+						var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
+						output.push(edgeX + (edgeX2 - edgeX) * ua);
+						output.push(edgeY + (edgeY2 - edgeY) * ua);
+					}
+					else if (side2) {
+						var c0 = inputY2 - inputY, c2 = inputX2 - inputX;
+						var ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
+						output.push(edgeX + (edgeX2 - edgeX) * ua);
+						output.push(edgeY + (edgeY2 - edgeY) * ua);
+						output.push(inputX2);
+						output.push(inputY2);
+					}
+					clipped = true;
+				}
+				if (outputStart == output.length) {
+					originalOutput.length = 0;
+					return true;
+				}
+				output.push(output[0]);
+				output.push(output[1]);
+				if (i == clippingVerticesLast)
+					break;
+				var temp = output;
+				output = input;
+				output.length = 0;
+				input = temp;
+			}
+			if (originalOutput != output) {
+				originalOutput.length = 0;
+				for (var i = 0, n = output.length - 2; i < n; i++)
+					originalOutput[i] = output[i];
+			}
+			else
+				originalOutput.length = originalOutput.length - 2;
+			return clipped;
+		};
+		SkeletonClipping.makeClockwise = function (polygon) {
+			var vertices = polygon;
+			var verticeslength = polygon.length;
+			var area = vertices[verticeslength - 2] * vertices[1] - vertices[0] * vertices[verticeslength - 1], p1x = 0, p1y = 0, p2x = 0, p2y = 0;
+			for (var i = 0, n = verticeslength - 3; i < n; i += 2) {
+				p1x = vertices[i];
+				p1y = vertices[i + 1];
+				p2x = vertices[i + 2];
+				p2y = vertices[i + 3];
+				area += p1x * p2y - p2x * p1y;
+			}
+			if (area < 0)
+				return;
+			for (var i = 0, lastX = verticeslength - 2, n = verticeslength >> 1; i < n; i += 2) {
+				var x = vertices[i], y = vertices[i + 1];
+				var other = lastX - i;
+				vertices[i] = vertices[other];
+				vertices[i + 1] = vertices[other + 1];
+				vertices[other] = x;
+				vertices[other + 1] = y;
+			}
+		};
+		return SkeletonClipping;
+	}());
+	spine.SkeletonClipping = SkeletonClipping;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var SkeletonData = (function () {
 		function SkeletonData() {
@@ -4236,7 +4731,7 @@ var spine;
 							throw new Error("Slot not found: " + slotName);
 						var slotMap = skinMap[slotName];
 						for (var entryName in slotMap) {
-							var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName);
+							var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName, skeletonData);
 							if (attachment != null)
 								skin.addAttachment(slotIndex, entryName, attachment);
 						}
@@ -4276,7 +4771,7 @@ var spine;
 			}
 			return skeletonData;
 		};
-		SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name) {
+		SkeletonJson.prototype.readAttachment = function (map, skin, slotIndex, name, skeletonData) {
 			var scale = this.scale;
 			name = this.getValue(map, "name", name);
 			var type = this.getValue(map, "type", "region");
@@ -4363,6 +4858,24 @@ var spine;
 						point.color.setFromString(color);
 					return point;
 				}
+				case "clipping": {
+					var clip = this.attachmentLoader.newClippingAttachment(skin, name);
+					if (clip == null)
+						return null;
+					var end = this.getValue(map, "end", null);
+					if (end != null) {
+						var slot = skeletonData.findSlot(end);
+						if (slot == null)
+							throw new Error("Clipping end slot not found: " + end);
+						clip.endSlot = slot;
+					}
+					var vertexCount = map.vertexCount;
+					this.readVertices(map, clip, vertexCount << 1);
+					var color = this.getValue(map, "color", null);
+					if (color != null)
+						clip.color.setFromString(color);
+					return clip;
+				}
 			}
 			return null;
 		};
@@ -5543,6 +6056,17 @@ var spine;
 				return array;
 			}
 		};
+		Utils.newShortArray = function (size) {
+			if (Utils.SUPPORTS_TYPED_ARRAYS) {
+				return new Int16Array(size);
+			}
+			else {
+				var array = new Array(size);
+				for (var i = 0; i < array.length; i++)
+					array[i] = 0;
+				return array;
+			}
+		};
 		Utils.toFloatArray = function (array) {
 			return Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array;
 		};
@@ -7563,6 +8087,7 @@ var spine;
 				this.attachmentLineColor = new spine.Color(0, 0, 1, 0.5);
 				this.triangleLineColor = new spine.Color(1, 0.64, 0, 0.5);
 				this.pathColor = new spine.Color().setFromString("FF7F00");
+				this.clipColor = new spine.Color(0.8, 0, 0, 2);
 				this.aabbColor = new spine.Color(0, 1, 0, 0.5);
 				this.drawBones = true;
 				this.drawRegionAttachments = true;
@@ -7571,6 +8096,7 @@ var spine;
 				this.drawMeshTriangles = true;
 				this.drawPaths = true;
 				this.drawSkeletonXY = false;
+				this.drawClipping = true;
 				this.premultipliedAlpha = false;
 				this.scale = 1;
 				this.boneWidth = 2;
@@ -7711,6 +8237,27 @@ var spine;
 						shapes.circle(true, skeletonX + bone.worldX, skeletonY + bone.worldY, 3 * this.scale, SkeletonDebugRenderer.GREEN, 8);
 					}
 				}
+				if (this.drawClipping) {
+					var slots = skeleton.slots;
+					shapes.setColor(this.clipColor);
+					for (var i = 0, n = slots.length; i < n; i++) {
+						var slot = slots[i];
+						var attachment = slot.getAttachment();
+						if (!(attachment instanceof spine.ClippingAttachment))
+							continue;
+						var clip = attachment;
+						var nn = clip.worldVerticesLength;
+						var world = this.temp = spine.Utils.setArraySize(this.temp, nn, 0);
+						clip.computeWorldVertices(slot, 0, nn, world, 0, 2);
+						for (var i_5 = 0, n_2 = world.length; i_5 < n_2; i_5 += 2) {
+							var x = world[i_5];
+							var y = world[i_5 + 1];
+							var x2 = world[(i_5 + 2) % world.length];
+							var y2 = world[(i_5 + 3) % world.length];
+							shapes.line(x, y, x2, y2);
+						}
+					}
+				}
 			};
 			SkeletonDebugRenderer.prototype.dispose = function () {
 			};
@@ -7726,8 +8273,9 @@ var spine;
 	var webgl;
 	(function (webgl) {
 		var Renderable = (function () {
-			function Renderable(vertices, numFloats) {
+			function Renderable(vertices, numVertices, numFloats) {
 				this.vertices = vertices;
+				this.numVertices = numVertices;
 				this.numFloats = numFloats;
 			}
 			return Renderable;
@@ -7741,7 +8289,8 @@ var spine;
 				this.tempColor2 = new spine.Color();
 				this.vertexSize = 2 + 2 + 4;
 				this.twoColorTint = false;
-				this.renderable = new Renderable(null, 0);
+				this.renderable = new Renderable(null, 0, 0);
+				this.clipper = new spine.SkeletonClipping();
 				this.gl = gl;
 				this.twoColorTint = twoColorTint;
 				if (twoColorTint)
@@ -7749,165 +8298,115 @@ var spine;
 				this.vertices = spine.Utils.newFloatArray(this.vertexSize * 1024);
 			}
 			SkeletonRenderer.prototype.draw = function (batcher, skeleton) {
+				var clipper = this.clipper;
 				var premultipliedAlpha = this.premultipliedAlpha;
+				var twoColorTint = this.twoColorTint;
 				var blendMode = null;
-				var vertices = null;
+				var renderable = this.renderable;
+				var uvs = null;
 				var triangles = null;
 				var drawOrder = skeleton.drawOrder;
+				var attachmentColor = null;
+				var skeletonColor = skeleton.color;
+				var vertexSize = twoColorTint ? 12 : 8;
 				for (var i = 0, n = drawOrder.length; i < n; i++) {
+					var clippedVertexSize = clipper.isClipping() ? 2 : vertexSize;
 					var slot = drawOrder[i];
 					var attachment = slot.getAttachment();
 					var texture = null;
 					if (attachment instanceof spine.RegionAttachment) {
 						var region = attachment;
-						vertices = this.computeRegionVertices(slot, region, premultipliedAlpha, this.twoColorTint);
+						renderable.vertices = this.vertices;
+						renderable.numVertices = 4;
+						renderable.numFloats = clippedVertexSize << 2;
+						region.computeWorldVertices(slot.bone, renderable.vertices, 0, clippedVertexSize);
 						triangles = SkeletonRenderer.QUAD_TRIANGLES;
+						uvs = region.uvs;
 						texture = region.region.renderObject.texture;
+						attachmentColor = region.color;
 					}
 					else if (attachment instanceof spine.MeshAttachment) {
 						var mesh = attachment;
-						vertices = this.computeMeshVertices(slot, mesh, premultipliedAlpha, this.twoColorTint);
+						renderable.vertices = this.vertices;
+						renderable.numVertices = (mesh.worldVerticesLength >> 1);
+						renderable.numFloats = renderable.numVertices * clippedVertexSize;
+						if (renderable.numFloats > renderable.vertices.length) {
+							renderable.vertices = this.vertices = spine.Utils.newFloatArray(renderable.numFloats);
+						}
+						mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, renderable.vertices, 0, clippedVertexSize);
 						triangles = mesh.triangles;
 						texture = mesh.region.renderObject.texture;
+						uvs = mesh.uvs;
+						attachmentColor = mesh.color;
+					}
+					else if (attachment instanceof spine.ClippingAttachment) {
+						var clip = (attachment);
+						clipper.clipStart(slot, clip);
+						continue;
 					}
 					else
 						continue;
 					if (texture != null) {
+						var slotColor = slot.color;
+						var finalColor = this.tempColor;
+						finalColor.r = skeletonColor.r * slotColor.r * attachmentColor.r;
+						finalColor.g = skeletonColor.g * slotColor.g * attachmentColor.g;
+						finalColor.b = skeletonColor.b * slotColor.b * attachmentColor.b;
+						finalColor.a = skeletonColor.a * slotColor.a * attachmentColor.a;
+						if (premultipliedAlpha) {
+							finalColor.r *= finalColor.a;
+							finalColor.g *= finalColor.a;
+							finalColor.b *= finalColor.a;
+						}
+						var darkColor = this.tempColor2;
+						if (slot.darkColor == null)
+							darkColor.set(0, 0, 0, 1);
+						else
+							darkColor.setFromColor(slot.darkColor);
 						var slotBlendMode = slot.data.blendMode;
 						if (slotBlendMode != blendMode) {
 							blendMode = slotBlendMode;
 							batcher.setBlendMode(webgl.getSourceGLBlendMode(this.gl, blendMode, premultipliedAlpha), webgl.getDestGLBlendMode(this.gl, blendMode));
 						}
-						var view = vertices.vertices.subarray(0, vertices.numFloats);
-						batcher.draw(texture, view, triangles);
-					}
-				}
-			};
-			SkeletonRenderer.prototype.computeRegionVertices = function (slot, region, pma, twoColorTint) {
-				if (twoColorTint === void 0) { twoColorTint = false; }
-				var skeleton = slot.bone.skeleton;
-				var skeletonColor = skeleton.color;
-				var slotColor = slot.color;
-				var regionColor = region.color;
-				var alpha = skeletonColor.a * slotColor.a * regionColor.a;
-				var multiplier = pma ? alpha : 1;
-				var color = this.tempColor;
-				color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
-				var dark = this.tempColor2;
-				if (slot.darkColor == null)
-					dark.set(0, 0, 0, 1);
-				else
-					dark.setFromColor(slot.darkColor);
-				region.computeWorldVertices(slot.bone, this.vertices, 0, this.vertexSize);
-				var vertices = this.vertices;
-				var uvs = region.uvs;
-				var i = 2;
-				vertices[i++] = color.r;
-				vertices[i++] = color.g;
-				vertices[i++] = color.b;
-				vertices[i++] = color.a;
-				vertices[i++] = uvs[0];
-				vertices[i++] = uvs[1];
-				if (twoColorTint) {
-					vertices[i++] = dark.r;
-					vertices[i++] = dark.g;
-					vertices[i++] = dark.b;
-					vertices[i++] = 1;
-				}
-				i += 2;
-				vertices[i++] = color.r;
-				vertices[i++] = color.g;
-				vertices[i++] = color.b;
-				vertices[i++] = color.a;
-				vertices[i++] = uvs[2];
-				vertices[i++] = uvs[3];
-				if (twoColorTint) {
-					vertices[i++] = dark.r;
-					vertices[i++] = dark.g;
-					vertices[i++] = dark.b;
-					vertices[i++] = 1;
-				}
-				i += 2;
-				vertices[i++] = color.r;
-				vertices[i++] = color.g;
-				vertices[i++] = color.b;
-				vertices[i++] = color.a;
-				vertices[i++] = uvs[4];
-				vertices[i++] = uvs[5];
-				if (twoColorTint) {
-					vertices[i++] = dark.r;
-					vertices[i++] = dark.g;
-					vertices[i++] = dark.b;
-					vertices[i++] = 1;
-				}
-				i += 2;
-				vertices[i++] = color.r;
-				vertices[i++] = color.g;
-				vertices[i++] = color.b;
-				vertices[i++] = color.a;
-				vertices[i++] = uvs[6];
-				vertices[i++] = uvs[7];
-				if (twoColorTint) {
-					vertices[i++] = dark.r;
-					vertices[i++] = dark.g;
-					vertices[i++] = dark.b;
-					vertices[i++] = 1;
-				}
-				this.renderable.vertices = vertices;
-				this.renderable.numFloats = 4 * (twoColorTint ? 12 : 8);
-				return this.renderable;
-			};
-			SkeletonRenderer.prototype.computeMeshVertices = function (slot, mesh, pma, twoColorTint) {
-				if (twoColorTint === void 0) { twoColorTint = false; }
-				var skeleton = slot.bone.skeleton;
-				var skeletonColor = skeleton.color;
-				var slotColor = slot.color;
-				var regionColor = mesh.color;
-				var alpha = skeletonColor.a * slotColor.a * regionColor.a;
-				var multiplier = pma ? alpha : 1;
-				var color = this.tempColor;
-				color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier, skeletonColor.g * slotColor.g * regionColor.g * multiplier, skeletonColor.b * slotColor.b * regionColor.b * multiplier, alpha);
-				var dark = this.tempColor2;
-				if (slot.darkColor == null)
-					dark.set(0, 0, 0, 1);
-				else
-					dark.setFromColor(slot.darkColor);
-				var numVertices = mesh.worldVerticesLength / 2;
-				if (this.vertices.length < mesh.worldVerticesLength) {
-					this.vertices = spine.Utils.newFloatArray(mesh.worldVerticesLength);
-				}
-				var vertices = this.vertices;
-				mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, this.vertexSize);
-				var uvs = mesh.uvs;
-				if (!twoColorTint) {
-					for (var i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
-						vertices[v++] = color.r;
-						vertices[v++] = color.g;
-						vertices[v++] = color.b;
-						vertices[v++] = color.a;
-						vertices[v++] = uvs[u++];
-						vertices[v++] = uvs[u++];
-						v += 2;
-					}
-				}
-				else {
-					for (var i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
-						vertices[v++] = color.r;
-						vertices[v++] = color.g;
-						vertices[v++] = color.b;
-						vertices[v++] = color.a;
-						vertices[v++] = uvs[u++];
-						vertices[v++] = uvs[u++];
-						vertices[v++] = dark.r;
-						vertices[v++] = dark.g;
-						vertices[v++] = dark.b;
-						vertices[v++] = 1;
-						v += 2;
+						if (clipper.isClipping()) {
+							clipper.clipTriangles(renderable.vertices, renderable.numFloats, triangles, triangles.length, uvs, finalColor, darkColor, twoColorTint);
+							var clippedVertices = new Float32Array(clipper.clippedVertices);
+							var clippedTriangles = clipper.clippedTriangles;
+							batcher.draw(texture, clippedVertices, clippedTriangles);
+						}
+						else {
+							var verts = renderable.vertices;
+							if (!twoColorTint) {
+								for (var v = 2, u = 0, n_3 = renderable.numFloats; v < n_3; v += vertexSize, u += 2) {
+									verts[v] = finalColor.r;
+									verts[v + 1] = finalColor.g;
+									verts[v + 2] = finalColor.b;
+									verts[v + 3] = finalColor.a;
+									verts[v + 4] = uvs[u];
+									verts[v + 5] = uvs[u + 1];
+								}
+							}
+							else {
+								for (var v = 2, u = 0, n_4 = renderable.numFloats; v < n_4; v += vertexSize, u += 2) {
+									verts[v] = finalColor.r;
+									verts[v + 1] = finalColor.g;
+									verts[v + 2] = finalColor.b;
+									verts[v + 3] = finalColor.a;
+									verts[v + 4] = uvs[u];
+									verts[v + 5] = uvs[u + 1];
+									verts[v + 6] = darkColor.r;
+									verts[v + 7] = darkColor.g;
+									verts[v + 8] = darkColor.b;
+									verts[v + 9] = darkColor.a;
+								}
+							}
+							var view = renderable.vertices.subarray(0, renderable.numFloats);
+							batcher.draw(texture, view, triangles);
+						}
 					}
+					clipper.clipEndWithSlot(slot);
 				}
-				this.renderable.vertices = vertices;
-				this.renderable.numFloats = numVertices * (twoColorTint ? 12 : 8);
-				return this.renderable;
+				clipper.clipEnd();
 			};
 			SkeletonRenderer.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
 			return SkeletonRenderer;

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
spine-ts/build/spine-widget.js.map


+ 30 - 32
spine-ts/core/src/SkeletonClipping.ts

@@ -33,8 +33,8 @@ module spine {
 		private decomposer = new ConvexDecomposer();
 		private clippingPolygon = new Array<number>();
 		private clipOutput = new Array<number>();
-		private clippedVertices = new Array<number>();
-		private clippedTriangles = new Array<number>();
+		clippedVertices = new Array<number>();
+		clippedTriangles = new Array<number>();
 		private scratch = new Array<number>();
 
 		private clipAttachment: ClippingAttachment;
@@ -82,7 +82,7 @@ module spine {
 			let clippedTriangles = this.clippedTriangles;
 			let polygons = this.clippingPolygons;
 			let polygonsCount = this.clippingPolygons.length;
-			let vertexSize = twoColor ? 6 : 5;
+			let vertexSize = twoColor ? 12 : 8;
 
 			let index = 0;
 			clippedVertices.length = 0;
@@ -120,21 +120,19 @@ module spine {
 							clippedVerticesItems[s + 3] = light.g;
 							clippedVerticesItems[s + 4] = light.b;
 							clippedVerticesItems[s + 5] = light.a;
-							if (twoColor) {
-								clippedVerticesItems[s + 6] = dark.r;
-								clippedVerticesItems[s + 7] = dark.g;
-								clippedVerticesItems[s + 8] = dark.b;
-								clippedVerticesItems[s + 9] = dark.a;
-								s += 10;
-							} else
-								s += 6;
 							let c0 = x - x3, c1 = y - y3;
 							let a = (d0 * c0 + d1 * c1) * d;
 							let b = (d4 * c0 + d2 * c1) * d;
 							let c = 1 - a - b;
-							clippedVerticesItems[s] = u1 * a + u2 * b + u3 * c;
-							clippedVerticesItems[s + 1] = v1 * a + v2 * b + v3 * c;
-							s += 2;
+							clippedVerticesItems[s + 6] = u1 * a + u2 * b + u3 * c;
+							clippedVerticesItems[s + 7] = v1 * a + v2 * b + v3 * c;
+							if (twoColor) {
+								clippedVerticesItems[s + 8] = dark.r;
+								clippedVerticesItems[s + 8] = dark.g;
+								clippedVerticesItems[s + 10] = dark.b;
+								clippedVerticesItems[s + 11] = dark.a;
+							}
+							s += vertexSize;
 						}
 
 						s = clippedTriangles.length;
@@ -178,12 +176,12 @@ module spine {
 							clippedVerticesItems[s + 22] = u3;
 							clippedVerticesItems[s + 23] = v3;
 						} else {
-							clippedVerticesItems[s + 6] = dark.r;
-							clippedVerticesItems[s + 7] = dark.g;
-							clippedVerticesItems[s + 8] = dark.b;
-							clippedVerticesItems[s + 9] = dark.a;
-							clippedVerticesItems[s + 10] = u1;
-							clippedVerticesItems[s + 11] = v1;
+							clippedVerticesItems[s + 6] = u1;
+							clippedVerticesItems[s + 7] = v1;
+							clippedVerticesItems[s + 8] = dark.r;
+							clippedVerticesItems[s + 9] = dark.g;
+							clippedVerticesItems[s + 10] = dark.b;
+							clippedVerticesItems[s + 11] = dark.a;
 
 							clippedVerticesItems[s + 12] = x2;
 							clippedVerticesItems[s + 13] = y2;
@@ -191,12 +189,12 @@ module spine {
 							clippedVerticesItems[s + 15] = light.g;
 							clippedVerticesItems[s + 16] = light.b;
 							clippedVerticesItems[s + 17] = light.a;
-							clippedVerticesItems[s + 18] = dark.r;
-							clippedVerticesItems[s + 19] = dark.g;
-							clippedVerticesItems[s + 20] = dark.b;
-							clippedVerticesItems[s + 21] = dark.a;
-							clippedVerticesItems[s + 22] = u2;
-							clippedVerticesItems[s + 23] = v2;
+							clippedVerticesItems[s + 18] = u2;
+							clippedVerticesItems[s + 19] = v2;
+							clippedVerticesItems[s + 20] = dark.r;
+							clippedVerticesItems[s + 21] = dark.g;
+							clippedVerticesItems[s + 22] = dark.b;
+							clippedVerticesItems[s + 23] = dark.a;
 
 							clippedVerticesItems[s + 24] = x3;
 							clippedVerticesItems[s + 25] = y3;
@@ -204,12 +202,12 @@ module spine {
 							clippedVerticesItems[s + 27] = light.g;
 							clippedVerticesItems[s + 28] = light.b;
 							clippedVerticesItems[s + 29] = light.a;
-							clippedVerticesItems[s + 30] = dark.r;
-							clippedVerticesItems[s + 31] = dark.g;
-							clippedVerticesItems[s + 32] = dark.b;
-							clippedVerticesItems[s + 33] = dark.a;
-							clippedVerticesItems[s + 34] = u3;
-							clippedVerticesItems[s + 35] = v3;
+							clippedVerticesItems[s + 30] = u3;
+							clippedVerticesItems[s + 31] = v3;
+							clippedVerticesItems[s + 32] = dark.r;
+							clippedVerticesItems[s + 33] = dark.g;
+							clippedVerticesItems[s + 34] = dark.b;
+							clippedVerticesItems[s + 35] = dark.a;
 						}
 
 						s = clippedTriangles.length;

+ 118 - 146
spine-ts/webgl/example/assets/raptor.atlas

@@ -1,279 +1,251 @@
 
 raptor.png
-size: 1024,1024
+size: 2048,2048
 format: RGBA8888
 filter: Linear,Linear
 repeat: none
 back_arm
-  rotate: true
-  xy: 140, 191
-  size: 46, 29
-  orig: 46, 29
+  rotate: false
+  xy: 1888, 1638
+  size: 91, 57
+  orig: 91, 57
   offset: 0, 0
   index: -1
 back_bracer
-  rotate: true
-  xy: 167, 317
-  size: 39, 28
-  orig: 39, 28
+  rotate: false
+  xy: 1888, 1581
+  size: 77, 55
+  orig: 77, 55
   offset: 0, 0
   index: -1
 back_hand
   rotate: false
-  xy: 167, 358
-  size: 36, 34
-  orig: 36, 34
+  xy: 1954, 1764
+  size: 72, 68
+  orig: 72, 68
   offset: 0, 0
   index: -1
 back_knee
   rotate: false
-  xy: 299, 478
-  size: 49, 67
-  orig: 49, 67
+  xy: 275, 438
+  size: 97, 134
+  orig: 97, 134
   offset: 0, 0
   index: -1
 back_thigh
-  rotate: true
-  xy: 167, 437
-  size: 39, 24
-  orig: 39, 24
-  offset: 0, 0
-  index: -1
-eyes_closed
-  rotate: true
-  xy: 2, 2
-  size: 47, 45
-  orig: 47, 45
+  rotate: false
+  xy: 1778, 1518
+  size: 78, 47
+  orig: 78, 47
   offset: 0, 0
   index: -1
 eyes_open
-  rotate: true
-  xy: 49, 2
-  size: 47, 45
-  orig: 47, 45
-  offset: 0, 0
-  index: -1
-eyes_surprised
-  rotate: true
-  xy: 96, 2
-  size: 47, 45
-  orig: 47, 45
+  rotate: false
+  xy: 275, 347
+  size: 93, 89
+  orig: 93, 89
   offset: 0, 0
   index: -1
 front_arm
   rotate: false
-  xy: 419, 544
-  size: 48, 30
-  orig: 48, 30
+  xy: 830, 1089
+  size: 96, 60
+  orig: 96, 60
   offset: 0, 0
   index: -1
 front_bracer
   rotate: false
-  xy: 880, 695
-  size: 41, 29
-  orig: 41, 29
+  xy: 1888, 1697
+  size: 81, 58
+  orig: 81, 58
   offset: 0, 0
   index: -1
 front_hand
-  rotate: true
-  xy: 167, 394
-  size: 41, 38
-  orig: 41, 38
+  rotate: false
+  xy: 1870, 1757
+  size: 82, 75
+  orig: 82, 75
   offset: 0, 0
   index: -1
 front_open_hand
   rotate: false
-  xy: 880, 726
-  size: 43, 44
-  orig: 43, 44
+  xy: 192, 15
+  size: 86, 87
+  orig: 86, 87
   offset: 0, 0
   index: -1
 front_thigh
   rotate: false
-  xy: 360, 545
-  size: 57, 29
-  orig: 57, 29
+  xy: 714, 1091
+  size: 114, 58
+  orig: 114, 58
   offset: 0, 0
   index: -1
 gun
   rotate: false
-  xy: 785, 774
-  size: 107, 103
-  orig: 107, 103
+  xy: 1563, 1543
+  size: 213, 206
+  orig: 213, 206
   offset: 0, 0
   index: -1
 gun_nohand
   rotate: false
-  xy: 614, 703
-  size: 105, 102
-  orig: 105, 102
+  xy: 1223, 1403
+  size: 210, 203
+  orig: 210, 203
   offset: 0, 0
   index: -1
 head
   rotate: false
-  xy: 2, 137
-  size: 136, 149
-  orig: 136, 149
+  xy: 2, 274
+  size: 271, 298
+  orig: 271, 298
   offset: 0, 0
   index: -1
 lower_leg
-  rotate: true
-  xy: 780, 699
-  size: 73, 98
-  orig: 73, 98
-  offset: 0, 0
-  index: -1
-mouth_grind
   rotate: false
-  xy: 469, 544
-  size: 47, 30
-  orig: 47, 30
-  offset: 0, 0
-  index: -1
-mouth_oooo
-  rotate: true
-  xy: 894, 772
-  size: 105, 30
-  orig: 105, 30
+  xy: 551, 893
+  size: 146, 195
+  orig: 146, 195
   offset: 0, 0
   index: -1
 mouth_smile
-  rotate: true
-  xy: 140, 239
-  size: 47, 30
-  orig: 47, 30
+  rotate: false
+  xy: 928, 1090
+  size: 93, 59
+  orig: 93, 59
   offset: 0, 0
   index: -1
 neck
-  rotate: true
-  xy: 538, 577
-  size: 18, 21
-  orig: 18, 21
+  rotate: false
+  xy: 330, 908
+  size: 36, 41
+  orig: 36, 41
   offset: 0, 0
   index: -1
 raptor_arm_back
   rotate: false
-  xy: 940, 936
-  size: 82, 86
-  orig: 82, 86
+  xy: 386, 916
+  size: 163, 172
+  orig: 163, 172
   offset: 0, 0
   index: -1
 raptor_body
   rotate: false
-  xy: 2, 737
-  size: 610, 285
-  orig: 610, 285
+  xy: 2, 1467
+  size: 1219, 570
+  orig: 1219, 570
   offset: 0, 0
   index: -1
 raptor_front_arm
-  rotate: true
-  xy: 195, 464
-  size: 81, 102
-  orig: 81, 102
+  rotate: false
+  xy: 1870, 1834
+  size: 162, 203
+  orig: 162, 203
   offset: 0, 0
   index: -1
 raptor_front_leg
   rotate: false
-  xy: 2, 478
-  size: 191, 257
-  orig: 191, 257
+  xy: 2, 951
+  size: 382, 514
+  orig: 382, 514
   offset: 0, 0
   index: -1
 raptor_hindleg_back
   rotate: false
-  xy: 614, 807
-  size: 169, 215
-  orig: 169, 215
+  xy: 1223, 1608
+  size: 338, 429
+  orig: 338, 429
   offset: 0, 0
   index: -1
 raptor_horn
   rotate: false
-  xy: 360, 655
-  size: 182, 80
-  orig: 182, 80
+  xy: 714, 1306
+  size: 363, 159
+  orig: 363, 159
   offset: 0, 0
   index: -1
 raptor_horn_back
   rotate: false
-  xy: 360, 576
-  size: 176, 77
-  orig: 176, 77
+  xy: 714, 1151
+  size: 351, 153
+  orig: 351, 153
   offset: 0, 0
   index: -1
 raptor_jaw
   rotate: false
-  xy: 785, 879
-  size: 153, 143
-  orig: 153, 143
+  xy: 1563, 1751
+  size: 305, 286
+  orig: 305, 286
   offset: 0, 0
   index: -1
 raptor_saddle_noshadow
   rotate: false
-  xy: 2, 288
-  size: 163, 188
-  orig: 163, 188
+  xy: 2, 574
+  size: 326, 375
+  orig: 326, 375
   offset: 0, 0
   index: -1
 raptor_saddle_strap_front
   rotate: false
-  xy: 721, 710
-  size: 57, 95
-  orig: 57, 95
+  xy: 1435, 1417
+  size: 114, 189
+  orig: 114, 189
   offset: 0, 0
   index: -1
 raptor_saddle_strap_rear
-  rotate: true
-  xy: 940, 880
-  size: 54, 74
-  orig: 54, 74
+  rotate: false
+  xy: 1079, 1317
+  size: 108, 148
+  orig: 108, 148
   offset: 0, 0
   index: -1
 raptor_saddle_w_shadow
   rotate: false
-  xy: 195, 547
-  size: 163, 188
-  orig: 163, 188
+  xy: 386, 1090
+  size: 326, 375
+  orig: 326, 375
   offset: 0, 0
   index: -1
 raptor_tongue
-  rotate: true
-  xy: 544, 649
-  size: 86, 64
-  orig: 86, 64
+  rotate: false
+  xy: 1551, 1413
+  size: 171, 128
+  orig: 171, 128
   offset: 0, 0
   index: -1
 stirrup_back
-  rotate: true
-  xy: 140, 145
-  size: 44, 35
-  orig: 44, 35
+  rotate: false
+  xy: 275, 276
+  size: 87, 69
+  orig: 87, 69
   offset: 0, 0
   index: -1
 stirrup_front
   rotate: false
-  xy: 538, 597
-  size: 45, 50
-  orig: 45, 50
+  xy: 2, 2
+  size: 89, 100
+  orig: 89, 100
   offset: 0, 0
   index: -1
 stirrup_strap
   rotate: false
-  xy: 350, 497
-  size: 49, 46
-  orig: 49, 46
+  xy: 93, 11
+  size: 97, 91
+  orig: 97, 91
   offset: 0, 0
   index: -1
 torso
-  rotate: true
-  xy: 610, 647
-  size: 54, 91
-  orig: 54, 91
+  rotate: false
+  xy: 1778, 1567
+  size: 108, 182
+  orig: 108, 182
   offset: 0, 0
   index: -1
 visor
   rotate: false
-  xy: 2, 51
-  size: 131, 84
-  orig: 131, 84
+  xy: 2, 104
+  size: 261, 168
+  orig: 261, 168
   offset: 0, 0
   index: -1

+ 11 - 1
spine-ts/webgl/example/assets/raptor.json

@@ -1,5 +1,5 @@
 {
-"skeleton": { "hash": "WOArBZLexLEX/Tow3AuM8ddszEE", "spine": "3.6.14-beta", "width": 1223.73, "height": 1055.62, "images": "./images/" },
+"skeleton": { "hash": "T+jP778edtEIrEMb7QvVNAgiHUo", "spine": "3.6.14-beta", "width": 1223.73, "height": 1056.91, "images": "./images/" },
 "bones": [
 	{ "name": "root" },
 	{ "name": "hip", "parent": "root", "rotation": 3.16, "x": -136.79, "y": 415.48, "color": "fbff00ff" },
@@ -199,6 +199,7 @@
 	{ "name": "tongue3", "parent": "tongue2", "length": 43.65, "rotation": 12.86, "x": 44.27, "y": -0.21, "color": "fff200ff" }
 ],
 "slots": [
+	{ "name": "clip", "bone": "root", "attachment": "clip" },
 	{ "name": "back_hand", "bone": "back_hand", "attachment": "back_hand" },
 	{ "name": "back_arm", "bone": "back_arm", "attachment": "back_arm" },
 	{ "name": "back_bracer", "bone": "back_bracer", "attachment": "back_bracer" },
@@ -310,6 +311,15 @@
 		"back_thigh": {
 			"back_thigh": { "x": 37.85, "y": -4.37, "rotation": 19.25, "width": 78, "height": 47 }
 		},
+		"clip": {
+			"clip": {
+				"type": "clipping",
+				"end": "clip",
+				"vertexCount": 25,
+				"vertices": [ -31.42, 352.85, -182.02, 382.27, -214.91, 562.3, -8.92, 647.12, 183.22, 555.37, 254.19, 375.35, 261.12, 153.78, 3.2, 13.57, -270.3, -36.63, -408.78, 48.19, -349.93, 280.14, -228.76, 133.01, -59.12, 94.93, 107.06, 160.71, 202.26, 349.38, 122.64, 487.86, -41.81, 557.1, -142.21, 489.6, -57.39, 422.09, 49.94, 432.47, 133.02, 370.16, 94.94, 271.49, 43.01, 186.67, -138.74, 174.55, -230.49, 273.22 ],
+				"color": "ce3a3aff"
+			}
+		},
 		"eyes_open": {
 			"eyes_open": { "x": 93.24, "y": -25.45, "rotation": -70.58, "width": 93, "height": 89 }
 		},

BIN
spine-ts/webgl/example/assets/raptor.png


+ 13 - 6
spine-ts/webgl/example/test.html

@@ -13,8 +13,9 @@
 <script>
 
 var FILE = "coin";
+var ANIMATION = "rotate";
 var NUM_SKELETONS = 1;
-var SCALE = 0.6;
+var SCALE = 0.5;
 
 var canvas, gl, renderer, input, assetManager;
 var skeletons = [];
@@ -29,6 +30,12 @@ function init() {
 	gl = canvas.getContext("webgl", { alpha: false }) || canvas.getContext("experimental-webgl", { alpha: false });
 
 	renderer = new spine.webgl.SceneRenderer(canvas, gl);
+	renderer.skeletonDebugRenderer.drawBones = false;
+	renderer.skeletonDebugRenderer.drawMeshTriangles = false;
+	renderer.skeletonDebugRenderer.drawMeshHull = false;
+	renderer.skeletonDebugRenderer.drawRegionAttachments = false;
+	renderer.skeletonDebugRenderer.drawBoundingBoxes = false;
+
 	assetManager = new spine.webgl.AssetManager(gl, "assets/");
 	var textureLoader = function(img) { return new spine.webgl.GLTexture(gl, img); };
 	input = new spine.webgl.Input(canvas);
@@ -62,10 +69,9 @@ function load() {
 			stateData.defaultMix = mixDuration;
 
 			state.multipleMixing = false;
-			state.setAnimation(0, "rotate", true);
-			state.apply(skeleton);
-			skeleton.x = Math.random() * 200 - Math.random() * 200;
-			skeleton.y = Math.random() * 200 - Math.random() * 200;
+			state.setAnimation(0, "walk", true);
+			skeleton.x = 0;
+			skeleton.y = 0;
 			skeleton.updateWorldTransform();
 			skeletons.push({ skeleton: skeleton, state: state });
 		}
@@ -92,7 +98,7 @@ function render() {
 	updateMean.addValue(Date.now() - start);
 	start = Date.now();
 
-	gl.clearColor(0, 0, 0, 1);
+	gl.clearColor(0.2, 0.2, 0.2, 1);
 	gl.clear(gl.COLOR_BUFFER_BIT);
 
 	renderer.resize(spine.webgl.ResizeMode.Fit);
@@ -100,6 +106,7 @@ function render() {
 	for (var i = 0; i < skeletons.length; i++) {
 		var skeleton = skeletons[i].skeleton;
 		renderer.drawSkeleton(skeleton);
+		renderer.drawSkeletonDebug(skeleton);
 	}
 	renderer.end();
 

+ 23 - 0
spine-ts/webgl/src/SkeletonDebugRenderer.ts

@@ -35,6 +35,7 @@ module spine.webgl {
 		attachmentLineColor = new Color(0, 0, 1, 0.5);
 		triangleLineColor = new Color(1, 0.64, 0, 0.5);
 		pathColor = new Color().setFromString("FF7F00");
+		clipColor = new Color(0.8, 0, 0, 2);
 		aabbColor = new Color(0, 1, 0, 0.5);
 		drawBones = true;
 		drawRegionAttachments = true;
@@ -43,6 +44,7 @@ module spine.webgl {
 		drawMeshTriangles = true;
 		drawPaths = true;
 		drawSkeletonXY = false;
+		drawClipping = true;
 		premultipliedAlpha = false;
 		scale = 1;
 		boneWidth = 2;
@@ -192,6 +194,27 @@ module spine.webgl {
 					shapes.circle(true, skeletonX + bone.worldX, skeletonY + bone.worldY, 3 * this.scale, SkeletonDebugRenderer.GREEN, 8);
 				}
 			}
+
+			if (this.drawClipping) {
+				let slots = skeleton.slots;
+				shapes.setColor(this.clipColor)
+				for (let i = 0, n = slots.length; i < n; i++) {
+					let slot = slots[i];
+					let attachment = slot.getAttachment();
+					if (!(attachment instanceof ClippingAttachment)) continue;
+					let clip = <ClippingAttachment>attachment;
+					let nn = clip.worldVerticesLength;
+					let world = this.temp = Utils.setArraySize(this.temp, nn, 0);
+					clip.computeWorldVertices(slot, 0, nn, world, 0, 2);
+					for (let i = 0, n = world.length; i < n; i+=2) {
+						let x = world[i];
+						let y = world[i + 1];
+						let x2 = world[(i + 2) % world.length];
+						let y2 = world[(i + 3) % world.length];
+						shapes.line(x, y, x2, y2);
+					}
+				}
+			}
 		}
 
 		dispose () {

+ 80 - 144
spine-ts/webgl/src/SkeletonRenderer.ts

@@ -30,7 +30,7 @@
 
 module spine.webgl {
 	class Renderable {
-		constructor(public vertices: ArrayLike<number>, public numFloats: number) {}
+		constructor(public vertices: ArrayLike<number>, public numVertices: number, public numFloats: number) {}
 	};
 
 	export class SkeletonRenderer {
@@ -43,7 +43,8 @@ module spine.webgl {
 		private vertices:ArrayLike<number>;
 		private vertexSize = 2 + 2 + 4;
 		private twoColorTint = false;
-		private renderable: Renderable = new Renderable(null, 0);
+		private renderable: Renderable = new Renderable(null, 0, 0);
+		private clipper: SkeletonClipping = new SkeletonClipping();
 
 		constructor (gl: WebGLRenderingContext, twoColorTint: boolean = true) {
 			this.gl = gl;
@@ -54,177 +55,112 @@ module spine.webgl {
 		}
 
 		draw (batcher: PolygonBatcher, skeleton: Skeleton) {
+			let clipper = this.clipper;
 			let premultipliedAlpha = this.premultipliedAlpha;
+			let twoColorTint = this.twoColorTint;
 			let blendMode: BlendMode = null;
 
-			let vertices: Renderable = null;
+			let renderable: Renderable = this.renderable;
+			let uvs: ArrayLike<number> = null;
 			let triangles: Array<number> = null;
 			let drawOrder = skeleton.drawOrder;
+			let attachmentColor: Color = null;
+			let skeletonColor = skeleton.color;
+			let vertexSize = twoColorTint ? 12 : 8;
 			for (let i = 0, n = drawOrder.length; i < n; i++) {
+				let clippedVertexSize = clipper.isClipping() ? 2 : vertexSize;
 				let slot = drawOrder[i];
 				let attachment = slot.getAttachment();
 				let texture: GLTexture = null;
 				if (attachment instanceof RegionAttachment) {
 					let region = <RegionAttachment>attachment;
-					vertices = this.computeRegionVertices(slot, region, premultipliedAlpha, this.twoColorTint);
+					renderable.vertices = this.vertices;
+					renderable.numVertices = 4;
+					renderable.numFloats = clippedVertexSize << 2;
+					region.computeWorldVertices(slot.bone, renderable.vertices, 0, clippedVertexSize);
 					triangles = SkeletonRenderer.QUAD_TRIANGLES;
+					uvs = region.uvs;
 					texture = <GLTexture>(<TextureAtlasRegion>region.region.renderObject).texture;
-
+					attachmentColor = region.color;
 				} else if (attachment instanceof MeshAttachment) {
 					let mesh = <MeshAttachment>attachment;
-					vertices = this.computeMeshVertices(slot, mesh, premultipliedAlpha, this.twoColorTint);
+					renderable.vertices = this.vertices;
+					renderable.numVertices = (mesh.worldVerticesLength >> 1);
+					renderable.numFloats = renderable.numVertices * clippedVertexSize;
+					if (renderable.numFloats > renderable.vertices.length) {
+						renderable.vertices = this.vertices = spine.Utils.newFloatArray(renderable.numFloats);
+					}
+					mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, renderable.vertices, 0, clippedVertexSize);
 					triangles = mesh.triangles;
 					texture = <GLTexture>(<TextureAtlasRegion>mesh.region.renderObject).texture;
+					uvs = mesh.uvs;
+					attachmentColor = mesh.color;
+				} else if (attachment instanceof ClippingAttachment) {
+					let clip = <ClippingAttachment>(attachment);
+					clipper.clipStart(slot, clip);
+					continue;
 				} else continue;
 
 				if (texture != null) {
+					let slotColor = slot.color;
+					let finalColor = this.tempColor;
+					finalColor.r = skeletonColor.r * slotColor.r * attachmentColor.r;
+					finalColor.g = skeletonColor.g * slotColor.g * attachmentColor.g;
+					finalColor.b = skeletonColor.b * slotColor.b * attachmentColor.b;
+					finalColor.a = skeletonColor.a * slotColor.a * attachmentColor.a;
+					if (premultipliedAlpha) {
+						finalColor.r *= finalColor.a;
+						finalColor.g *= finalColor.a;
+						finalColor.b *= finalColor.a;
+					}
+					let darkColor = this.tempColor2;
+					if (slot.darkColor == null) darkColor.set(0, 0, 0, 1);
+					else darkColor.setFromColor(slot.darkColor);
+
 					let slotBlendMode = slot.data.blendMode;
 					if (slotBlendMode != blendMode) {
 						blendMode = slotBlendMode;
 						batcher.setBlendMode(getSourceGLBlendMode(this.gl, blendMode, premultipliedAlpha), getDestGLBlendMode(this.gl, blendMode));
 					}
 
-					let view = (vertices.vertices as Float32Array).subarray(0, vertices.numFloats);
-					batcher.draw(texture, view, triangles);
+					if (clipper.isClipping()) {
+						clipper.clipTriangles(renderable.vertices, renderable.numFloats, triangles, triangles.length, uvs, finalColor, darkColor, twoColorTint);
+						let clippedVertices = new Float32Array(clipper.clippedVertices);
+						let clippedTriangles = clipper.clippedTriangles;
+						batcher.draw(texture, clippedVertices, clippedTriangles);
+					} else {
+						let verts = renderable.vertices;
+						if (!twoColorTint) {
+							for (let v = 2, u = 0, n = renderable.numFloats; v < n; v += vertexSize, u += 2) {
+								verts[v] = finalColor.r;
+								verts[v + 1] = finalColor.g;
+								verts[v + 2] = finalColor.b;
+								verts[v + 3] = finalColor.a;
+								verts[v + 4] = uvs[u];
+								verts[v + 5] = uvs[u + 1];
+							}
+						} else {
+							for (let v = 2, u = 0, n = renderable.numFloats; v < n; v += vertexSize, u += 2) {
+								verts[v] = finalColor.r;
+								verts[v + 1] = finalColor.g;
+								verts[v + 2] = finalColor.b;
+								verts[v + 3] = finalColor.a;
+								verts[v + 4] = uvs[u];
+								verts[v + 5] = uvs[u + 1];
+								verts[v + 6] = darkColor.r;
+								verts[v + 7] = darkColor.g;
+								verts[v + 8] = darkColor.b;
+								verts[v + 9] = darkColor.a;
+							}
+						}
+						let view = (renderable.vertices as Float32Array).subarray(0, renderable.numFloats);
+						batcher.draw(texture, view, triangles);
+					}
 				}
-			}
-		}
 
-		private computeRegionVertices(slot: Slot, region: RegionAttachment, pma: boolean, twoColorTint: boolean = false) {
-			let skeleton = slot.bone.skeleton;
-			let skeletonColor = skeleton.color;
-			let slotColor = slot.color;
-			let regionColor = region.color;
-			let alpha = skeletonColor.a * slotColor.a * regionColor.a;
-			let multiplier = pma ? alpha : 1;
-			let color = this.tempColor;
-			color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier,
-					  skeletonColor.g * slotColor.g * regionColor.g * multiplier,
-					  skeletonColor.b * slotColor.b * regionColor.b * multiplier,
-					  alpha);
-			let dark = this.tempColor2;
-			if (slot.darkColor == null) dark.set(0, 0, 0, 1);
-			else dark.setFromColor(slot.darkColor);
-
-			region.computeWorldVertices(slot.bone, this.vertices, 0, this.vertexSize);
-
-			let vertices = this.vertices;
-			let uvs = region.uvs;
-
-			let i = 2;
-			vertices[i++] = color.r;
-			vertices[i++] = color.g;
-			vertices[i++] = color.b;
-			vertices[i++] = color.a;
-			vertices[i++] = uvs[0];
-			vertices[i++] = uvs[1];
-			if (twoColorTint) {
-				vertices[i++] = dark.r;
-				vertices[i++] = dark.g;
-				vertices[i++] = dark.b;
-				vertices[i++] = 1;
+				clipper.clipEndWithSlot(slot);
 			}
-			i+=2;
-
-			vertices[i++] = color.r;
-			vertices[i++] = color.g;
-			vertices[i++] = color.b;
-			vertices[i++] = color.a;
-			vertices[i++] = uvs[2];
-			vertices[i++] = uvs[3];
-			if (twoColorTint) {
-				vertices[i++] = dark.r;
-				vertices[i++] = dark.g;
-				vertices[i++] = dark.b;
-				vertices[i++] = 1;
-			}
-			i+=2;
-
-			vertices[i++] = color.r;
-			vertices[i++] = color.g;
-			vertices[i++] = color.b;
-			vertices[i++] = color.a;
-			vertices[i++] = uvs[4];
-			vertices[i++] = uvs[5];
-			if (twoColorTint) {
-				vertices[i++] = dark.r;
-				vertices[i++] = dark.g;
-				vertices[i++] = dark.b;
-				vertices[i++] = 1;
-			}
-			i+=2;
-
-			vertices[i++] = color.r;
-			vertices[i++] = color.g;
-			vertices[i++] = color.b;
-			vertices[i++] = color.a;
-			vertices[i++] = uvs[6];
-			vertices[i++] = uvs[7];
-			if (twoColorTint) {
-				vertices[i++] = dark.r;
-				vertices[i++] = dark.g;
-				vertices[i++] = dark.b;
-				vertices[i++] = 1;
-			}
-
-			this.renderable.vertices = vertices;
-			this.renderable.numFloats = 4 * (twoColorTint ? 12 :  8);
-			return this.renderable;
-		}
-
-		private computeMeshVertices(slot: Slot, mesh: MeshAttachment, pma: boolean, twoColorTint: boolean = false) {
-			let skeleton = slot.bone.skeleton;
-			let skeletonColor = skeleton.color;
-			let slotColor = slot.color;
-			let regionColor = mesh.color;
-			let alpha = skeletonColor.a * slotColor.a * regionColor.a;
-			let multiplier = pma ? alpha : 1;
-			let color = this.tempColor;
-			color.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier,
-					  skeletonColor.g * slotColor.g * regionColor.g * multiplier,
-					  skeletonColor.b * slotColor.b * regionColor.b * multiplier,
-					  alpha);
-			let dark = this.tempColor2;
-			if (slot.darkColor == null) dark.set(0, 0, 0, 1);
-			else dark.setFromColor(slot.darkColor);
-
-			let numVertices = mesh.worldVerticesLength / 2;
-			if (this.vertices.length < mesh.worldVerticesLength) {
-				this.vertices = Utils.newFloatArray(mesh.worldVerticesLength);
-			}
-			let vertices = this.vertices;
-			mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, vertices, 0, this.vertexSize);
-
-			let uvs = mesh.uvs;
-			if (!twoColorTint) {
-				for (let i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
-					vertices[v++] = color.r;
-					vertices[v++] = color.g;
-					vertices[v++] = color.b;
-					vertices[v++] = color.a;
-					vertices[v++] = uvs[u++];
-					vertices[v++] = uvs[u++];
-					v += 2;
-				}
-			} else {
-				for (let i = 0, n = numVertices, u = 0, v = 2; i < n; i++) {
-					vertices[v++] = color.r;
-					vertices[v++] = color.g;
-					vertices[v++] = color.b;
-					vertices[v++] = color.a;
-					vertices[v++] = uvs[u++];
-					vertices[v++] = uvs[u++];
-					vertices[v++] = dark.r;
-					vertices[v++] = dark.g;
-					vertices[v++] = dark.b;
-					vertices[v++] = 1;
-					v += 2;
-				}
-			}
-
-			this.renderable.vertices = vertices;
-			this.renderable.numFloats = numVertices * (twoColorTint ? 12 :  8);
-			return this.renderable;
+			clipper.clipEnd();
 		}
 	}
 }

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно