Просмотр исходного кода

[ts] Ported skin bones/constraints changes. See #1346.

badlogic 6 лет назад
Родитель
Сommit
3aa14d9b86
77 измененных файлов с 5006 добавлено и 4545 удалено
  1. 23 18
      spine-ts/build/spine-all.d.ts
  2. 210 73
      spine-ts/build/spine-all.js
  3. 0 0
      spine-ts/build/spine-all.js.map
  4. 23 18
      spine-ts/build/spine-canvas.d.ts
  5. 198 73
      spine-ts/build/spine-canvas.js
  6. 0 0
      spine-ts/build/spine-canvas.js.map
  7. 23 18
      spine-ts/build/spine-core.d.ts
  8. 196 73
      spine-ts/build/spine-core.js
  9. 0 0
      spine-ts/build/spine-core.js.map
  10. 23 18
      spine-ts/build/spine-player.d.ts
  11. 206 73
      spine-ts/build/spine-player.js
  12. 0 0
      spine-ts/build/spine-player.js.map
  13. 23 18
      spine-ts/build/spine-threejs.d.ts
  14. 198 73
      spine-ts/build/spine-threejs.js
  15. 0 0
      spine-ts/build/spine-threejs.js.map
  16. 23 18
      spine-ts/build/spine-webgl.d.ts
  17. 206 73
      spine-ts/build/spine-webgl.js
  18. 0 0
      spine-ts/build/spine-webgl.js.map
  19. 209 390
      spine-ts/canvas/example/assets/spineboy-ess.json
  20. 51 51
      spine-ts/canvas/example/assets/spineboy.atlas
  21. BIN
      spine-ts/canvas/example/assets/spineboy.png
  22. 1 0
      spine-ts/canvas/src/SkeletonRenderer.ts
  23. 13 1
      spine-ts/core/src/Animation.ts
  24. 1 0
      spine-ts/core/src/AnimationState.ts
  25. 5 0
      spine-ts/core/src/Bone.ts
  26. 1 0
      spine-ts/core/src/BoneData.ts
  27. 2 2
      spine-ts/core/src/Constraint.ts
  28. 4 3
      spine-ts/core/src/IkConstraint.ts
  29. 2 4
      spine-ts/core/src/IkConstraintData.ts
  30. 7 5
      spine-ts/core/src/PathConstraint.ts
  31. 2 4
      spine-ts/core/src/PathConstraintData.ts
  32. 29 2
      spine-ts/core/src/Skeleton.ts
  33. 69 31
      spine-ts/core/src/SkeletonJson.ts
  34. 1 1
      spine-ts/core/src/Skin.ts
  35. 6 5
      spine-ts/core/src/TransformConstraint.ts
  36. 2 5
      spine-ts/core/src/TransformConstraintData.ts
  37. 2 0
      spine-ts/core/src/Updatable.ts
  38. 7 0
      spine-ts/core/src/Utils.ts
  39. 58 58
      spine-ts/player/example/assets/raptor-pma.atlas
  40. BIN
      spine-ts/player/example/assets/raptor-pma.png
  41. 73 74
      spine-ts/player/example/assets/raptor-pro.json
  42. 51 51
      spine-ts/player/example/assets/spineboy-pma.atlas
  43. BIN
      spine-ts/player/example/assets/spineboy-pma.png
  44. 85 103
      spine-ts/player/example/assets/spineboy-pro.json
  45. 73 74
      spine-ts/threejs/example/assets/raptor-pro.json
  46. 58 58
      spine-ts/threejs/example/assets/raptor.atlas
  47. BIN
      spine-ts/threejs/example/assets/raptor.png
  48. 1 0
      spine-ts/threejs/src/SkeletonMesh.ts
  49. 9 9
      spine-ts/webgl/example/assets/coin-pma.atlas
  50. BIN
      spine-ts/webgl/example/assets/coin-pma.png
  51. 75 181
      spine-ts/webgl/example/assets/coin-pro.json
  52. 60 60
      spine-ts/webgl/example/assets/goblins-pma.atlas
  53. BIN
      spine-ts/webgl/example/assets/goblins-pma.png
  54. 382 474
      spine-ts/webgl/example/assets/goblins-pro.json
  55. 35 35
      spine-ts/webgl/example/assets/owl-pma.atlas
  56. BIN
      spine-ts/webgl/example/assets/owl-pma.png
  57. 148 151
      spine-ts/webgl/example/assets/owl-pro.json
  58. 58 58
      spine-ts/webgl/example/assets/raptor-pma.atlas
  59. BIN
      spine-ts/webgl/example/assets/raptor-pma.png
  60. 73 74
      spine-ts/webgl/example/assets/raptor-pro.json
  61. 51 51
      spine-ts/webgl/example/assets/spineboy-pma.atlas
  62. BIN
      spine-ts/webgl/example/assets/spineboy-pma.png
  63. 85 103
      spine-ts/webgl/example/assets/spineboy-pro.json
  64. BIN
      spine-ts/webgl/example/assets/spineboy.png
  65. 5 5
      spine-ts/webgl/example/assets/stretchyman-pma.atlas
  66. BIN
      spine-ts/webgl/example/assets/stretchyman-pma.png
  67. 17 20
      spine-ts/webgl/example/assets/stretchyman-pro.json
  68. 17 20
      spine-ts/webgl/example/assets/stretchyman-stretchy-ik-pro.json
  69. 36 36
      spine-ts/webgl/example/assets/tank-pma.atlas
  70. BIN
      spine-ts/webgl/example/assets/tank-pma.png
  71. 1773 1788
      spine-ts/webgl/example/assets/tank-pro.json
  72. 3 3
      spine-ts/webgl/example/assets/vine-pma.atlas
  73. BIN
      spine-ts/webgl/example/assets/vine-pma.png
  74. 6 9
      spine-ts/webgl/example/assets/vine-pro.json
  75. 1 0
      spine-ts/webgl/example/index.html
  76. 3 0
      spine-ts/webgl/src/SkeletonDebugRenderer.ts
  77. 4 0
      spine-ts/webgl/src/SkeletonRenderer.ts

+ 23 - 18
spine-ts/build/spine-all.d.ts

@@ -447,7 +447,9 @@ declare module spine {
 		d: number;
 		worldY: number;
 		sorted: boolean;
+		active: boolean;
 		constructor(data: BoneData, skeleton: Skeleton, parent: Bone);
+		isActive(): boolean;
 		update(): void;
 		updateWorldTransform(): void;
 		updateWorldTransformWith(x: number, y: number, rotation: number, scaleX: number, scaleY: number, shearX: number, shearY: number): void;
@@ -478,6 +480,7 @@ declare module spine {
 		shearX: number;
 		shearY: number;
 		transformMode: TransformMode;
+		skinRequired: boolean;
 		constructor(index: number, name: string, parent: BoneData);
 	}
 	enum TransformMode {
@@ -489,8 +492,11 @@ declare module spine {
 	}
 }
 declare module spine {
-	interface Constraint extends Updatable {
-		getOrder(): number;
+	abstract class ConstraintData {
+		name: string;
+		order: number;
+		skinRequired: boolean;
+		constructor(name: string, order: number, skinRequired: boolean);
 	}
 }
 declare module spine {
@@ -518,7 +524,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class IkConstraint implements Constraint {
+	class IkConstraint implements Updatable {
 		data: IkConstraintData;
 		bones: Array<Bone>;
 		target: Bone;
@@ -526,8 +532,9 @@ declare module spine {
 		compress: boolean;
 		stretch: boolean;
 		mix: number;
+		active: boolean;
 		constructor(data: IkConstraintData, skeleton: Skeleton);
-		getOrder(): number;
+		isActive(): boolean;
 		apply(): void;
 		update(): void;
 		apply1(bone: Bone, targetX: number, targetY: number, compress: boolean, stretch: boolean, uniform: boolean, alpha: number): void;
@@ -535,9 +542,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class IkConstraintData {
-		name: string;
-		order: number;
+	class IkConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: BoneData;
 		bendDirection: number;
@@ -549,7 +554,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class PathConstraint implements Constraint {
+	class PathConstraint implements Updatable {
 		static NONE: number;
 		static BEFORE: number;
 		static AFTER: number;
@@ -567,20 +572,19 @@ declare module spine {
 		curves: number[];
 		lengths: number[];
 		segments: number[];
+		active: boolean;
 		constructor(data: PathConstraintData, skeleton: Skeleton);
+		isActive(): boolean;
 		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;
+	class PathConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: SlotData;
 		positionMode: PositionMode;
@@ -781,7 +785,7 @@ declare module spine {
 		name: string;
 		attachments: Map<Attachment>[];
 		bones: BoneData[];
-		constraints: Constraint[];
+		constraints: ConstraintData[];
 		constructor(name: string);
 		setAttachment(slotIndex: number, name: string, attachment: Attachment): void;
 		addSkin(skin: Skin): void;
@@ -899,7 +903,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class TransformConstraint implements Constraint {
+	class TransformConstraint implements Updatable {
 		data: TransformConstraintData;
 		bones: Array<Bone>;
 		target: Bone;
@@ -908,20 +912,19 @@ declare module spine {
 		scaleMix: number;
 		shearMix: number;
 		temp: Vector2;
+		active: boolean;
 		constructor(data: TransformConstraintData, skeleton: Skeleton);
+		isActive(): boolean;
 		apply(): void;
 		update(): void;
 		applyAbsoluteWorld(): void;
 		applyRelativeWorld(): void;
 		applyAbsoluteLocal(): void;
 		applyRelativeLocal(): void;
-		getOrder(): number;
 	}
 }
 declare module spine {
-	class TransformConstraintData {
-		name: string;
-		order: number;
+	class TransformConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: BoneData;
 		rotateMix: number;
@@ -958,6 +961,7 @@ declare module spine {
 declare module spine {
 	interface Updatable {
 		update(): void;
+		isActive(): boolean;
 	}
 }
 declare module spine {
@@ -1034,6 +1038,7 @@ declare module spine {
 		static toFloatArray(array: Array<number>): number[] | Float32Array;
 		static toSinglePrecision(value: number): number;
 		static webkit602BugfixHelper(alpha: number, blend: MixBlend): void;
+		static contains<T>(array: Array<T>, element: T, identity?: boolean): boolean;
 	}
 	class DebugUtils {
 		static logBones(skeleton: Skeleton): void;

+ 210 - 73
spine-ts/build/spine-all.js

@@ -188,6 +188,8 @@ var spine;
 		RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -257,6 +259,8 @@ var spine;
 		TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -318,6 +322,8 @@ var spine;
 		ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -416,6 +422,8 @@ var spine;
 		ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -480,6 +488,8 @@ var spine;
 		};
 		ColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var frames = this.frames;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -558,6 +568,8 @@ var spine;
 		};
 		TwoColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var frames = this.frames;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -652,6 +664,8 @@ var spine;
 		};
 		AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			if (direction == MixDirection.mixOut && blend == MixBlend.setup) {
 				var attachmentName_1 = slot.data.attachmentName;
 				slot.setAttachment(attachmentName_1 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_1));
@@ -697,6 +711,8 @@ var spine;
 		};
 		DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var slotAttachment = slot.getAttachment();
 			if (!(slotAttachment instanceof spine.VertexAttachment) || !(slotAttachment.deformAttachment == this.attachment))
 				return;
@@ -976,6 +992,8 @@ var spine;
 		IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.ikConstraints[this.ikConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1076,6 +1094,8 @@ var spine;
 		TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.transformConstraints[this.transformConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				var data = constraint.data;
 				switch (blend) {
@@ -1159,6 +1179,8 @@ var spine;
 		PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1202,6 +1224,8 @@ var spine;
 		PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1249,6 +1273,8 @@ var spine;
 		PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1535,6 +1561,8 @@ var spine;
 			var rotateTimeline = timeline;
 			var frames = rotateTimeline.frames;
 			var bone = skeleton.bones[rotateTimeline.boneIndex];
+			if (!bone.active)
+				return;
 			var r1 = 0, r2 = 0;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -2425,6 +2453,7 @@ var spine;
 			this.d = 0;
 			this.worldY = 0;
 			this.sorted = false;
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2434,6 +2463,9 @@ var spine;
 			this.parent = parent;
 			this.setToSetupPose();
 		}
+		Bone.prototype.isActive = function () {
+			return this.active;
+		};
 		Bone.prototype.update = function () {
 			this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY);
 		};
@@ -2658,6 +2690,7 @@ var spine;
 			this.shearX = 0;
 			this.shearY = 0;
 			this.transformMode = TransformMode.Normal;
+			this.skinRequired = false;
 			if (index < 0)
 				throw new Error("index must be >= 0.");
 			if (name == null)
@@ -2679,6 +2712,18 @@ var spine;
 	})(TransformMode = spine.TransformMode || (spine.TransformMode = {}));
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var ConstraintData = (function () {
+		function ConstraintData(name, order, skinRequired) {
+			this.name = name;
+			this.order = order;
+			this.skinRequired = skinRequired;
+		}
+		return ConstraintData;
+	}());
+	spine.ConstraintData = ConstraintData;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var Event = (function () {
 		function Event(time, data) {
@@ -2709,6 +2754,7 @@ var spine;
 			this.compress = false;
 			this.stretch = false;
 			this.mix = 1;
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2723,8 +2769,8 @@ var spine;
 				this.bones.push(skeleton.findBone(data.bones[i].name));
 			this.target = skeleton.findBone(data.target.name);
 		}
-		IkConstraint.prototype.getOrder = function () {
-			return this.data.order;
+		IkConstraint.prototype.isActive = function () {
+			return this.active;
 		};
 		IkConstraint.prototype.apply = function () {
 			this.update();
@@ -2908,19 +2954,20 @@ var spine;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var IkConstraintData = (function () {
+	var IkConstraintData = (function (_super) {
+		__extends(IkConstraintData, _super);
 		function IkConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.bendDirection = 1;
-			this.compress = false;
-			this.stretch = false;
-			this.uniform = false;
-			this.mix = 1;
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			_this.bendDirection = 1;
+			_this.compress = false;
+			_this.stretch = false;
+			_this.uniform = false;
+			_this.mix = 1;
+			return _this;
 		}
 		return IkConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.IkConstraintData = IkConstraintData;
 })(spine || (spine = {}));
 var spine;
@@ -2937,6 +2984,7 @@ var spine;
 			this.curves = new Array();
 			this.lengths = new Array();
 			this.segments = new Array();
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2951,6 +2999,9 @@ var spine;
 			this.rotateMix = data.rotateMix;
 			this.translateMix = data.translateMix;
 		}
+		PathConstraint.prototype.isActive = function () {
+			return this.active;
+		};
 		PathConstraint.prototype.apply = function () {
 			this.update();
 		};
@@ -3306,9 +3357,6 @@ var spine;
 					out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
 			}
 		};
-		PathConstraint.prototype.getOrder = function () {
-			return this.data.order;
-		};
 		PathConstraint.NONE = -1;
 		PathConstraint.BEFORE = -2;
 		PathConstraint.AFTER = -3;
@@ -3319,14 +3367,15 @@ var spine;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var PathConstraintData = (function () {
+	var PathConstraintData = (function (_super) {
+		__extends(PathConstraintData, _super);
 		function PathConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			return _this;
 		}
 		return PathConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.PathConstraintData = PathConstraintData;
 	var PositionMode;
 	(function (PositionMode) {
@@ -3543,8 +3592,22 @@ var spine;
 			updateCache.length = 0;
 			this.updateCacheReset.length = 0;
 			var bones = this.bones;
-			for (var i = 0, n = bones.length; i < n; i++)
-				bones[i].sorted = false;
+			for (var i = 0, n = bones.length; i < n; i++) {
+				var bone = bones[i];
+				bone.sorted = bone.data.skinRequired;
+				bone.active = !bone.sorted;
+			}
+			if (this.skin != null) {
+				var skinBones = this.skin.bones;
+				for (var i = 0, n = this.skin.bones.length; i < n; i++) {
+					var bone = this.bones[skinBones[i].index];
+					do {
+						bone.sorted = false;
+						bone.active = true;
+						bone = bone.parent;
+					} while (bone != null);
+				}
+			}
 			var ikConstraints = this.ikConstraints;
 			var transformConstraints = this.transformConstraints;
 			var pathConstraints = this.pathConstraints;
@@ -3577,6 +3640,9 @@ var spine;
 				this.sortBone(bones[i]);
 		};
 		Skeleton.prototype.sortIkConstraint = function (constraint) {
+			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			var target = constraint.target;
 			this.sortBone(target);
 			var constrained = constraint.bones;
@@ -3592,6 +3658,9 @@ var spine;
 			constrained[constrained.length - 1].sorted = true;
 		};
 		Skeleton.prototype.sortPathConstraint = function (constraint) {
+			constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			var slot = constraint.target;
 			var slotIndex = slot.data.index;
 			var slotBone = slot.bone;
@@ -3615,6 +3684,9 @@ var spine;
 				constrained[i].sorted = true;
 		};
 		Skeleton.prototype.sortTransformConstraint = function (constraint) {
+			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			this.sortBone(constraint.target);
 			var constrained = constraint.bones;
 			var boneCount = constrained.length;
@@ -3675,6 +3747,8 @@ var spine;
 		Skeleton.prototype.sortReset = function (bones) {
 			for (var i = 0, n = bones.length; i < n; i++) {
 				var bone = bones[i];
+				if (!bone.update)
+					continue;
 				if (bone.sorted)
 					this.sortReset(bone.children);
 				bone.sorted = false;
@@ -3790,6 +3864,8 @@ var spine;
 			this.setSkin(skin);
 		};
 		Skeleton.prototype.setSkin = function (newSkin) {
+			if (newSkin == this.skin)
+				return;
 			if (newSkin != null) {
 				if (this.skin != null)
 					newSkin.attachAll(this, this.skin);
@@ -3807,6 +3883,7 @@ var spine;
 				}
 			}
 			this.skin = newSkin;
+			this.updateCache();
 		};
 		Skeleton.prototype.getAttachmentByName = function (slotName, attachmentName) {
 			return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName);
@@ -4555,6 +4632,7 @@ var spine;
 					data.shearX = this.getValue(boneMap, "shearX", 0);
 					data.shearY = this.getValue(boneMap, "shearY", 0);
 					data.transformMode = SkeletonJson.transformModeFromString(this.getValue(boneMap, "transform", "normal"));
+					data.skinRequired = this.getValue(boneMap, "skin", false);
 					skeletonData.bones.push(data);
 				}
 			}
@@ -4585,6 +4663,7 @@ var spine;
 					var constraintMap = root.ik[i];
 					var data = new spine.IkConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4609,6 +4688,7 @@ var spine;
 					var constraintMap = root.transform[i];
 					var data = new spine.TransformConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4640,6 +4720,7 @@ var spine;
 					var constraintMap = root.path[i];
 					var data = new spine.PathConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4667,18 +4748,50 @@ var spine;
 				}
 			}
 			if (root.skins) {
-				for (var skinName in root.skins) {
-					var skinMap = root.skins[skinName];
-					var skin = new spine.Skin(skinName);
-					for (var slotName in skinMap) {
-						var slotIndex = skeletonData.findSlotIndex(slotName);
-						if (slotIndex == -1)
+				for (var i = 0; i < root.skins.length; i++) {
+					var skinMap = root.skins[i];
+					var skin = new spine.Skin(skinMap.name);
+					if (skinMap.bones) {
+						for (var ii = 0; ii < skinMap.bones.length; ii++) {
+							var bone = skeletonData.findBone(skinMap.bones[ii]);
+							if (bone == null)
+								throw new Error("Skin bone not found: " + skinMap.bones[i]);
+							skin.bones.push(bone);
+						}
+					}
+					if (skinMap.ik) {
+						for (var ii = 0; ii < skinMap.ik.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.ik[ii]);
+							if (constraint == null)
+								throw new Error("Skin IK constraint not found: " + skinMap.ik[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					if (skinMap.transform) {
+						for (var ii = 0; ii < skinMap.transform.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.transform[ii]);
+							if (constraint == null)
+								throw new Error("Skin transform constraint not found: " + skinMap.transform[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					if (skinMap.path) {
+						for (var ii = 0; ii < skinMap.path.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.path[ii]);
+							if (constraint == null)
+								throw new Error("Skin path constraint not found: " + skinMap.path[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					for (var slotName in skinMap.attachments) {
+						var slot = skeletonData.findSlot(slotName);
+						if (slot == null)
 							throw new Error("Slot not found: " + slotName);
-						var slotMap = skinMap[slotName];
+						var slotMap = skinMap.attachments[slotName];
 						for (var entryName in slotMap) {
-							var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName, skeletonData);
+							var attachment = this.readAttachment(slotMap[entryName], skin, slot.index, entryName, skeletonData);
 							if (attachment != null)
-								skin.setAttachment(slotIndex, entryName, attachment);
+								skin.setAttachment(slot.index, entryName, attachment);
 						}
 					}
 					skeletonData.skins.push(skin);
@@ -4878,7 +4991,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex++, valueMap.time, valueMap.name);
+								timeline.setFrame(frameIndex++, this.getValue(valueMap, "time", 0), valueMap.name);
 							}
 							timelines.push(timeline);
 							duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
@@ -4891,7 +5004,7 @@ var spine;
 								var valueMap = timelineMap[i];
 								var color = new spine.Color();
 								color.setFromString(valueMap.color);
-								timeline.setFrame(frameIndex, valueMap.time, color.r, color.g, color.b, color.a);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), color.r, color.g, color.b, color.a);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4908,7 +5021,7 @@ var spine;
 								var dark = new spine.Color();
 								light.setFromString(valueMap.light);
 								dark.setFromString(valueMap.dark);
-								timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4934,7 +5047,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, valueMap.angle);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "angle", 0));
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4943,9 +5056,11 @@ var spine;
 						}
 						else if (timelineName === "translate" || timelineName === "scale" || timelineName === "shear") {
 							var timeline = null;
-							var timelineScale = 1;
-							if (timelineName === "scale")
+							var timelineScale = 1, defaultValue = 0;
+							if (timelineName === "scale") {
 								timeline = new spine.ScaleTimeline(timelineMap.length);
+								defaultValue = 1;
+							}
 							else if (timelineName === "shear")
 								timeline = new spine.ShearTimeline(timelineMap.length);
 							else {
@@ -4956,8 +5071,8 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								var x = this.getValue(valueMap, "x", 0), y = this.getValue(valueMap, "y", 0);
-								timeline.setFrame(frameIndex, valueMap.time, x * timelineScale, y * timelineScale);
+								var x = this.getValue(valueMap, "x", defaultValue), y = this.getValue(valueMap, "y", defaultValue);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), x * timelineScale, y * timelineScale);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4978,7 +5093,7 @@ var spine;
 					var frameIndex = 0;
 					for (var i = 0; i < constraintMap.length; i++) {
 						var valueMap = constraintMap[i];
-						timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false));
+						timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false));
 						this.readCurve(valueMap, timeline, frameIndex);
 						frameIndex++;
 					}
@@ -4995,7 +5110,7 @@ var spine;
 					var frameIndex = 0;
 					for (var i = 0; i < constraintMap.length; i++) {
 						var valueMap = constraintMap[i];
-						timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1));
+						timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1));
 						this.readCurve(valueMap, timeline, frameIndex);
 						frameIndex++;
 					}
@@ -5003,9 +5118,9 @@ var spine;
 					duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TransformConstraintTimeline.ENTRIES]);
 				}
 			}
-			if (map.paths) {
-				for (var constraintName in map.paths) {
-					var constraintMap = map.paths[constraintName];
+			if (map.path) {
+				for (var constraintName in map.path) {
+					var constraintMap = map.path[constraintName];
 					var index = skeletonData.findPathConstraintIndex(constraintName);
 					if (index == -1)
 						throw new Error("Path constraint not found: " + constraintName);
@@ -5029,7 +5144,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, timelineName, 0) * timelineScale);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, timelineName, 0) * timelineScale);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5042,7 +5157,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1));
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1));
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5094,7 +5209,7 @@ var spine;
 											deform[i] += vertices[i];
 									}
 								}
-								timeline.setFrame(frameIndex, valueMap.time, deform);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), deform);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5134,7 +5249,7 @@ var spine;
 							if (drawOrder[i] == -1)
 								drawOrder[i] = unchanged[--unchangedIndex];
 					}
-					timeline.setFrame(frameIndex++, drawOrderMap.time, drawOrder);
+					timeline.setFrame(frameIndex++, this.getValue(drawOrderMap, "time", 0), drawOrder);
 				}
 				timelines.push(timeline);
 				duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
@@ -5147,7 +5262,7 @@ var spine;
 					var eventData = skeletonData.findEvent(eventMap.name);
 					if (eventData == null)
 						throw new Error("Event not found: " + eventMap.name);
-					var event_5 = new spine.Event(spine.Utils.toSinglePrecision(eventMap.time), eventData);
+					var event_5 = new spine.Event(spine.Utils.toSinglePrecision(this.getValue(eventMap, "time", 0)), eventData);
 					event_5.intValue = this.getValue(eventMap, "int", eventData.intValue);
 					event_5.floatValue = this.getValue(eventMap, "float", eventData.floatValue);
 					event_5.stringValue = this.getValue(eventMap, "string", eventData.stringValue);
@@ -5168,11 +5283,11 @@ var spine;
 		SkeletonJson.prototype.readCurve = function (map, timeline, frameIndex) {
 			if (!map.curve)
 				return;
-			if (map.curve === "stepped")
+			if (map.curve == "stepped")
 				timeline.setStepped(frameIndex);
 			else if (Object.prototype.toString.call(map.curve) === '[object Array]') {
 				var curve = map.curve;
-				timeline.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]);
+				timeline.setCurve(frameIndex, curve, this.getValue(map, "c2", 0), this.getValue(map, "c3", 1), this.getValue(map, "c4", 1));
 			}
 		};
 		SkeletonJson.prototype.getValue = function (map, prop, defaultValue) {
@@ -5725,6 +5840,7 @@ var spine;
 			this.scaleMix = 0;
 			this.shearMix = 0;
 			this.temp = new spine.Vector2();
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -5739,6 +5855,9 @@ var spine;
 				this.bones.push(skeleton.findBone(data.bones[i].name));
 			this.target = skeleton.findBone(data.target.name);
 		}
+		TransformConstraint.prototype.isActive = function () {
+			return this.active;
+		};
 		TransformConstraint.prototype.apply = function () {
 			this.update();
 		};
@@ -5948,37 +6067,33 @@ var spine;
 				bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
 			}
 		};
-		TransformConstraint.prototype.getOrder = function () {
-			return this.data.order;
-		};
 		return TransformConstraint;
 	}());
 	spine.TransformConstraint = TransformConstraint;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var TransformConstraintData = (function () {
+	var TransformConstraintData = (function (_super) {
+		__extends(TransformConstraintData, _super);
 		function TransformConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.rotateMix = 0;
-			this.translateMix = 0;
-			this.scaleMix = 0;
-			this.shearMix = 0;
-			this.offsetRotation = 0;
-			this.offsetX = 0;
-			this.offsetY = 0;
-			this.offsetScaleX = 0;
-			this.offsetScaleY = 0;
-			this.offsetShearY = 0;
-			this.relative = false;
-			this.local = false;
-			if (name == null)
-				throw new Error("name cannot be null.");
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			_this.rotateMix = 0;
+			_this.translateMix = 0;
+			_this.scaleMix = 0;
+			_this.shearMix = 0;
+			_this.offsetRotation = 0;
+			_this.offsetX = 0;
+			_this.offsetY = 0;
+			_this.offsetScaleX = 0;
+			_this.offsetScaleY = 0;
+			_this.offsetShearY = 0;
+			_this.relative = false;
+			_this.local = false;
+			return _this;
 		}
 		return TransformConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.TransformConstraintData = TransformConstraintData;
 })(spine || (spine = {}));
 var spine;
@@ -6428,6 +6543,14 @@ var spine;
 		};
 		Utils.webkit602BugfixHelper = function (alpha, blend) {
 		};
+		Utils.contains = function (array, element, identity) {
+			if (identity === void 0) { identity = true; }
+			for (var i = 0; i < array.length; i++) {
+				if (array[i] == element)
+					return true;
+			}
+			return false;
+		};
 		Utils.SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== "undefined";
 		return Utils;
 	}());
@@ -7177,6 +7300,8 @@ var spine;
 				ctx.save();
 				for (var i = 0, n = drawOrder.length; i < n; i++) {
 					var slot = drawOrder[i];
+					if (!slot.bone.active)
+						continue;
 					var attachment = slot.getAttachment();
 					var regionAttachment = null;
 					var region = null;
@@ -9435,6 +9560,8 @@ var spine;
 					var slots = skeleton.slots;
 					for (var i = 0, n = slots.length; i < n; i++) {
 						var slot = slots[i];
+						if (!slot.bone.active)
+							continue;
 						var attachment = slot.getAttachment();
 						if (!(attachment instanceof spine.MeshAttachment))
 							continue;
@@ -9480,6 +9607,8 @@ var spine;
 					var slots = skeleton.slots;
 					for (var i = 0, n = slots.length; i < n; i++) {
 						var slot = slots[i];
+						if (!slot.bone.active)
+							continue;
 						var attachment = slot.getAttachment();
 						if (!(attachment instanceof spine.PathAttachment))
 							continue;
@@ -9528,6 +9657,8 @@ var spine;
 					shapes.setColor(this.clipColor);
 					for (var i = 0, n = slots.length; i < n; i++) {
 						var slot = slots[i];
+						if (!slot.bone.active)
+							continue;
 						var attachment = slot.getAttachment();
 						if (!(attachment instanceof spine.ClippingAttachment))
 							continue;
@@ -9611,6 +9742,10 @@ var spine;
 				for (var i = 0, n = drawOrder.length; i < n; i++) {
 					var clippedVertexSize = clipper.isClipping() ? 2 : vertexSize;
 					var slot = drawOrder[i];
+					if (!slot.bone.active) {
+						clipper.clipEndWithSlot(slot);
+						continue;
+					}
 					if (slotRangeStart >= 0 && slotRangeStart == slot.data.index) {
 						inRange = true;
 					}
@@ -10185,6 +10320,8 @@ var spine;
 				for (var i = 0, n = drawOrder.length; i < n; i++) {
 					var vertexSize = clipper.isClipping() ? 2 : SkeletonMesh.VERTEX_SIZE;
 					var slot = drawOrder[i];
+					if (!slot.bone.active)
+						continue;
 					var attachment = slot.getAttachment();
 					var attachmentColor = null;
 					var texture = null;

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
spine-ts/build/spine-all.js.map


+ 23 - 18
spine-ts/build/spine-canvas.d.ts

@@ -447,7 +447,9 @@ declare module spine {
 		d: number;
 		worldY: number;
 		sorted: boolean;
+		active: boolean;
 		constructor(data: BoneData, skeleton: Skeleton, parent: Bone);
+		isActive(): boolean;
 		update(): void;
 		updateWorldTransform(): void;
 		updateWorldTransformWith(x: number, y: number, rotation: number, scaleX: number, scaleY: number, shearX: number, shearY: number): void;
@@ -478,6 +480,7 @@ declare module spine {
 		shearX: number;
 		shearY: number;
 		transformMode: TransformMode;
+		skinRequired: boolean;
 		constructor(index: number, name: string, parent: BoneData);
 	}
 	enum TransformMode {
@@ -489,8 +492,11 @@ declare module spine {
 	}
 }
 declare module spine {
-	interface Constraint extends Updatable {
-		getOrder(): number;
+	abstract class ConstraintData {
+		name: string;
+		order: number;
+		skinRequired: boolean;
+		constructor(name: string, order: number, skinRequired: boolean);
 	}
 }
 declare module spine {
@@ -518,7 +524,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class IkConstraint implements Constraint {
+	class IkConstraint implements Updatable {
 		data: IkConstraintData;
 		bones: Array<Bone>;
 		target: Bone;
@@ -526,8 +532,9 @@ declare module spine {
 		compress: boolean;
 		stretch: boolean;
 		mix: number;
+		active: boolean;
 		constructor(data: IkConstraintData, skeleton: Skeleton);
-		getOrder(): number;
+		isActive(): boolean;
 		apply(): void;
 		update(): void;
 		apply1(bone: Bone, targetX: number, targetY: number, compress: boolean, stretch: boolean, uniform: boolean, alpha: number): void;
@@ -535,9 +542,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class IkConstraintData {
-		name: string;
-		order: number;
+	class IkConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: BoneData;
 		bendDirection: number;
@@ -549,7 +554,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class PathConstraint implements Constraint {
+	class PathConstraint implements Updatable {
 		static NONE: number;
 		static BEFORE: number;
 		static AFTER: number;
@@ -567,20 +572,19 @@ declare module spine {
 		curves: number[];
 		lengths: number[];
 		segments: number[];
+		active: boolean;
 		constructor(data: PathConstraintData, skeleton: Skeleton);
+		isActive(): boolean;
 		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;
+	class PathConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: SlotData;
 		positionMode: PositionMode;
@@ -781,7 +785,7 @@ declare module spine {
 		name: string;
 		attachments: Map<Attachment>[];
 		bones: BoneData[];
-		constraints: Constraint[];
+		constraints: ConstraintData[];
 		constructor(name: string);
 		setAttachment(slotIndex: number, name: string, attachment: Attachment): void;
 		addSkin(skin: Skin): void;
@@ -899,7 +903,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class TransformConstraint implements Constraint {
+	class TransformConstraint implements Updatable {
 		data: TransformConstraintData;
 		bones: Array<Bone>;
 		target: Bone;
@@ -908,20 +912,19 @@ declare module spine {
 		scaleMix: number;
 		shearMix: number;
 		temp: Vector2;
+		active: boolean;
 		constructor(data: TransformConstraintData, skeleton: Skeleton);
+		isActive(): boolean;
 		apply(): void;
 		update(): void;
 		applyAbsoluteWorld(): void;
 		applyRelativeWorld(): void;
 		applyAbsoluteLocal(): void;
 		applyRelativeLocal(): void;
-		getOrder(): number;
 	}
 }
 declare module spine {
-	class TransformConstraintData {
-		name: string;
-		order: number;
+	class TransformConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: BoneData;
 		rotateMix: number;
@@ -958,6 +961,7 @@ declare module spine {
 declare module spine {
 	interface Updatable {
 		update(): void;
+		isActive(): boolean;
 	}
 }
 declare module spine {
@@ -1034,6 +1038,7 @@ declare module spine {
 		static toFloatArray(array: Array<number>): number[] | Float32Array;
 		static toSinglePrecision(value: number): number;
 		static webkit602BugfixHelper(alpha: number, blend: MixBlend): void;
+		static contains<T>(array: Array<T>, element: T, identity?: boolean): boolean;
 	}
 	class DebugUtils {
 		static logBones(skeleton: Skeleton): void;

+ 198 - 73
spine-ts/build/spine-canvas.js

@@ -188,6 +188,8 @@ var spine;
 		RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -257,6 +259,8 @@ var spine;
 		TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -318,6 +322,8 @@ var spine;
 		ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -416,6 +422,8 @@ var spine;
 		ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -480,6 +488,8 @@ var spine;
 		};
 		ColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var frames = this.frames;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -558,6 +568,8 @@ var spine;
 		};
 		TwoColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var frames = this.frames;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -652,6 +664,8 @@ var spine;
 		};
 		AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			if (direction == MixDirection.mixOut && blend == MixBlend.setup) {
 				var attachmentName_1 = slot.data.attachmentName;
 				slot.setAttachment(attachmentName_1 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_1));
@@ -697,6 +711,8 @@ var spine;
 		};
 		DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var slotAttachment = slot.getAttachment();
 			if (!(slotAttachment instanceof spine.VertexAttachment) || !(slotAttachment.deformAttachment == this.attachment))
 				return;
@@ -976,6 +992,8 @@ var spine;
 		IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.ikConstraints[this.ikConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1076,6 +1094,8 @@ var spine;
 		TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.transformConstraints[this.transformConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				var data = constraint.data;
 				switch (blend) {
@@ -1159,6 +1179,8 @@ var spine;
 		PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1202,6 +1224,8 @@ var spine;
 		PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1249,6 +1273,8 @@ var spine;
 		PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1535,6 +1561,8 @@ var spine;
 			var rotateTimeline = timeline;
 			var frames = rotateTimeline.frames;
 			var bone = skeleton.bones[rotateTimeline.boneIndex];
+			if (!bone.active)
+				return;
 			var r1 = 0, r2 = 0;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -2425,6 +2453,7 @@ var spine;
 			this.d = 0;
 			this.worldY = 0;
 			this.sorted = false;
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2434,6 +2463,9 @@ var spine;
 			this.parent = parent;
 			this.setToSetupPose();
 		}
+		Bone.prototype.isActive = function () {
+			return this.active;
+		};
 		Bone.prototype.update = function () {
 			this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY);
 		};
@@ -2658,6 +2690,7 @@ var spine;
 			this.shearX = 0;
 			this.shearY = 0;
 			this.transformMode = TransformMode.Normal;
+			this.skinRequired = false;
 			if (index < 0)
 				throw new Error("index must be >= 0.");
 			if (name == null)
@@ -2679,6 +2712,18 @@ var spine;
 	})(TransformMode = spine.TransformMode || (spine.TransformMode = {}));
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var ConstraintData = (function () {
+		function ConstraintData(name, order, skinRequired) {
+			this.name = name;
+			this.order = order;
+			this.skinRequired = skinRequired;
+		}
+		return ConstraintData;
+	}());
+	spine.ConstraintData = ConstraintData;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var Event = (function () {
 		function Event(time, data) {
@@ -2709,6 +2754,7 @@ var spine;
 			this.compress = false;
 			this.stretch = false;
 			this.mix = 1;
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2723,8 +2769,8 @@ var spine;
 				this.bones.push(skeleton.findBone(data.bones[i].name));
 			this.target = skeleton.findBone(data.target.name);
 		}
-		IkConstraint.prototype.getOrder = function () {
-			return this.data.order;
+		IkConstraint.prototype.isActive = function () {
+			return this.active;
 		};
 		IkConstraint.prototype.apply = function () {
 			this.update();
@@ -2908,19 +2954,20 @@ var spine;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var IkConstraintData = (function () {
+	var IkConstraintData = (function (_super) {
+		__extends(IkConstraintData, _super);
 		function IkConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.bendDirection = 1;
-			this.compress = false;
-			this.stretch = false;
-			this.uniform = false;
-			this.mix = 1;
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			_this.bendDirection = 1;
+			_this.compress = false;
+			_this.stretch = false;
+			_this.uniform = false;
+			_this.mix = 1;
+			return _this;
 		}
 		return IkConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.IkConstraintData = IkConstraintData;
 })(spine || (spine = {}));
 var spine;
@@ -2937,6 +2984,7 @@ var spine;
 			this.curves = new Array();
 			this.lengths = new Array();
 			this.segments = new Array();
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2951,6 +2999,9 @@ var spine;
 			this.rotateMix = data.rotateMix;
 			this.translateMix = data.translateMix;
 		}
+		PathConstraint.prototype.isActive = function () {
+			return this.active;
+		};
 		PathConstraint.prototype.apply = function () {
 			this.update();
 		};
@@ -3306,9 +3357,6 @@ var spine;
 					out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
 			}
 		};
-		PathConstraint.prototype.getOrder = function () {
-			return this.data.order;
-		};
 		PathConstraint.NONE = -1;
 		PathConstraint.BEFORE = -2;
 		PathConstraint.AFTER = -3;
@@ -3319,14 +3367,15 @@ var spine;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var PathConstraintData = (function () {
+	var PathConstraintData = (function (_super) {
+		__extends(PathConstraintData, _super);
 		function PathConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			return _this;
 		}
 		return PathConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.PathConstraintData = PathConstraintData;
 	var PositionMode;
 	(function (PositionMode) {
@@ -3543,8 +3592,22 @@ var spine;
 			updateCache.length = 0;
 			this.updateCacheReset.length = 0;
 			var bones = this.bones;
-			for (var i = 0, n = bones.length; i < n; i++)
-				bones[i].sorted = false;
+			for (var i = 0, n = bones.length; i < n; i++) {
+				var bone = bones[i];
+				bone.sorted = bone.data.skinRequired;
+				bone.active = !bone.sorted;
+			}
+			if (this.skin != null) {
+				var skinBones = this.skin.bones;
+				for (var i = 0, n = this.skin.bones.length; i < n; i++) {
+					var bone = this.bones[skinBones[i].index];
+					do {
+						bone.sorted = false;
+						bone.active = true;
+						bone = bone.parent;
+					} while (bone != null);
+				}
+			}
 			var ikConstraints = this.ikConstraints;
 			var transformConstraints = this.transformConstraints;
 			var pathConstraints = this.pathConstraints;
@@ -3577,6 +3640,9 @@ var spine;
 				this.sortBone(bones[i]);
 		};
 		Skeleton.prototype.sortIkConstraint = function (constraint) {
+			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			var target = constraint.target;
 			this.sortBone(target);
 			var constrained = constraint.bones;
@@ -3592,6 +3658,9 @@ var spine;
 			constrained[constrained.length - 1].sorted = true;
 		};
 		Skeleton.prototype.sortPathConstraint = function (constraint) {
+			constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			var slot = constraint.target;
 			var slotIndex = slot.data.index;
 			var slotBone = slot.bone;
@@ -3615,6 +3684,9 @@ var spine;
 				constrained[i].sorted = true;
 		};
 		Skeleton.prototype.sortTransformConstraint = function (constraint) {
+			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			this.sortBone(constraint.target);
 			var constrained = constraint.bones;
 			var boneCount = constrained.length;
@@ -3675,6 +3747,8 @@ var spine;
 		Skeleton.prototype.sortReset = function (bones) {
 			for (var i = 0, n = bones.length; i < n; i++) {
 				var bone = bones[i];
+				if (!bone.update)
+					continue;
 				if (bone.sorted)
 					this.sortReset(bone.children);
 				bone.sorted = false;
@@ -3790,6 +3864,8 @@ var spine;
 			this.setSkin(skin);
 		};
 		Skeleton.prototype.setSkin = function (newSkin) {
+			if (newSkin == this.skin)
+				return;
 			if (newSkin != null) {
 				if (this.skin != null)
 					newSkin.attachAll(this, this.skin);
@@ -3807,6 +3883,7 @@ var spine;
 				}
 			}
 			this.skin = newSkin;
+			this.updateCache();
 		};
 		Skeleton.prototype.getAttachmentByName = function (slotName, attachmentName) {
 			return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName);
@@ -4555,6 +4632,7 @@ var spine;
 					data.shearX = this.getValue(boneMap, "shearX", 0);
 					data.shearY = this.getValue(boneMap, "shearY", 0);
 					data.transformMode = SkeletonJson.transformModeFromString(this.getValue(boneMap, "transform", "normal"));
+					data.skinRequired = this.getValue(boneMap, "skin", false);
 					skeletonData.bones.push(data);
 				}
 			}
@@ -4585,6 +4663,7 @@ var spine;
 					var constraintMap = root.ik[i];
 					var data = new spine.IkConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4609,6 +4688,7 @@ var spine;
 					var constraintMap = root.transform[i];
 					var data = new spine.TransformConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4640,6 +4720,7 @@ var spine;
 					var constraintMap = root.path[i];
 					var data = new spine.PathConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4667,18 +4748,50 @@ var spine;
 				}
 			}
 			if (root.skins) {
-				for (var skinName in root.skins) {
-					var skinMap = root.skins[skinName];
-					var skin = new spine.Skin(skinName);
-					for (var slotName in skinMap) {
-						var slotIndex = skeletonData.findSlotIndex(slotName);
-						if (slotIndex == -1)
+				for (var i = 0; i < root.skins.length; i++) {
+					var skinMap = root.skins[i];
+					var skin = new spine.Skin(skinMap.name);
+					if (skinMap.bones) {
+						for (var ii = 0; ii < skinMap.bones.length; ii++) {
+							var bone = skeletonData.findBone(skinMap.bones[ii]);
+							if (bone == null)
+								throw new Error("Skin bone not found: " + skinMap.bones[i]);
+							skin.bones.push(bone);
+						}
+					}
+					if (skinMap.ik) {
+						for (var ii = 0; ii < skinMap.ik.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.ik[ii]);
+							if (constraint == null)
+								throw new Error("Skin IK constraint not found: " + skinMap.ik[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					if (skinMap.transform) {
+						for (var ii = 0; ii < skinMap.transform.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.transform[ii]);
+							if (constraint == null)
+								throw new Error("Skin transform constraint not found: " + skinMap.transform[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					if (skinMap.path) {
+						for (var ii = 0; ii < skinMap.path.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.path[ii]);
+							if (constraint == null)
+								throw new Error("Skin path constraint not found: " + skinMap.path[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					for (var slotName in skinMap.attachments) {
+						var slot = skeletonData.findSlot(slotName);
+						if (slot == null)
 							throw new Error("Slot not found: " + slotName);
-						var slotMap = skinMap[slotName];
+						var slotMap = skinMap.attachments[slotName];
 						for (var entryName in slotMap) {
-							var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName, skeletonData);
+							var attachment = this.readAttachment(slotMap[entryName], skin, slot.index, entryName, skeletonData);
 							if (attachment != null)
-								skin.setAttachment(slotIndex, entryName, attachment);
+								skin.setAttachment(slot.index, entryName, attachment);
 						}
 					}
 					skeletonData.skins.push(skin);
@@ -4878,7 +4991,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex++, valueMap.time, valueMap.name);
+								timeline.setFrame(frameIndex++, this.getValue(valueMap, "time", 0), valueMap.name);
 							}
 							timelines.push(timeline);
 							duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
@@ -4891,7 +5004,7 @@ var spine;
 								var valueMap = timelineMap[i];
 								var color = new spine.Color();
 								color.setFromString(valueMap.color);
-								timeline.setFrame(frameIndex, valueMap.time, color.r, color.g, color.b, color.a);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), color.r, color.g, color.b, color.a);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4908,7 +5021,7 @@ var spine;
 								var dark = new spine.Color();
 								light.setFromString(valueMap.light);
 								dark.setFromString(valueMap.dark);
-								timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4934,7 +5047,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, valueMap.angle);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "angle", 0));
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4943,9 +5056,11 @@ var spine;
 						}
 						else if (timelineName === "translate" || timelineName === "scale" || timelineName === "shear") {
 							var timeline = null;
-							var timelineScale = 1;
-							if (timelineName === "scale")
+							var timelineScale = 1, defaultValue = 0;
+							if (timelineName === "scale") {
 								timeline = new spine.ScaleTimeline(timelineMap.length);
+								defaultValue = 1;
+							}
 							else if (timelineName === "shear")
 								timeline = new spine.ShearTimeline(timelineMap.length);
 							else {
@@ -4956,8 +5071,8 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								var x = this.getValue(valueMap, "x", 0), y = this.getValue(valueMap, "y", 0);
-								timeline.setFrame(frameIndex, valueMap.time, x * timelineScale, y * timelineScale);
+								var x = this.getValue(valueMap, "x", defaultValue), y = this.getValue(valueMap, "y", defaultValue);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), x * timelineScale, y * timelineScale);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4978,7 +5093,7 @@ var spine;
 					var frameIndex = 0;
 					for (var i = 0; i < constraintMap.length; i++) {
 						var valueMap = constraintMap[i];
-						timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false));
+						timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false));
 						this.readCurve(valueMap, timeline, frameIndex);
 						frameIndex++;
 					}
@@ -4995,7 +5110,7 @@ var spine;
 					var frameIndex = 0;
 					for (var i = 0; i < constraintMap.length; i++) {
 						var valueMap = constraintMap[i];
-						timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1));
+						timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1));
 						this.readCurve(valueMap, timeline, frameIndex);
 						frameIndex++;
 					}
@@ -5003,9 +5118,9 @@ var spine;
 					duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TransformConstraintTimeline.ENTRIES]);
 				}
 			}
-			if (map.paths) {
-				for (var constraintName in map.paths) {
-					var constraintMap = map.paths[constraintName];
+			if (map.path) {
+				for (var constraintName in map.path) {
+					var constraintMap = map.path[constraintName];
 					var index = skeletonData.findPathConstraintIndex(constraintName);
 					if (index == -1)
 						throw new Error("Path constraint not found: " + constraintName);
@@ -5029,7 +5144,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, timelineName, 0) * timelineScale);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, timelineName, 0) * timelineScale);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5042,7 +5157,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1));
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1));
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5094,7 +5209,7 @@ var spine;
 											deform[i] += vertices[i];
 									}
 								}
-								timeline.setFrame(frameIndex, valueMap.time, deform);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), deform);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5134,7 +5249,7 @@ var spine;
 							if (drawOrder[i] == -1)
 								drawOrder[i] = unchanged[--unchangedIndex];
 					}
-					timeline.setFrame(frameIndex++, drawOrderMap.time, drawOrder);
+					timeline.setFrame(frameIndex++, this.getValue(drawOrderMap, "time", 0), drawOrder);
 				}
 				timelines.push(timeline);
 				duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
@@ -5147,7 +5262,7 @@ var spine;
 					var eventData = skeletonData.findEvent(eventMap.name);
 					if (eventData == null)
 						throw new Error("Event not found: " + eventMap.name);
-					var event_5 = new spine.Event(spine.Utils.toSinglePrecision(eventMap.time), eventData);
+					var event_5 = new spine.Event(spine.Utils.toSinglePrecision(this.getValue(eventMap, "time", 0)), eventData);
 					event_5.intValue = this.getValue(eventMap, "int", eventData.intValue);
 					event_5.floatValue = this.getValue(eventMap, "float", eventData.floatValue);
 					event_5.stringValue = this.getValue(eventMap, "string", eventData.stringValue);
@@ -5168,11 +5283,11 @@ var spine;
 		SkeletonJson.prototype.readCurve = function (map, timeline, frameIndex) {
 			if (!map.curve)
 				return;
-			if (map.curve === "stepped")
+			if (map.curve == "stepped")
 				timeline.setStepped(frameIndex);
 			else if (Object.prototype.toString.call(map.curve) === '[object Array]') {
 				var curve = map.curve;
-				timeline.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]);
+				timeline.setCurve(frameIndex, curve, this.getValue(map, "c2", 0), this.getValue(map, "c3", 1), this.getValue(map, "c4", 1));
 			}
 		};
 		SkeletonJson.prototype.getValue = function (map, prop, defaultValue) {
@@ -5725,6 +5840,7 @@ var spine;
 			this.scaleMix = 0;
 			this.shearMix = 0;
 			this.temp = new spine.Vector2();
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -5739,6 +5855,9 @@ var spine;
 				this.bones.push(skeleton.findBone(data.bones[i].name));
 			this.target = skeleton.findBone(data.target.name);
 		}
+		TransformConstraint.prototype.isActive = function () {
+			return this.active;
+		};
 		TransformConstraint.prototype.apply = function () {
 			this.update();
 		};
@@ -5948,37 +6067,33 @@ var spine;
 				bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
 			}
 		};
-		TransformConstraint.prototype.getOrder = function () {
-			return this.data.order;
-		};
 		return TransformConstraint;
 	}());
 	spine.TransformConstraint = TransformConstraint;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var TransformConstraintData = (function () {
+	var TransformConstraintData = (function (_super) {
+		__extends(TransformConstraintData, _super);
 		function TransformConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.rotateMix = 0;
-			this.translateMix = 0;
-			this.scaleMix = 0;
-			this.shearMix = 0;
-			this.offsetRotation = 0;
-			this.offsetX = 0;
-			this.offsetY = 0;
-			this.offsetScaleX = 0;
-			this.offsetScaleY = 0;
-			this.offsetShearY = 0;
-			this.relative = false;
-			this.local = false;
-			if (name == null)
-				throw new Error("name cannot be null.");
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			_this.rotateMix = 0;
+			_this.translateMix = 0;
+			_this.scaleMix = 0;
+			_this.shearMix = 0;
+			_this.offsetRotation = 0;
+			_this.offsetX = 0;
+			_this.offsetY = 0;
+			_this.offsetScaleX = 0;
+			_this.offsetScaleY = 0;
+			_this.offsetShearY = 0;
+			_this.relative = false;
+			_this.local = false;
+			return _this;
 		}
 		return TransformConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.TransformConstraintData = TransformConstraintData;
 })(spine || (spine = {}));
 var spine;
@@ -6428,6 +6543,14 @@ var spine;
 		};
 		Utils.webkit602BugfixHelper = function (alpha, blend) {
 		};
+		Utils.contains = function (array, element, identity) {
+			if (identity === void 0) { identity = true; }
+			for (var i = 0; i < array.length; i++) {
+				if (array[i] == element)
+					return true;
+			}
+			return false;
+		};
 		Utils.SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== "undefined";
 		return Utils;
 	}());
@@ -7177,6 +7300,8 @@ var spine;
 				ctx.save();
 				for (var i = 0, n = drawOrder.length; i < n; i++) {
 					var slot = drawOrder[i];
+					if (!slot.bone.active)
+						continue;
 					var attachment = slot.getAttachment();
 					var regionAttachment = null;
 					var region = null;

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
spine-ts/build/spine-canvas.js.map


+ 23 - 18
spine-ts/build/spine-core.d.ts

@@ -447,7 +447,9 @@ declare module spine {
 		d: number;
 		worldY: number;
 		sorted: boolean;
+		active: boolean;
 		constructor(data: BoneData, skeleton: Skeleton, parent: Bone);
+		isActive(): boolean;
 		update(): void;
 		updateWorldTransform(): void;
 		updateWorldTransformWith(x: number, y: number, rotation: number, scaleX: number, scaleY: number, shearX: number, shearY: number): void;
@@ -478,6 +480,7 @@ declare module spine {
 		shearX: number;
 		shearY: number;
 		transformMode: TransformMode;
+		skinRequired: boolean;
 		constructor(index: number, name: string, parent: BoneData);
 	}
 	enum TransformMode {
@@ -489,8 +492,11 @@ declare module spine {
 	}
 }
 declare module spine {
-	interface Constraint extends Updatable {
-		getOrder(): number;
+	abstract class ConstraintData {
+		name: string;
+		order: number;
+		skinRequired: boolean;
+		constructor(name: string, order: number, skinRequired: boolean);
 	}
 }
 declare module spine {
@@ -518,7 +524,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class IkConstraint implements Constraint {
+	class IkConstraint implements Updatable {
 		data: IkConstraintData;
 		bones: Array<Bone>;
 		target: Bone;
@@ -526,8 +532,9 @@ declare module spine {
 		compress: boolean;
 		stretch: boolean;
 		mix: number;
+		active: boolean;
 		constructor(data: IkConstraintData, skeleton: Skeleton);
-		getOrder(): number;
+		isActive(): boolean;
 		apply(): void;
 		update(): void;
 		apply1(bone: Bone, targetX: number, targetY: number, compress: boolean, stretch: boolean, uniform: boolean, alpha: number): void;
@@ -535,9 +542,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class IkConstraintData {
-		name: string;
-		order: number;
+	class IkConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: BoneData;
 		bendDirection: number;
@@ -549,7 +554,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class PathConstraint implements Constraint {
+	class PathConstraint implements Updatable {
 		static NONE: number;
 		static BEFORE: number;
 		static AFTER: number;
@@ -567,20 +572,19 @@ declare module spine {
 		curves: number[];
 		lengths: number[];
 		segments: number[];
+		active: boolean;
 		constructor(data: PathConstraintData, skeleton: Skeleton);
+		isActive(): boolean;
 		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;
+	class PathConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: SlotData;
 		positionMode: PositionMode;
@@ -781,7 +785,7 @@ declare module spine {
 		name: string;
 		attachments: Map<Attachment>[];
 		bones: BoneData[];
-		constraints: Constraint[];
+		constraints: ConstraintData[];
 		constructor(name: string);
 		setAttachment(slotIndex: number, name: string, attachment: Attachment): void;
 		addSkin(skin: Skin): void;
@@ -899,7 +903,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class TransformConstraint implements Constraint {
+	class TransformConstraint implements Updatable {
 		data: TransformConstraintData;
 		bones: Array<Bone>;
 		target: Bone;
@@ -908,20 +912,19 @@ declare module spine {
 		scaleMix: number;
 		shearMix: number;
 		temp: Vector2;
+		active: boolean;
 		constructor(data: TransformConstraintData, skeleton: Skeleton);
+		isActive(): boolean;
 		apply(): void;
 		update(): void;
 		applyAbsoluteWorld(): void;
 		applyRelativeWorld(): void;
 		applyAbsoluteLocal(): void;
 		applyRelativeLocal(): void;
-		getOrder(): number;
 	}
 }
 declare module spine {
-	class TransformConstraintData {
-		name: string;
-		order: number;
+	class TransformConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: BoneData;
 		rotateMix: number;
@@ -958,6 +961,7 @@ declare module spine {
 declare module spine {
 	interface Updatable {
 		update(): void;
+		isActive(): boolean;
 	}
 }
 declare module spine {
@@ -1034,6 +1038,7 @@ declare module spine {
 		static toFloatArray(array: Array<number>): number[] | Float32Array;
 		static toSinglePrecision(value: number): number;
 		static webkit602BugfixHelper(alpha: number, blend: MixBlend): void;
+		static contains<T>(array: Array<T>, element: T, identity?: boolean): boolean;
 	}
 	class DebugUtils {
 		static logBones(skeleton: Skeleton): void;

+ 196 - 73
spine-ts/build/spine-core.js

@@ -188,6 +188,8 @@ var spine;
 		RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -257,6 +259,8 @@ var spine;
 		TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -318,6 +322,8 @@ var spine;
 		ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -416,6 +422,8 @@ var spine;
 		ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -480,6 +488,8 @@ var spine;
 		};
 		ColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var frames = this.frames;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -558,6 +568,8 @@ var spine;
 		};
 		TwoColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var frames = this.frames;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -652,6 +664,8 @@ var spine;
 		};
 		AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			if (direction == MixDirection.mixOut && blend == MixBlend.setup) {
 				var attachmentName_1 = slot.data.attachmentName;
 				slot.setAttachment(attachmentName_1 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_1));
@@ -697,6 +711,8 @@ var spine;
 		};
 		DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var slotAttachment = slot.getAttachment();
 			if (!(slotAttachment instanceof spine.VertexAttachment) || !(slotAttachment.deformAttachment == this.attachment))
 				return;
@@ -976,6 +992,8 @@ var spine;
 		IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.ikConstraints[this.ikConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1076,6 +1094,8 @@ var spine;
 		TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.transformConstraints[this.transformConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				var data = constraint.data;
 				switch (blend) {
@@ -1159,6 +1179,8 @@ var spine;
 		PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1202,6 +1224,8 @@ var spine;
 		PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1249,6 +1273,8 @@ var spine;
 		PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1535,6 +1561,8 @@ var spine;
 			var rotateTimeline = timeline;
 			var frames = rotateTimeline.frames;
 			var bone = skeleton.bones[rotateTimeline.boneIndex];
+			if (!bone.active)
+				return;
 			var r1 = 0, r2 = 0;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -2425,6 +2453,7 @@ var spine;
 			this.d = 0;
 			this.worldY = 0;
 			this.sorted = false;
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2434,6 +2463,9 @@ var spine;
 			this.parent = parent;
 			this.setToSetupPose();
 		}
+		Bone.prototype.isActive = function () {
+			return this.active;
+		};
 		Bone.prototype.update = function () {
 			this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY);
 		};
@@ -2658,6 +2690,7 @@ var spine;
 			this.shearX = 0;
 			this.shearY = 0;
 			this.transformMode = TransformMode.Normal;
+			this.skinRequired = false;
 			if (index < 0)
 				throw new Error("index must be >= 0.");
 			if (name == null)
@@ -2679,6 +2712,18 @@ var spine;
 	})(TransformMode = spine.TransformMode || (spine.TransformMode = {}));
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var ConstraintData = (function () {
+		function ConstraintData(name, order, skinRequired) {
+			this.name = name;
+			this.order = order;
+			this.skinRequired = skinRequired;
+		}
+		return ConstraintData;
+	}());
+	spine.ConstraintData = ConstraintData;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var Event = (function () {
 		function Event(time, data) {
@@ -2709,6 +2754,7 @@ var spine;
 			this.compress = false;
 			this.stretch = false;
 			this.mix = 1;
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2723,8 +2769,8 @@ var spine;
 				this.bones.push(skeleton.findBone(data.bones[i].name));
 			this.target = skeleton.findBone(data.target.name);
 		}
-		IkConstraint.prototype.getOrder = function () {
-			return this.data.order;
+		IkConstraint.prototype.isActive = function () {
+			return this.active;
 		};
 		IkConstraint.prototype.apply = function () {
 			this.update();
@@ -2908,19 +2954,20 @@ var spine;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var IkConstraintData = (function () {
+	var IkConstraintData = (function (_super) {
+		__extends(IkConstraintData, _super);
 		function IkConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.bendDirection = 1;
-			this.compress = false;
-			this.stretch = false;
-			this.uniform = false;
-			this.mix = 1;
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			_this.bendDirection = 1;
+			_this.compress = false;
+			_this.stretch = false;
+			_this.uniform = false;
+			_this.mix = 1;
+			return _this;
 		}
 		return IkConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.IkConstraintData = IkConstraintData;
 })(spine || (spine = {}));
 var spine;
@@ -2937,6 +2984,7 @@ var spine;
 			this.curves = new Array();
 			this.lengths = new Array();
 			this.segments = new Array();
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2951,6 +2999,9 @@ var spine;
 			this.rotateMix = data.rotateMix;
 			this.translateMix = data.translateMix;
 		}
+		PathConstraint.prototype.isActive = function () {
+			return this.active;
+		};
 		PathConstraint.prototype.apply = function () {
 			this.update();
 		};
@@ -3306,9 +3357,6 @@ var spine;
 					out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
 			}
 		};
-		PathConstraint.prototype.getOrder = function () {
-			return this.data.order;
-		};
 		PathConstraint.NONE = -1;
 		PathConstraint.BEFORE = -2;
 		PathConstraint.AFTER = -3;
@@ -3319,14 +3367,15 @@ var spine;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var PathConstraintData = (function () {
+	var PathConstraintData = (function (_super) {
+		__extends(PathConstraintData, _super);
 		function PathConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			return _this;
 		}
 		return PathConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.PathConstraintData = PathConstraintData;
 	var PositionMode;
 	(function (PositionMode) {
@@ -3543,8 +3592,22 @@ var spine;
 			updateCache.length = 0;
 			this.updateCacheReset.length = 0;
 			var bones = this.bones;
-			for (var i = 0, n = bones.length; i < n; i++)
-				bones[i].sorted = false;
+			for (var i = 0, n = bones.length; i < n; i++) {
+				var bone = bones[i];
+				bone.sorted = bone.data.skinRequired;
+				bone.active = !bone.sorted;
+			}
+			if (this.skin != null) {
+				var skinBones = this.skin.bones;
+				for (var i = 0, n = this.skin.bones.length; i < n; i++) {
+					var bone = this.bones[skinBones[i].index];
+					do {
+						bone.sorted = false;
+						bone.active = true;
+						bone = bone.parent;
+					} while (bone != null);
+				}
+			}
 			var ikConstraints = this.ikConstraints;
 			var transformConstraints = this.transformConstraints;
 			var pathConstraints = this.pathConstraints;
@@ -3577,6 +3640,9 @@ var spine;
 				this.sortBone(bones[i]);
 		};
 		Skeleton.prototype.sortIkConstraint = function (constraint) {
+			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			var target = constraint.target;
 			this.sortBone(target);
 			var constrained = constraint.bones;
@@ -3592,6 +3658,9 @@ var spine;
 			constrained[constrained.length - 1].sorted = true;
 		};
 		Skeleton.prototype.sortPathConstraint = function (constraint) {
+			constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			var slot = constraint.target;
 			var slotIndex = slot.data.index;
 			var slotBone = slot.bone;
@@ -3615,6 +3684,9 @@ var spine;
 				constrained[i].sorted = true;
 		};
 		Skeleton.prototype.sortTransformConstraint = function (constraint) {
+			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			this.sortBone(constraint.target);
 			var constrained = constraint.bones;
 			var boneCount = constrained.length;
@@ -3675,6 +3747,8 @@ var spine;
 		Skeleton.prototype.sortReset = function (bones) {
 			for (var i = 0, n = bones.length; i < n; i++) {
 				var bone = bones[i];
+				if (!bone.update)
+					continue;
 				if (bone.sorted)
 					this.sortReset(bone.children);
 				bone.sorted = false;
@@ -3790,6 +3864,8 @@ var spine;
 			this.setSkin(skin);
 		};
 		Skeleton.prototype.setSkin = function (newSkin) {
+			if (newSkin == this.skin)
+				return;
 			if (newSkin != null) {
 				if (this.skin != null)
 					newSkin.attachAll(this, this.skin);
@@ -3807,6 +3883,7 @@ var spine;
 				}
 			}
 			this.skin = newSkin;
+			this.updateCache();
 		};
 		Skeleton.prototype.getAttachmentByName = function (slotName, attachmentName) {
 			return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName);
@@ -4555,6 +4632,7 @@ var spine;
 					data.shearX = this.getValue(boneMap, "shearX", 0);
 					data.shearY = this.getValue(boneMap, "shearY", 0);
 					data.transformMode = SkeletonJson.transformModeFromString(this.getValue(boneMap, "transform", "normal"));
+					data.skinRequired = this.getValue(boneMap, "skin", false);
 					skeletonData.bones.push(data);
 				}
 			}
@@ -4585,6 +4663,7 @@ var spine;
 					var constraintMap = root.ik[i];
 					var data = new spine.IkConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4609,6 +4688,7 @@ var spine;
 					var constraintMap = root.transform[i];
 					var data = new spine.TransformConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4640,6 +4720,7 @@ var spine;
 					var constraintMap = root.path[i];
 					var data = new spine.PathConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4667,18 +4748,50 @@ var spine;
 				}
 			}
 			if (root.skins) {
-				for (var skinName in root.skins) {
-					var skinMap = root.skins[skinName];
-					var skin = new spine.Skin(skinName);
-					for (var slotName in skinMap) {
-						var slotIndex = skeletonData.findSlotIndex(slotName);
-						if (slotIndex == -1)
+				for (var i = 0; i < root.skins.length; i++) {
+					var skinMap = root.skins[i];
+					var skin = new spine.Skin(skinMap.name);
+					if (skinMap.bones) {
+						for (var ii = 0; ii < skinMap.bones.length; ii++) {
+							var bone = skeletonData.findBone(skinMap.bones[ii]);
+							if (bone == null)
+								throw new Error("Skin bone not found: " + skinMap.bones[i]);
+							skin.bones.push(bone);
+						}
+					}
+					if (skinMap.ik) {
+						for (var ii = 0; ii < skinMap.ik.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.ik[ii]);
+							if (constraint == null)
+								throw new Error("Skin IK constraint not found: " + skinMap.ik[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					if (skinMap.transform) {
+						for (var ii = 0; ii < skinMap.transform.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.transform[ii]);
+							if (constraint == null)
+								throw new Error("Skin transform constraint not found: " + skinMap.transform[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					if (skinMap.path) {
+						for (var ii = 0; ii < skinMap.path.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.path[ii]);
+							if (constraint == null)
+								throw new Error("Skin path constraint not found: " + skinMap.path[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					for (var slotName in skinMap.attachments) {
+						var slot = skeletonData.findSlot(slotName);
+						if (slot == null)
 							throw new Error("Slot not found: " + slotName);
-						var slotMap = skinMap[slotName];
+						var slotMap = skinMap.attachments[slotName];
 						for (var entryName in slotMap) {
-							var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName, skeletonData);
+							var attachment = this.readAttachment(slotMap[entryName], skin, slot.index, entryName, skeletonData);
 							if (attachment != null)
-								skin.setAttachment(slotIndex, entryName, attachment);
+								skin.setAttachment(slot.index, entryName, attachment);
 						}
 					}
 					skeletonData.skins.push(skin);
@@ -4878,7 +4991,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex++, valueMap.time, valueMap.name);
+								timeline.setFrame(frameIndex++, this.getValue(valueMap, "time", 0), valueMap.name);
 							}
 							timelines.push(timeline);
 							duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
@@ -4891,7 +5004,7 @@ var spine;
 								var valueMap = timelineMap[i];
 								var color = new spine.Color();
 								color.setFromString(valueMap.color);
-								timeline.setFrame(frameIndex, valueMap.time, color.r, color.g, color.b, color.a);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), color.r, color.g, color.b, color.a);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4908,7 +5021,7 @@ var spine;
 								var dark = new spine.Color();
 								light.setFromString(valueMap.light);
 								dark.setFromString(valueMap.dark);
-								timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4934,7 +5047,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, valueMap.angle);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "angle", 0));
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4943,9 +5056,11 @@ var spine;
 						}
 						else if (timelineName === "translate" || timelineName === "scale" || timelineName === "shear") {
 							var timeline = null;
-							var timelineScale = 1;
-							if (timelineName === "scale")
+							var timelineScale = 1, defaultValue = 0;
+							if (timelineName === "scale") {
 								timeline = new spine.ScaleTimeline(timelineMap.length);
+								defaultValue = 1;
+							}
 							else if (timelineName === "shear")
 								timeline = new spine.ShearTimeline(timelineMap.length);
 							else {
@@ -4956,8 +5071,8 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								var x = this.getValue(valueMap, "x", 0), y = this.getValue(valueMap, "y", 0);
-								timeline.setFrame(frameIndex, valueMap.time, x * timelineScale, y * timelineScale);
+								var x = this.getValue(valueMap, "x", defaultValue), y = this.getValue(valueMap, "y", defaultValue);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), x * timelineScale, y * timelineScale);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4978,7 +5093,7 @@ var spine;
 					var frameIndex = 0;
 					for (var i = 0; i < constraintMap.length; i++) {
 						var valueMap = constraintMap[i];
-						timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false));
+						timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false));
 						this.readCurve(valueMap, timeline, frameIndex);
 						frameIndex++;
 					}
@@ -4995,7 +5110,7 @@ var spine;
 					var frameIndex = 0;
 					for (var i = 0; i < constraintMap.length; i++) {
 						var valueMap = constraintMap[i];
-						timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1));
+						timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1));
 						this.readCurve(valueMap, timeline, frameIndex);
 						frameIndex++;
 					}
@@ -5003,9 +5118,9 @@ var spine;
 					duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TransformConstraintTimeline.ENTRIES]);
 				}
 			}
-			if (map.paths) {
-				for (var constraintName in map.paths) {
-					var constraintMap = map.paths[constraintName];
+			if (map.path) {
+				for (var constraintName in map.path) {
+					var constraintMap = map.path[constraintName];
 					var index = skeletonData.findPathConstraintIndex(constraintName);
 					if (index == -1)
 						throw new Error("Path constraint not found: " + constraintName);
@@ -5029,7 +5144,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, timelineName, 0) * timelineScale);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, timelineName, 0) * timelineScale);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5042,7 +5157,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1));
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1));
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5094,7 +5209,7 @@ var spine;
 											deform[i] += vertices[i];
 									}
 								}
-								timeline.setFrame(frameIndex, valueMap.time, deform);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), deform);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5134,7 +5249,7 @@ var spine;
 							if (drawOrder[i] == -1)
 								drawOrder[i] = unchanged[--unchangedIndex];
 					}
-					timeline.setFrame(frameIndex++, drawOrderMap.time, drawOrder);
+					timeline.setFrame(frameIndex++, this.getValue(drawOrderMap, "time", 0), drawOrder);
 				}
 				timelines.push(timeline);
 				duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
@@ -5147,7 +5262,7 @@ var spine;
 					var eventData = skeletonData.findEvent(eventMap.name);
 					if (eventData == null)
 						throw new Error("Event not found: " + eventMap.name);
-					var event_5 = new spine.Event(spine.Utils.toSinglePrecision(eventMap.time), eventData);
+					var event_5 = new spine.Event(spine.Utils.toSinglePrecision(this.getValue(eventMap, "time", 0)), eventData);
 					event_5.intValue = this.getValue(eventMap, "int", eventData.intValue);
 					event_5.floatValue = this.getValue(eventMap, "float", eventData.floatValue);
 					event_5.stringValue = this.getValue(eventMap, "string", eventData.stringValue);
@@ -5168,11 +5283,11 @@ var spine;
 		SkeletonJson.prototype.readCurve = function (map, timeline, frameIndex) {
 			if (!map.curve)
 				return;
-			if (map.curve === "stepped")
+			if (map.curve == "stepped")
 				timeline.setStepped(frameIndex);
 			else if (Object.prototype.toString.call(map.curve) === '[object Array]') {
 				var curve = map.curve;
-				timeline.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]);
+				timeline.setCurve(frameIndex, curve, this.getValue(map, "c2", 0), this.getValue(map, "c3", 1), this.getValue(map, "c4", 1));
 			}
 		};
 		SkeletonJson.prototype.getValue = function (map, prop, defaultValue) {
@@ -5725,6 +5840,7 @@ var spine;
 			this.scaleMix = 0;
 			this.shearMix = 0;
 			this.temp = new spine.Vector2();
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -5739,6 +5855,9 @@ var spine;
 				this.bones.push(skeleton.findBone(data.bones[i].name));
 			this.target = skeleton.findBone(data.target.name);
 		}
+		TransformConstraint.prototype.isActive = function () {
+			return this.active;
+		};
 		TransformConstraint.prototype.apply = function () {
 			this.update();
 		};
@@ -5948,37 +6067,33 @@ var spine;
 				bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
 			}
 		};
-		TransformConstraint.prototype.getOrder = function () {
-			return this.data.order;
-		};
 		return TransformConstraint;
 	}());
 	spine.TransformConstraint = TransformConstraint;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var TransformConstraintData = (function () {
+	var TransformConstraintData = (function (_super) {
+		__extends(TransformConstraintData, _super);
 		function TransformConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.rotateMix = 0;
-			this.translateMix = 0;
-			this.scaleMix = 0;
-			this.shearMix = 0;
-			this.offsetRotation = 0;
-			this.offsetX = 0;
-			this.offsetY = 0;
-			this.offsetScaleX = 0;
-			this.offsetScaleY = 0;
-			this.offsetShearY = 0;
-			this.relative = false;
-			this.local = false;
-			if (name == null)
-				throw new Error("name cannot be null.");
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			_this.rotateMix = 0;
+			_this.translateMix = 0;
+			_this.scaleMix = 0;
+			_this.shearMix = 0;
+			_this.offsetRotation = 0;
+			_this.offsetX = 0;
+			_this.offsetY = 0;
+			_this.offsetScaleX = 0;
+			_this.offsetScaleY = 0;
+			_this.offsetShearY = 0;
+			_this.relative = false;
+			_this.local = false;
+			return _this;
 		}
 		return TransformConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.TransformConstraintData = TransformConstraintData;
 })(spine || (spine = {}));
 var spine;
@@ -6428,6 +6543,14 @@ var spine;
 		};
 		Utils.webkit602BugfixHelper = function (alpha, blend) {
 		};
+		Utils.contains = function (array, element, identity) {
+			if (identity === void 0) { identity = true; }
+			for (var i = 0; i < array.length; i++) {
+				if (array[i] == element)
+					return true;
+			}
+			return false;
+		};
 		Utils.SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== "undefined";
 		return Utils;
 	}());

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
spine-ts/build/spine-core.js.map


+ 23 - 18
spine-ts/build/spine-player.d.ts

@@ -447,7 +447,9 @@ declare module spine {
 		d: number;
 		worldY: number;
 		sorted: boolean;
+		active: boolean;
 		constructor(data: BoneData, skeleton: Skeleton, parent: Bone);
+		isActive(): boolean;
 		update(): void;
 		updateWorldTransform(): void;
 		updateWorldTransformWith(x: number, y: number, rotation: number, scaleX: number, scaleY: number, shearX: number, shearY: number): void;
@@ -478,6 +480,7 @@ declare module spine {
 		shearX: number;
 		shearY: number;
 		transformMode: TransformMode;
+		skinRequired: boolean;
 		constructor(index: number, name: string, parent: BoneData);
 	}
 	enum TransformMode {
@@ -489,8 +492,11 @@ declare module spine {
 	}
 }
 declare module spine {
-	interface Constraint extends Updatable {
-		getOrder(): number;
+	abstract class ConstraintData {
+		name: string;
+		order: number;
+		skinRequired: boolean;
+		constructor(name: string, order: number, skinRequired: boolean);
 	}
 }
 declare module spine {
@@ -518,7 +524,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class IkConstraint implements Constraint {
+	class IkConstraint implements Updatable {
 		data: IkConstraintData;
 		bones: Array<Bone>;
 		target: Bone;
@@ -526,8 +532,9 @@ declare module spine {
 		compress: boolean;
 		stretch: boolean;
 		mix: number;
+		active: boolean;
 		constructor(data: IkConstraintData, skeleton: Skeleton);
-		getOrder(): number;
+		isActive(): boolean;
 		apply(): void;
 		update(): void;
 		apply1(bone: Bone, targetX: number, targetY: number, compress: boolean, stretch: boolean, uniform: boolean, alpha: number): void;
@@ -535,9 +542,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class IkConstraintData {
-		name: string;
-		order: number;
+	class IkConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: BoneData;
 		bendDirection: number;
@@ -549,7 +554,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class PathConstraint implements Constraint {
+	class PathConstraint implements Updatable {
 		static NONE: number;
 		static BEFORE: number;
 		static AFTER: number;
@@ -567,20 +572,19 @@ declare module spine {
 		curves: number[];
 		lengths: number[];
 		segments: number[];
+		active: boolean;
 		constructor(data: PathConstraintData, skeleton: Skeleton);
+		isActive(): boolean;
 		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;
+	class PathConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: SlotData;
 		positionMode: PositionMode;
@@ -781,7 +785,7 @@ declare module spine {
 		name: string;
 		attachments: Map<Attachment>[];
 		bones: BoneData[];
-		constraints: Constraint[];
+		constraints: ConstraintData[];
 		constructor(name: string);
 		setAttachment(slotIndex: number, name: string, attachment: Attachment): void;
 		addSkin(skin: Skin): void;
@@ -899,7 +903,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class TransformConstraint implements Constraint {
+	class TransformConstraint implements Updatable {
 		data: TransformConstraintData;
 		bones: Array<Bone>;
 		target: Bone;
@@ -908,20 +912,19 @@ declare module spine {
 		scaleMix: number;
 		shearMix: number;
 		temp: Vector2;
+		active: boolean;
 		constructor(data: TransformConstraintData, skeleton: Skeleton);
+		isActive(): boolean;
 		apply(): void;
 		update(): void;
 		applyAbsoluteWorld(): void;
 		applyRelativeWorld(): void;
 		applyAbsoluteLocal(): void;
 		applyRelativeLocal(): void;
-		getOrder(): number;
 	}
 }
 declare module spine {
-	class TransformConstraintData {
-		name: string;
-		order: number;
+	class TransformConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: BoneData;
 		rotateMix: number;
@@ -958,6 +961,7 @@ declare module spine {
 declare module spine {
 	interface Updatable {
 		update(): void;
+		isActive(): boolean;
 	}
 }
 declare module spine {
@@ -1034,6 +1038,7 @@ declare module spine {
 		static toFloatArray(array: Array<number>): number[] | Float32Array;
 		static toSinglePrecision(value: number): number;
 		static webkit602BugfixHelper(alpha: number, blend: MixBlend): void;
+		static contains<T>(array: Array<T>, element: T, identity?: boolean): boolean;
 	}
 	class DebugUtils {
 		static logBones(skeleton: Skeleton): void;

+ 206 - 73
spine-ts/build/spine-player.js

@@ -188,6 +188,8 @@ var spine;
 		RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -257,6 +259,8 @@ var spine;
 		TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -318,6 +322,8 @@ var spine;
 		ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -416,6 +422,8 @@ var spine;
 		ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -480,6 +488,8 @@ var spine;
 		};
 		ColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var frames = this.frames;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -558,6 +568,8 @@ var spine;
 		};
 		TwoColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var frames = this.frames;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -652,6 +664,8 @@ var spine;
 		};
 		AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			if (direction == MixDirection.mixOut && blend == MixBlend.setup) {
 				var attachmentName_1 = slot.data.attachmentName;
 				slot.setAttachment(attachmentName_1 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_1));
@@ -697,6 +711,8 @@ var spine;
 		};
 		DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var slotAttachment = slot.getAttachment();
 			if (!(slotAttachment instanceof spine.VertexAttachment) || !(slotAttachment.deformAttachment == this.attachment))
 				return;
@@ -976,6 +992,8 @@ var spine;
 		IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.ikConstraints[this.ikConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1076,6 +1094,8 @@ var spine;
 		TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.transformConstraints[this.transformConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				var data = constraint.data;
 				switch (blend) {
@@ -1159,6 +1179,8 @@ var spine;
 		PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1202,6 +1224,8 @@ var spine;
 		PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1249,6 +1273,8 @@ var spine;
 		PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1535,6 +1561,8 @@ var spine;
 			var rotateTimeline = timeline;
 			var frames = rotateTimeline.frames;
 			var bone = skeleton.bones[rotateTimeline.boneIndex];
+			if (!bone.active)
+				return;
 			var r1 = 0, r2 = 0;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -2425,6 +2453,7 @@ var spine;
 			this.d = 0;
 			this.worldY = 0;
 			this.sorted = false;
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2434,6 +2463,9 @@ var spine;
 			this.parent = parent;
 			this.setToSetupPose();
 		}
+		Bone.prototype.isActive = function () {
+			return this.active;
+		};
 		Bone.prototype.update = function () {
 			this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY);
 		};
@@ -2658,6 +2690,7 @@ var spine;
 			this.shearX = 0;
 			this.shearY = 0;
 			this.transformMode = TransformMode.Normal;
+			this.skinRequired = false;
 			if (index < 0)
 				throw new Error("index must be >= 0.");
 			if (name == null)
@@ -2679,6 +2712,18 @@ var spine;
 	})(TransformMode = spine.TransformMode || (spine.TransformMode = {}));
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var ConstraintData = (function () {
+		function ConstraintData(name, order, skinRequired) {
+			this.name = name;
+			this.order = order;
+			this.skinRequired = skinRequired;
+		}
+		return ConstraintData;
+	}());
+	spine.ConstraintData = ConstraintData;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var Event = (function () {
 		function Event(time, data) {
@@ -2709,6 +2754,7 @@ var spine;
 			this.compress = false;
 			this.stretch = false;
 			this.mix = 1;
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2723,8 +2769,8 @@ var spine;
 				this.bones.push(skeleton.findBone(data.bones[i].name));
 			this.target = skeleton.findBone(data.target.name);
 		}
-		IkConstraint.prototype.getOrder = function () {
-			return this.data.order;
+		IkConstraint.prototype.isActive = function () {
+			return this.active;
 		};
 		IkConstraint.prototype.apply = function () {
 			this.update();
@@ -2908,19 +2954,20 @@ var spine;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var IkConstraintData = (function () {
+	var IkConstraintData = (function (_super) {
+		__extends(IkConstraintData, _super);
 		function IkConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.bendDirection = 1;
-			this.compress = false;
-			this.stretch = false;
-			this.uniform = false;
-			this.mix = 1;
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			_this.bendDirection = 1;
+			_this.compress = false;
+			_this.stretch = false;
+			_this.uniform = false;
+			_this.mix = 1;
+			return _this;
 		}
 		return IkConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.IkConstraintData = IkConstraintData;
 })(spine || (spine = {}));
 var spine;
@@ -2937,6 +2984,7 @@ var spine;
 			this.curves = new Array();
 			this.lengths = new Array();
 			this.segments = new Array();
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2951,6 +2999,9 @@ var spine;
 			this.rotateMix = data.rotateMix;
 			this.translateMix = data.translateMix;
 		}
+		PathConstraint.prototype.isActive = function () {
+			return this.active;
+		};
 		PathConstraint.prototype.apply = function () {
 			this.update();
 		};
@@ -3306,9 +3357,6 @@ var spine;
 					out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
 			}
 		};
-		PathConstraint.prototype.getOrder = function () {
-			return this.data.order;
-		};
 		PathConstraint.NONE = -1;
 		PathConstraint.BEFORE = -2;
 		PathConstraint.AFTER = -3;
@@ -3319,14 +3367,15 @@ var spine;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var PathConstraintData = (function () {
+	var PathConstraintData = (function (_super) {
+		__extends(PathConstraintData, _super);
 		function PathConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			return _this;
 		}
 		return PathConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.PathConstraintData = PathConstraintData;
 	var PositionMode;
 	(function (PositionMode) {
@@ -3543,8 +3592,22 @@ var spine;
 			updateCache.length = 0;
 			this.updateCacheReset.length = 0;
 			var bones = this.bones;
-			for (var i = 0, n = bones.length; i < n; i++)
-				bones[i].sorted = false;
+			for (var i = 0, n = bones.length; i < n; i++) {
+				var bone = bones[i];
+				bone.sorted = bone.data.skinRequired;
+				bone.active = !bone.sorted;
+			}
+			if (this.skin != null) {
+				var skinBones = this.skin.bones;
+				for (var i = 0, n = this.skin.bones.length; i < n; i++) {
+					var bone = this.bones[skinBones[i].index];
+					do {
+						bone.sorted = false;
+						bone.active = true;
+						bone = bone.parent;
+					} while (bone != null);
+				}
+			}
 			var ikConstraints = this.ikConstraints;
 			var transformConstraints = this.transformConstraints;
 			var pathConstraints = this.pathConstraints;
@@ -3577,6 +3640,9 @@ var spine;
 				this.sortBone(bones[i]);
 		};
 		Skeleton.prototype.sortIkConstraint = function (constraint) {
+			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			var target = constraint.target;
 			this.sortBone(target);
 			var constrained = constraint.bones;
@@ -3592,6 +3658,9 @@ var spine;
 			constrained[constrained.length - 1].sorted = true;
 		};
 		Skeleton.prototype.sortPathConstraint = function (constraint) {
+			constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			var slot = constraint.target;
 			var slotIndex = slot.data.index;
 			var slotBone = slot.bone;
@@ -3615,6 +3684,9 @@ var spine;
 				constrained[i].sorted = true;
 		};
 		Skeleton.prototype.sortTransformConstraint = function (constraint) {
+			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			this.sortBone(constraint.target);
 			var constrained = constraint.bones;
 			var boneCount = constrained.length;
@@ -3675,6 +3747,8 @@ var spine;
 		Skeleton.prototype.sortReset = function (bones) {
 			for (var i = 0, n = bones.length; i < n; i++) {
 				var bone = bones[i];
+				if (!bone.update)
+					continue;
 				if (bone.sorted)
 					this.sortReset(bone.children);
 				bone.sorted = false;
@@ -3790,6 +3864,8 @@ var spine;
 			this.setSkin(skin);
 		};
 		Skeleton.prototype.setSkin = function (newSkin) {
+			if (newSkin == this.skin)
+				return;
 			if (newSkin != null) {
 				if (this.skin != null)
 					newSkin.attachAll(this, this.skin);
@@ -3807,6 +3883,7 @@ var spine;
 				}
 			}
 			this.skin = newSkin;
+			this.updateCache();
 		};
 		Skeleton.prototype.getAttachmentByName = function (slotName, attachmentName) {
 			return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName);
@@ -4555,6 +4632,7 @@ var spine;
 					data.shearX = this.getValue(boneMap, "shearX", 0);
 					data.shearY = this.getValue(boneMap, "shearY", 0);
 					data.transformMode = SkeletonJson.transformModeFromString(this.getValue(boneMap, "transform", "normal"));
+					data.skinRequired = this.getValue(boneMap, "skin", false);
 					skeletonData.bones.push(data);
 				}
 			}
@@ -4585,6 +4663,7 @@ var spine;
 					var constraintMap = root.ik[i];
 					var data = new spine.IkConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4609,6 +4688,7 @@ var spine;
 					var constraintMap = root.transform[i];
 					var data = new spine.TransformConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4640,6 +4720,7 @@ var spine;
 					var constraintMap = root.path[i];
 					var data = new spine.PathConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4667,18 +4748,50 @@ var spine;
 				}
 			}
 			if (root.skins) {
-				for (var skinName in root.skins) {
-					var skinMap = root.skins[skinName];
-					var skin = new spine.Skin(skinName);
-					for (var slotName in skinMap) {
-						var slotIndex = skeletonData.findSlotIndex(slotName);
-						if (slotIndex == -1)
+				for (var i = 0; i < root.skins.length; i++) {
+					var skinMap = root.skins[i];
+					var skin = new spine.Skin(skinMap.name);
+					if (skinMap.bones) {
+						for (var ii = 0; ii < skinMap.bones.length; ii++) {
+							var bone = skeletonData.findBone(skinMap.bones[ii]);
+							if (bone == null)
+								throw new Error("Skin bone not found: " + skinMap.bones[i]);
+							skin.bones.push(bone);
+						}
+					}
+					if (skinMap.ik) {
+						for (var ii = 0; ii < skinMap.ik.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.ik[ii]);
+							if (constraint == null)
+								throw new Error("Skin IK constraint not found: " + skinMap.ik[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					if (skinMap.transform) {
+						for (var ii = 0; ii < skinMap.transform.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.transform[ii]);
+							if (constraint == null)
+								throw new Error("Skin transform constraint not found: " + skinMap.transform[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					if (skinMap.path) {
+						for (var ii = 0; ii < skinMap.path.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.path[ii]);
+							if (constraint == null)
+								throw new Error("Skin path constraint not found: " + skinMap.path[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					for (var slotName in skinMap.attachments) {
+						var slot = skeletonData.findSlot(slotName);
+						if (slot == null)
 							throw new Error("Slot not found: " + slotName);
-						var slotMap = skinMap[slotName];
+						var slotMap = skinMap.attachments[slotName];
 						for (var entryName in slotMap) {
-							var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName, skeletonData);
+							var attachment = this.readAttachment(slotMap[entryName], skin, slot.index, entryName, skeletonData);
 							if (attachment != null)
-								skin.setAttachment(slotIndex, entryName, attachment);
+								skin.setAttachment(slot.index, entryName, attachment);
 						}
 					}
 					skeletonData.skins.push(skin);
@@ -4878,7 +4991,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex++, valueMap.time, valueMap.name);
+								timeline.setFrame(frameIndex++, this.getValue(valueMap, "time", 0), valueMap.name);
 							}
 							timelines.push(timeline);
 							duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
@@ -4891,7 +5004,7 @@ var spine;
 								var valueMap = timelineMap[i];
 								var color = new spine.Color();
 								color.setFromString(valueMap.color);
-								timeline.setFrame(frameIndex, valueMap.time, color.r, color.g, color.b, color.a);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), color.r, color.g, color.b, color.a);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4908,7 +5021,7 @@ var spine;
 								var dark = new spine.Color();
 								light.setFromString(valueMap.light);
 								dark.setFromString(valueMap.dark);
-								timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4934,7 +5047,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, valueMap.angle);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "angle", 0));
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4943,9 +5056,11 @@ var spine;
 						}
 						else if (timelineName === "translate" || timelineName === "scale" || timelineName === "shear") {
 							var timeline = null;
-							var timelineScale = 1;
-							if (timelineName === "scale")
+							var timelineScale = 1, defaultValue = 0;
+							if (timelineName === "scale") {
 								timeline = new spine.ScaleTimeline(timelineMap.length);
+								defaultValue = 1;
+							}
 							else if (timelineName === "shear")
 								timeline = new spine.ShearTimeline(timelineMap.length);
 							else {
@@ -4956,8 +5071,8 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								var x = this.getValue(valueMap, "x", 0), y = this.getValue(valueMap, "y", 0);
-								timeline.setFrame(frameIndex, valueMap.time, x * timelineScale, y * timelineScale);
+								var x = this.getValue(valueMap, "x", defaultValue), y = this.getValue(valueMap, "y", defaultValue);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), x * timelineScale, y * timelineScale);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4978,7 +5093,7 @@ var spine;
 					var frameIndex = 0;
 					for (var i = 0; i < constraintMap.length; i++) {
 						var valueMap = constraintMap[i];
-						timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false));
+						timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false));
 						this.readCurve(valueMap, timeline, frameIndex);
 						frameIndex++;
 					}
@@ -4995,7 +5110,7 @@ var spine;
 					var frameIndex = 0;
 					for (var i = 0; i < constraintMap.length; i++) {
 						var valueMap = constraintMap[i];
-						timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1));
+						timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1));
 						this.readCurve(valueMap, timeline, frameIndex);
 						frameIndex++;
 					}
@@ -5003,9 +5118,9 @@ var spine;
 					duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TransformConstraintTimeline.ENTRIES]);
 				}
 			}
-			if (map.paths) {
-				for (var constraintName in map.paths) {
-					var constraintMap = map.paths[constraintName];
+			if (map.path) {
+				for (var constraintName in map.path) {
+					var constraintMap = map.path[constraintName];
 					var index = skeletonData.findPathConstraintIndex(constraintName);
 					if (index == -1)
 						throw new Error("Path constraint not found: " + constraintName);
@@ -5029,7 +5144,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, timelineName, 0) * timelineScale);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, timelineName, 0) * timelineScale);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5042,7 +5157,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1));
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1));
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5094,7 +5209,7 @@ var spine;
 											deform[i] += vertices[i];
 									}
 								}
-								timeline.setFrame(frameIndex, valueMap.time, deform);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), deform);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5134,7 +5249,7 @@ var spine;
 							if (drawOrder[i] == -1)
 								drawOrder[i] = unchanged[--unchangedIndex];
 					}
-					timeline.setFrame(frameIndex++, drawOrderMap.time, drawOrder);
+					timeline.setFrame(frameIndex++, this.getValue(drawOrderMap, "time", 0), drawOrder);
 				}
 				timelines.push(timeline);
 				duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
@@ -5147,7 +5262,7 @@ var spine;
 					var eventData = skeletonData.findEvent(eventMap.name);
 					if (eventData == null)
 						throw new Error("Event not found: " + eventMap.name);
-					var event_5 = new spine.Event(spine.Utils.toSinglePrecision(eventMap.time), eventData);
+					var event_5 = new spine.Event(spine.Utils.toSinglePrecision(this.getValue(eventMap, "time", 0)), eventData);
 					event_5.intValue = this.getValue(eventMap, "int", eventData.intValue);
 					event_5.floatValue = this.getValue(eventMap, "float", eventData.floatValue);
 					event_5.stringValue = this.getValue(eventMap, "string", eventData.stringValue);
@@ -5168,11 +5283,11 @@ var spine;
 		SkeletonJson.prototype.readCurve = function (map, timeline, frameIndex) {
 			if (!map.curve)
 				return;
-			if (map.curve === "stepped")
+			if (map.curve == "stepped")
 				timeline.setStepped(frameIndex);
 			else if (Object.prototype.toString.call(map.curve) === '[object Array]') {
 				var curve = map.curve;
-				timeline.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]);
+				timeline.setCurve(frameIndex, curve, this.getValue(map, "c2", 0), this.getValue(map, "c3", 1), this.getValue(map, "c4", 1));
 			}
 		};
 		SkeletonJson.prototype.getValue = function (map, prop, defaultValue) {
@@ -5725,6 +5840,7 @@ var spine;
 			this.scaleMix = 0;
 			this.shearMix = 0;
 			this.temp = new spine.Vector2();
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -5739,6 +5855,9 @@ var spine;
 				this.bones.push(skeleton.findBone(data.bones[i].name));
 			this.target = skeleton.findBone(data.target.name);
 		}
+		TransformConstraint.prototype.isActive = function () {
+			return this.active;
+		};
 		TransformConstraint.prototype.apply = function () {
 			this.update();
 		};
@@ -5948,37 +6067,33 @@ var spine;
 				bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
 			}
 		};
-		TransformConstraint.prototype.getOrder = function () {
-			return this.data.order;
-		};
 		return TransformConstraint;
 	}());
 	spine.TransformConstraint = TransformConstraint;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var TransformConstraintData = (function () {
+	var TransformConstraintData = (function (_super) {
+		__extends(TransformConstraintData, _super);
 		function TransformConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.rotateMix = 0;
-			this.translateMix = 0;
-			this.scaleMix = 0;
-			this.shearMix = 0;
-			this.offsetRotation = 0;
-			this.offsetX = 0;
-			this.offsetY = 0;
-			this.offsetScaleX = 0;
-			this.offsetScaleY = 0;
-			this.offsetShearY = 0;
-			this.relative = false;
-			this.local = false;
-			if (name == null)
-				throw new Error("name cannot be null.");
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			_this.rotateMix = 0;
+			_this.translateMix = 0;
+			_this.scaleMix = 0;
+			_this.shearMix = 0;
+			_this.offsetRotation = 0;
+			_this.offsetX = 0;
+			_this.offsetY = 0;
+			_this.offsetScaleX = 0;
+			_this.offsetScaleY = 0;
+			_this.offsetShearY = 0;
+			_this.relative = false;
+			_this.local = false;
+			return _this;
 		}
 		return TransformConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.TransformConstraintData = TransformConstraintData;
 })(spine || (spine = {}));
 var spine;
@@ -6428,6 +6543,14 @@ var spine;
 		};
 		Utils.webkit602BugfixHelper = function (alpha, blend) {
 		};
+		Utils.contains = function (array, element, identity) {
+			if (identity === void 0) { identity = true; }
+			for (var i = 0; i < array.length; i++) {
+				if (array[i] == element)
+					return true;
+			}
+			return false;
+		};
 		Utils.SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== "undefined";
 		return Utils;
 	}());
@@ -9169,6 +9292,8 @@ var spine;
 					var slots = skeleton.slots;
 					for (var i = 0, n = slots.length; i < n; i++) {
 						var slot = slots[i];
+						if (!slot.bone.active)
+							continue;
 						var attachment = slot.getAttachment();
 						if (!(attachment instanceof spine.MeshAttachment))
 							continue;
@@ -9214,6 +9339,8 @@ var spine;
 					var slots = skeleton.slots;
 					for (var i = 0, n = slots.length; i < n; i++) {
 						var slot = slots[i];
+						if (!slot.bone.active)
+							continue;
 						var attachment = slot.getAttachment();
 						if (!(attachment instanceof spine.PathAttachment))
 							continue;
@@ -9262,6 +9389,8 @@ var spine;
 					shapes.setColor(this.clipColor);
 					for (var i = 0, n = slots.length; i < n; i++) {
 						var slot = slots[i];
+						if (!slot.bone.active)
+							continue;
 						var attachment = slot.getAttachment();
 						if (!(attachment instanceof spine.ClippingAttachment))
 							continue;
@@ -9345,6 +9474,10 @@ var spine;
 				for (var i = 0, n = drawOrder.length; i < n; i++) {
 					var clippedVertexSize = clipper.isClipping() ? 2 : vertexSize;
 					var slot = drawOrder[i];
+					if (!slot.bone.active) {
+						clipper.clipEndWithSlot(slot);
+						continue;
+					}
 					if (slotRangeStart >= 0 && slotRangeStart == slot.data.index) {
 						inRange = true;
 					}

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
spine-ts/build/spine-player.js.map


+ 23 - 18
spine-ts/build/spine-threejs.d.ts

@@ -447,7 +447,9 @@ declare module spine {
 		d: number;
 		worldY: number;
 		sorted: boolean;
+		active: boolean;
 		constructor(data: BoneData, skeleton: Skeleton, parent: Bone);
+		isActive(): boolean;
 		update(): void;
 		updateWorldTransform(): void;
 		updateWorldTransformWith(x: number, y: number, rotation: number, scaleX: number, scaleY: number, shearX: number, shearY: number): void;
@@ -478,6 +480,7 @@ declare module spine {
 		shearX: number;
 		shearY: number;
 		transformMode: TransformMode;
+		skinRequired: boolean;
 		constructor(index: number, name: string, parent: BoneData);
 	}
 	enum TransformMode {
@@ -489,8 +492,11 @@ declare module spine {
 	}
 }
 declare module spine {
-	interface Constraint extends Updatable {
-		getOrder(): number;
+	abstract class ConstraintData {
+		name: string;
+		order: number;
+		skinRequired: boolean;
+		constructor(name: string, order: number, skinRequired: boolean);
 	}
 }
 declare module spine {
@@ -518,7 +524,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class IkConstraint implements Constraint {
+	class IkConstraint implements Updatable {
 		data: IkConstraintData;
 		bones: Array<Bone>;
 		target: Bone;
@@ -526,8 +532,9 @@ declare module spine {
 		compress: boolean;
 		stretch: boolean;
 		mix: number;
+		active: boolean;
 		constructor(data: IkConstraintData, skeleton: Skeleton);
-		getOrder(): number;
+		isActive(): boolean;
 		apply(): void;
 		update(): void;
 		apply1(bone: Bone, targetX: number, targetY: number, compress: boolean, stretch: boolean, uniform: boolean, alpha: number): void;
@@ -535,9 +542,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class IkConstraintData {
-		name: string;
-		order: number;
+	class IkConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: BoneData;
 		bendDirection: number;
@@ -549,7 +554,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class PathConstraint implements Constraint {
+	class PathConstraint implements Updatable {
 		static NONE: number;
 		static BEFORE: number;
 		static AFTER: number;
@@ -567,20 +572,19 @@ declare module spine {
 		curves: number[];
 		lengths: number[];
 		segments: number[];
+		active: boolean;
 		constructor(data: PathConstraintData, skeleton: Skeleton);
+		isActive(): boolean;
 		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;
+	class PathConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: SlotData;
 		positionMode: PositionMode;
@@ -781,7 +785,7 @@ declare module spine {
 		name: string;
 		attachments: Map<Attachment>[];
 		bones: BoneData[];
-		constraints: Constraint[];
+		constraints: ConstraintData[];
 		constructor(name: string);
 		setAttachment(slotIndex: number, name: string, attachment: Attachment): void;
 		addSkin(skin: Skin): void;
@@ -899,7 +903,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class TransformConstraint implements Constraint {
+	class TransformConstraint implements Updatable {
 		data: TransformConstraintData;
 		bones: Array<Bone>;
 		target: Bone;
@@ -908,20 +912,19 @@ declare module spine {
 		scaleMix: number;
 		shearMix: number;
 		temp: Vector2;
+		active: boolean;
 		constructor(data: TransformConstraintData, skeleton: Skeleton);
+		isActive(): boolean;
 		apply(): void;
 		update(): void;
 		applyAbsoluteWorld(): void;
 		applyRelativeWorld(): void;
 		applyAbsoluteLocal(): void;
 		applyRelativeLocal(): void;
-		getOrder(): number;
 	}
 }
 declare module spine {
-	class TransformConstraintData {
-		name: string;
-		order: number;
+	class TransformConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: BoneData;
 		rotateMix: number;
@@ -958,6 +961,7 @@ declare module spine {
 declare module spine {
 	interface Updatable {
 		update(): void;
+		isActive(): boolean;
 	}
 }
 declare module spine {
@@ -1034,6 +1038,7 @@ declare module spine {
 		static toFloatArray(array: Array<number>): number[] | Float32Array;
 		static toSinglePrecision(value: number): number;
 		static webkit602BugfixHelper(alpha: number, blend: MixBlend): void;
+		static contains<T>(array: Array<T>, element: T, identity?: boolean): boolean;
 	}
 	class DebugUtils {
 		static logBones(skeleton: Skeleton): void;

+ 198 - 73
spine-ts/build/spine-threejs.js

@@ -188,6 +188,8 @@ var spine;
 		RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -257,6 +259,8 @@ var spine;
 		TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -318,6 +322,8 @@ var spine;
 		ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -416,6 +422,8 @@ var spine;
 		ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -480,6 +488,8 @@ var spine;
 		};
 		ColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var frames = this.frames;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -558,6 +568,8 @@ var spine;
 		};
 		TwoColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var frames = this.frames;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -652,6 +664,8 @@ var spine;
 		};
 		AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			if (direction == MixDirection.mixOut && blend == MixBlend.setup) {
 				var attachmentName_1 = slot.data.attachmentName;
 				slot.setAttachment(attachmentName_1 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_1));
@@ -697,6 +711,8 @@ var spine;
 		};
 		DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var slotAttachment = slot.getAttachment();
 			if (!(slotAttachment instanceof spine.VertexAttachment) || !(slotAttachment.deformAttachment == this.attachment))
 				return;
@@ -976,6 +992,8 @@ var spine;
 		IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.ikConstraints[this.ikConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1076,6 +1094,8 @@ var spine;
 		TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.transformConstraints[this.transformConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				var data = constraint.data;
 				switch (blend) {
@@ -1159,6 +1179,8 @@ var spine;
 		PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1202,6 +1224,8 @@ var spine;
 		PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1249,6 +1273,8 @@ var spine;
 		PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1535,6 +1561,8 @@ var spine;
 			var rotateTimeline = timeline;
 			var frames = rotateTimeline.frames;
 			var bone = skeleton.bones[rotateTimeline.boneIndex];
+			if (!bone.active)
+				return;
 			var r1 = 0, r2 = 0;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -2425,6 +2453,7 @@ var spine;
 			this.d = 0;
 			this.worldY = 0;
 			this.sorted = false;
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2434,6 +2463,9 @@ var spine;
 			this.parent = parent;
 			this.setToSetupPose();
 		}
+		Bone.prototype.isActive = function () {
+			return this.active;
+		};
 		Bone.prototype.update = function () {
 			this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY);
 		};
@@ -2658,6 +2690,7 @@ var spine;
 			this.shearX = 0;
 			this.shearY = 0;
 			this.transformMode = TransformMode.Normal;
+			this.skinRequired = false;
 			if (index < 0)
 				throw new Error("index must be >= 0.");
 			if (name == null)
@@ -2679,6 +2712,18 @@ var spine;
 	})(TransformMode = spine.TransformMode || (spine.TransformMode = {}));
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var ConstraintData = (function () {
+		function ConstraintData(name, order, skinRequired) {
+			this.name = name;
+			this.order = order;
+			this.skinRequired = skinRequired;
+		}
+		return ConstraintData;
+	}());
+	spine.ConstraintData = ConstraintData;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var Event = (function () {
 		function Event(time, data) {
@@ -2709,6 +2754,7 @@ var spine;
 			this.compress = false;
 			this.stretch = false;
 			this.mix = 1;
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2723,8 +2769,8 @@ var spine;
 				this.bones.push(skeleton.findBone(data.bones[i].name));
 			this.target = skeleton.findBone(data.target.name);
 		}
-		IkConstraint.prototype.getOrder = function () {
-			return this.data.order;
+		IkConstraint.prototype.isActive = function () {
+			return this.active;
 		};
 		IkConstraint.prototype.apply = function () {
 			this.update();
@@ -2908,19 +2954,20 @@ var spine;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var IkConstraintData = (function () {
+	var IkConstraintData = (function (_super) {
+		__extends(IkConstraintData, _super);
 		function IkConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.bendDirection = 1;
-			this.compress = false;
-			this.stretch = false;
-			this.uniform = false;
-			this.mix = 1;
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			_this.bendDirection = 1;
+			_this.compress = false;
+			_this.stretch = false;
+			_this.uniform = false;
+			_this.mix = 1;
+			return _this;
 		}
 		return IkConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.IkConstraintData = IkConstraintData;
 })(spine || (spine = {}));
 var spine;
@@ -2937,6 +2984,7 @@ var spine;
 			this.curves = new Array();
 			this.lengths = new Array();
 			this.segments = new Array();
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2951,6 +2999,9 @@ var spine;
 			this.rotateMix = data.rotateMix;
 			this.translateMix = data.translateMix;
 		}
+		PathConstraint.prototype.isActive = function () {
+			return this.active;
+		};
 		PathConstraint.prototype.apply = function () {
 			this.update();
 		};
@@ -3306,9 +3357,6 @@ var spine;
 					out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
 			}
 		};
-		PathConstraint.prototype.getOrder = function () {
-			return this.data.order;
-		};
 		PathConstraint.NONE = -1;
 		PathConstraint.BEFORE = -2;
 		PathConstraint.AFTER = -3;
@@ -3319,14 +3367,15 @@ var spine;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var PathConstraintData = (function () {
+	var PathConstraintData = (function (_super) {
+		__extends(PathConstraintData, _super);
 		function PathConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			return _this;
 		}
 		return PathConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.PathConstraintData = PathConstraintData;
 	var PositionMode;
 	(function (PositionMode) {
@@ -3543,8 +3592,22 @@ var spine;
 			updateCache.length = 0;
 			this.updateCacheReset.length = 0;
 			var bones = this.bones;
-			for (var i = 0, n = bones.length; i < n; i++)
-				bones[i].sorted = false;
+			for (var i = 0, n = bones.length; i < n; i++) {
+				var bone = bones[i];
+				bone.sorted = bone.data.skinRequired;
+				bone.active = !bone.sorted;
+			}
+			if (this.skin != null) {
+				var skinBones = this.skin.bones;
+				for (var i = 0, n = this.skin.bones.length; i < n; i++) {
+					var bone = this.bones[skinBones[i].index];
+					do {
+						bone.sorted = false;
+						bone.active = true;
+						bone = bone.parent;
+					} while (bone != null);
+				}
+			}
 			var ikConstraints = this.ikConstraints;
 			var transformConstraints = this.transformConstraints;
 			var pathConstraints = this.pathConstraints;
@@ -3577,6 +3640,9 @@ var spine;
 				this.sortBone(bones[i]);
 		};
 		Skeleton.prototype.sortIkConstraint = function (constraint) {
+			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			var target = constraint.target;
 			this.sortBone(target);
 			var constrained = constraint.bones;
@@ -3592,6 +3658,9 @@ var spine;
 			constrained[constrained.length - 1].sorted = true;
 		};
 		Skeleton.prototype.sortPathConstraint = function (constraint) {
+			constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			var slot = constraint.target;
 			var slotIndex = slot.data.index;
 			var slotBone = slot.bone;
@@ -3615,6 +3684,9 @@ var spine;
 				constrained[i].sorted = true;
 		};
 		Skeleton.prototype.sortTransformConstraint = function (constraint) {
+			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			this.sortBone(constraint.target);
 			var constrained = constraint.bones;
 			var boneCount = constrained.length;
@@ -3675,6 +3747,8 @@ var spine;
 		Skeleton.prototype.sortReset = function (bones) {
 			for (var i = 0, n = bones.length; i < n; i++) {
 				var bone = bones[i];
+				if (!bone.update)
+					continue;
 				if (bone.sorted)
 					this.sortReset(bone.children);
 				bone.sorted = false;
@@ -3790,6 +3864,8 @@ var spine;
 			this.setSkin(skin);
 		};
 		Skeleton.prototype.setSkin = function (newSkin) {
+			if (newSkin == this.skin)
+				return;
 			if (newSkin != null) {
 				if (this.skin != null)
 					newSkin.attachAll(this, this.skin);
@@ -3807,6 +3883,7 @@ var spine;
 				}
 			}
 			this.skin = newSkin;
+			this.updateCache();
 		};
 		Skeleton.prototype.getAttachmentByName = function (slotName, attachmentName) {
 			return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName);
@@ -4555,6 +4632,7 @@ var spine;
 					data.shearX = this.getValue(boneMap, "shearX", 0);
 					data.shearY = this.getValue(boneMap, "shearY", 0);
 					data.transformMode = SkeletonJson.transformModeFromString(this.getValue(boneMap, "transform", "normal"));
+					data.skinRequired = this.getValue(boneMap, "skin", false);
 					skeletonData.bones.push(data);
 				}
 			}
@@ -4585,6 +4663,7 @@ var spine;
 					var constraintMap = root.ik[i];
 					var data = new spine.IkConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4609,6 +4688,7 @@ var spine;
 					var constraintMap = root.transform[i];
 					var data = new spine.TransformConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4640,6 +4720,7 @@ var spine;
 					var constraintMap = root.path[i];
 					var data = new spine.PathConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4667,18 +4748,50 @@ var spine;
 				}
 			}
 			if (root.skins) {
-				for (var skinName in root.skins) {
-					var skinMap = root.skins[skinName];
-					var skin = new spine.Skin(skinName);
-					for (var slotName in skinMap) {
-						var slotIndex = skeletonData.findSlotIndex(slotName);
-						if (slotIndex == -1)
+				for (var i = 0; i < root.skins.length; i++) {
+					var skinMap = root.skins[i];
+					var skin = new spine.Skin(skinMap.name);
+					if (skinMap.bones) {
+						for (var ii = 0; ii < skinMap.bones.length; ii++) {
+							var bone = skeletonData.findBone(skinMap.bones[ii]);
+							if (bone == null)
+								throw new Error("Skin bone not found: " + skinMap.bones[i]);
+							skin.bones.push(bone);
+						}
+					}
+					if (skinMap.ik) {
+						for (var ii = 0; ii < skinMap.ik.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.ik[ii]);
+							if (constraint == null)
+								throw new Error("Skin IK constraint not found: " + skinMap.ik[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					if (skinMap.transform) {
+						for (var ii = 0; ii < skinMap.transform.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.transform[ii]);
+							if (constraint == null)
+								throw new Error("Skin transform constraint not found: " + skinMap.transform[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					if (skinMap.path) {
+						for (var ii = 0; ii < skinMap.path.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.path[ii]);
+							if (constraint == null)
+								throw new Error("Skin path constraint not found: " + skinMap.path[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					for (var slotName in skinMap.attachments) {
+						var slot = skeletonData.findSlot(slotName);
+						if (slot == null)
 							throw new Error("Slot not found: " + slotName);
-						var slotMap = skinMap[slotName];
+						var slotMap = skinMap.attachments[slotName];
 						for (var entryName in slotMap) {
-							var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName, skeletonData);
+							var attachment = this.readAttachment(slotMap[entryName], skin, slot.index, entryName, skeletonData);
 							if (attachment != null)
-								skin.setAttachment(slotIndex, entryName, attachment);
+								skin.setAttachment(slot.index, entryName, attachment);
 						}
 					}
 					skeletonData.skins.push(skin);
@@ -4878,7 +4991,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex++, valueMap.time, valueMap.name);
+								timeline.setFrame(frameIndex++, this.getValue(valueMap, "time", 0), valueMap.name);
 							}
 							timelines.push(timeline);
 							duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
@@ -4891,7 +5004,7 @@ var spine;
 								var valueMap = timelineMap[i];
 								var color = new spine.Color();
 								color.setFromString(valueMap.color);
-								timeline.setFrame(frameIndex, valueMap.time, color.r, color.g, color.b, color.a);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), color.r, color.g, color.b, color.a);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4908,7 +5021,7 @@ var spine;
 								var dark = new spine.Color();
 								light.setFromString(valueMap.light);
 								dark.setFromString(valueMap.dark);
-								timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4934,7 +5047,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, valueMap.angle);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "angle", 0));
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4943,9 +5056,11 @@ var spine;
 						}
 						else if (timelineName === "translate" || timelineName === "scale" || timelineName === "shear") {
 							var timeline = null;
-							var timelineScale = 1;
-							if (timelineName === "scale")
+							var timelineScale = 1, defaultValue = 0;
+							if (timelineName === "scale") {
 								timeline = new spine.ScaleTimeline(timelineMap.length);
+								defaultValue = 1;
+							}
 							else if (timelineName === "shear")
 								timeline = new spine.ShearTimeline(timelineMap.length);
 							else {
@@ -4956,8 +5071,8 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								var x = this.getValue(valueMap, "x", 0), y = this.getValue(valueMap, "y", 0);
-								timeline.setFrame(frameIndex, valueMap.time, x * timelineScale, y * timelineScale);
+								var x = this.getValue(valueMap, "x", defaultValue), y = this.getValue(valueMap, "y", defaultValue);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), x * timelineScale, y * timelineScale);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4978,7 +5093,7 @@ var spine;
 					var frameIndex = 0;
 					for (var i = 0; i < constraintMap.length; i++) {
 						var valueMap = constraintMap[i];
-						timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false));
+						timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false));
 						this.readCurve(valueMap, timeline, frameIndex);
 						frameIndex++;
 					}
@@ -4995,7 +5110,7 @@ var spine;
 					var frameIndex = 0;
 					for (var i = 0; i < constraintMap.length; i++) {
 						var valueMap = constraintMap[i];
-						timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1));
+						timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1));
 						this.readCurve(valueMap, timeline, frameIndex);
 						frameIndex++;
 					}
@@ -5003,9 +5118,9 @@ var spine;
 					duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TransformConstraintTimeline.ENTRIES]);
 				}
 			}
-			if (map.paths) {
-				for (var constraintName in map.paths) {
-					var constraintMap = map.paths[constraintName];
+			if (map.path) {
+				for (var constraintName in map.path) {
+					var constraintMap = map.path[constraintName];
 					var index = skeletonData.findPathConstraintIndex(constraintName);
 					if (index == -1)
 						throw new Error("Path constraint not found: " + constraintName);
@@ -5029,7 +5144,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, timelineName, 0) * timelineScale);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, timelineName, 0) * timelineScale);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5042,7 +5157,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1));
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1));
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5094,7 +5209,7 @@ var spine;
 											deform[i] += vertices[i];
 									}
 								}
-								timeline.setFrame(frameIndex, valueMap.time, deform);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), deform);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5134,7 +5249,7 @@ var spine;
 							if (drawOrder[i] == -1)
 								drawOrder[i] = unchanged[--unchangedIndex];
 					}
-					timeline.setFrame(frameIndex++, drawOrderMap.time, drawOrder);
+					timeline.setFrame(frameIndex++, this.getValue(drawOrderMap, "time", 0), drawOrder);
 				}
 				timelines.push(timeline);
 				duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
@@ -5147,7 +5262,7 @@ var spine;
 					var eventData = skeletonData.findEvent(eventMap.name);
 					if (eventData == null)
 						throw new Error("Event not found: " + eventMap.name);
-					var event_5 = new spine.Event(spine.Utils.toSinglePrecision(eventMap.time), eventData);
+					var event_5 = new spine.Event(spine.Utils.toSinglePrecision(this.getValue(eventMap, "time", 0)), eventData);
 					event_5.intValue = this.getValue(eventMap, "int", eventData.intValue);
 					event_5.floatValue = this.getValue(eventMap, "float", eventData.floatValue);
 					event_5.stringValue = this.getValue(eventMap, "string", eventData.stringValue);
@@ -5168,11 +5283,11 @@ var spine;
 		SkeletonJson.prototype.readCurve = function (map, timeline, frameIndex) {
 			if (!map.curve)
 				return;
-			if (map.curve === "stepped")
+			if (map.curve == "stepped")
 				timeline.setStepped(frameIndex);
 			else if (Object.prototype.toString.call(map.curve) === '[object Array]') {
 				var curve = map.curve;
-				timeline.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]);
+				timeline.setCurve(frameIndex, curve, this.getValue(map, "c2", 0), this.getValue(map, "c3", 1), this.getValue(map, "c4", 1));
 			}
 		};
 		SkeletonJson.prototype.getValue = function (map, prop, defaultValue) {
@@ -5725,6 +5840,7 @@ var spine;
 			this.scaleMix = 0;
 			this.shearMix = 0;
 			this.temp = new spine.Vector2();
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -5739,6 +5855,9 @@ var spine;
 				this.bones.push(skeleton.findBone(data.bones[i].name));
 			this.target = skeleton.findBone(data.target.name);
 		}
+		TransformConstraint.prototype.isActive = function () {
+			return this.active;
+		};
 		TransformConstraint.prototype.apply = function () {
 			this.update();
 		};
@@ -5948,37 +6067,33 @@ var spine;
 				bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
 			}
 		};
-		TransformConstraint.prototype.getOrder = function () {
-			return this.data.order;
-		};
 		return TransformConstraint;
 	}());
 	spine.TransformConstraint = TransformConstraint;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var TransformConstraintData = (function () {
+	var TransformConstraintData = (function (_super) {
+		__extends(TransformConstraintData, _super);
 		function TransformConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.rotateMix = 0;
-			this.translateMix = 0;
-			this.scaleMix = 0;
-			this.shearMix = 0;
-			this.offsetRotation = 0;
-			this.offsetX = 0;
-			this.offsetY = 0;
-			this.offsetScaleX = 0;
-			this.offsetScaleY = 0;
-			this.offsetShearY = 0;
-			this.relative = false;
-			this.local = false;
-			if (name == null)
-				throw new Error("name cannot be null.");
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			_this.rotateMix = 0;
+			_this.translateMix = 0;
+			_this.scaleMix = 0;
+			_this.shearMix = 0;
+			_this.offsetRotation = 0;
+			_this.offsetX = 0;
+			_this.offsetY = 0;
+			_this.offsetScaleX = 0;
+			_this.offsetScaleY = 0;
+			_this.offsetShearY = 0;
+			_this.relative = false;
+			_this.local = false;
+			return _this;
 		}
 		return TransformConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.TransformConstraintData = TransformConstraintData;
 })(spine || (spine = {}));
 var spine;
@@ -6428,6 +6543,14 @@ var spine;
 		};
 		Utils.webkit602BugfixHelper = function (alpha, blend) {
 		};
+		Utils.contains = function (array, element, identity) {
+			if (identity === void 0) { identity = true; }
+			for (var i = 0; i < array.length; i++) {
+				if (array[i] == element)
+					return true;
+			}
+			return false;
+		};
 		Utils.SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== "undefined";
 		return Utils;
 	}());
@@ -7315,6 +7438,8 @@ var spine;
 				for (var i = 0, n = drawOrder.length; i < n; i++) {
 					var vertexSize = clipper.isClipping() ? 2 : SkeletonMesh.VERTEX_SIZE;
 					var slot = drawOrder[i];
+					if (!slot.bone.active)
+						continue;
 					var attachment = slot.getAttachment();
 					var attachmentColor = null;
 					var texture = null;

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
spine-ts/build/spine-threejs.js.map


+ 23 - 18
spine-ts/build/spine-webgl.d.ts

@@ -447,7 +447,9 @@ declare module spine {
 		d: number;
 		worldY: number;
 		sorted: boolean;
+		active: boolean;
 		constructor(data: BoneData, skeleton: Skeleton, parent: Bone);
+		isActive(): boolean;
 		update(): void;
 		updateWorldTransform(): void;
 		updateWorldTransformWith(x: number, y: number, rotation: number, scaleX: number, scaleY: number, shearX: number, shearY: number): void;
@@ -478,6 +480,7 @@ declare module spine {
 		shearX: number;
 		shearY: number;
 		transformMode: TransformMode;
+		skinRequired: boolean;
 		constructor(index: number, name: string, parent: BoneData);
 	}
 	enum TransformMode {
@@ -489,8 +492,11 @@ declare module spine {
 	}
 }
 declare module spine {
-	interface Constraint extends Updatable {
-		getOrder(): number;
+	abstract class ConstraintData {
+		name: string;
+		order: number;
+		skinRequired: boolean;
+		constructor(name: string, order: number, skinRequired: boolean);
 	}
 }
 declare module spine {
@@ -518,7 +524,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class IkConstraint implements Constraint {
+	class IkConstraint implements Updatable {
 		data: IkConstraintData;
 		bones: Array<Bone>;
 		target: Bone;
@@ -526,8 +532,9 @@ declare module spine {
 		compress: boolean;
 		stretch: boolean;
 		mix: number;
+		active: boolean;
 		constructor(data: IkConstraintData, skeleton: Skeleton);
-		getOrder(): number;
+		isActive(): boolean;
 		apply(): void;
 		update(): void;
 		apply1(bone: Bone, targetX: number, targetY: number, compress: boolean, stretch: boolean, uniform: boolean, alpha: number): void;
@@ -535,9 +542,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class IkConstraintData {
-		name: string;
-		order: number;
+	class IkConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: BoneData;
 		bendDirection: number;
@@ -549,7 +554,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class PathConstraint implements Constraint {
+	class PathConstraint implements Updatable {
 		static NONE: number;
 		static BEFORE: number;
 		static AFTER: number;
@@ -567,20 +572,19 @@ declare module spine {
 		curves: number[];
 		lengths: number[];
 		segments: number[];
+		active: boolean;
 		constructor(data: PathConstraintData, skeleton: Skeleton);
+		isActive(): boolean;
 		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;
+	class PathConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: SlotData;
 		positionMode: PositionMode;
@@ -781,7 +785,7 @@ declare module spine {
 		name: string;
 		attachments: Map<Attachment>[];
 		bones: BoneData[];
-		constraints: Constraint[];
+		constraints: ConstraintData[];
 		constructor(name: string);
 		setAttachment(slotIndex: number, name: string, attachment: Attachment): void;
 		addSkin(skin: Skin): void;
@@ -899,7 +903,7 @@ declare module spine {
 	}
 }
 declare module spine {
-	class TransformConstraint implements Constraint {
+	class TransformConstraint implements Updatable {
 		data: TransformConstraintData;
 		bones: Array<Bone>;
 		target: Bone;
@@ -908,20 +912,19 @@ declare module spine {
 		scaleMix: number;
 		shearMix: number;
 		temp: Vector2;
+		active: boolean;
 		constructor(data: TransformConstraintData, skeleton: Skeleton);
+		isActive(): boolean;
 		apply(): void;
 		update(): void;
 		applyAbsoluteWorld(): void;
 		applyRelativeWorld(): void;
 		applyAbsoluteLocal(): void;
 		applyRelativeLocal(): void;
-		getOrder(): number;
 	}
 }
 declare module spine {
-	class TransformConstraintData {
-		name: string;
-		order: number;
+	class TransformConstraintData extends ConstraintData {
 		bones: BoneData[];
 		target: BoneData;
 		rotateMix: number;
@@ -958,6 +961,7 @@ declare module spine {
 declare module spine {
 	interface Updatable {
 		update(): void;
+		isActive(): boolean;
 	}
 }
 declare module spine {
@@ -1034,6 +1038,7 @@ declare module spine {
 		static toFloatArray(array: Array<number>): number[] | Float32Array;
 		static toSinglePrecision(value: number): number;
 		static webkit602BugfixHelper(alpha: number, blend: MixBlend): void;
+		static contains<T>(array: Array<T>, element: T, identity?: boolean): boolean;
 	}
 	class DebugUtils {
 		static logBones(skeleton: Skeleton): void;

+ 206 - 73
spine-ts/build/spine-webgl.js

@@ -188,6 +188,8 @@ var spine;
 		RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -257,6 +259,8 @@ var spine;
 		TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -318,6 +322,8 @@ var spine;
 		ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -416,6 +422,8 @@ var spine;
 		ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var frames = this.frames;
 			var bone = skeleton.bones[this.boneIndex];
+			if (!bone.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -480,6 +488,8 @@ var spine;
 		};
 		ColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var frames = this.frames;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -558,6 +568,8 @@ var spine;
 		};
 		TwoColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var frames = this.frames;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -652,6 +664,8 @@ var spine;
 		};
 		AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			if (direction == MixDirection.mixOut && blend == MixBlend.setup) {
 				var attachmentName_1 = slot.data.attachmentName;
 				slot.setAttachment(attachmentName_1 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_1));
@@ -697,6 +711,8 @@ var spine;
 		};
 		DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active)
+				return;
 			var slotAttachment = slot.getAttachment();
 			if (!(slotAttachment instanceof spine.VertexAttachment) || !(slotAttachment.deformAttachment == this.attachment))
 				return;
@@ -976,6 +992,8 @@ var spine;
 		IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.ikConstraints[this.ikConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1076,6 +1094,8 @@ var spine;
 		TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.transformConstraints[this.transformConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				var data = constraint.data;
 				switch (blend) {
@@ -1159,6 +1179,8 @@ var spine;
 		PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1202,6 +1224,8 @@ var spine;
 		PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1249,6 +1273,8 @@ var spine;
 		PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
 			var frames = this.frames;
 			var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active)
+				return;
 			if (time < frames[0]) {
 				switch (blend) {
 					case MixBlend.setup:
@@ -1535,6 +1561,8 @@ var spine;
 			var rotateTimeline = timeline;
 			var frames = rotateTimeline.frames;
 			var bone = skeleton.bones[rotateTimeline.boneIndex];
+			if (!bone.active)
+				return;
 			var r1 = 0, r2 = 0;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -2425,6 +2453,7 @@ var spine;
 			this.d = 0;
 			this.worldY = 0;
 			this.sorted = false;
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2434,6 +2463,9 @@ var spine;
 			this.parent = parent;
 			this.setToSetupPose();
 		}
+		Bone.prototype.isActive = function () {
+			return this.active;
+		};
 		Bone.prototype.update = function () {
 			this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY);
 		};
@@ -2658,6 +2690,7 @@ var spine;
 			this.shearX = 0;
 			this.shearY = 0;
 			this.transformMode = TransformMode.Normal;
+			this.skinRequired = false;
 			if (index < 0)
 				throw new Error("index must be >= 0.");
 			if (name == null)
@@ -2679,6 +2712,18 @@ var spine;
 	})(TransformMode = spine.TransformMode || (spine.TransformMode = {}));
 })(spine || (spine = {}));
 var spine;
+(function (spine) {
+	var ConstraintData = (function () {
+		function ConstraintData(name, order, skinRequired) {
+			this.name = name;
+			this.order = order;
+			this.skinRequired = skinRequired;
+		}
+		return ConstraintData;
+	}());
+	spine.ConstraintData = ConstraintData;
+})(spine || (spine = {}));
+var spine;
 (function (spine) {
 	var Event = (function () {
 		function Event(time, data) {
@@ -2709,6 +2754,7 @@ var spine;
 			this.compress = false;
 			this.stretch = false;
 			this.mix = 1;
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2723,8 +2769,8 @@ var spine;
 				this.bones.push(skeleton.findBone(data.bones[i].name));
 			this.target = skeleton.findBone(data.target.name);
 		}
-		IkConstraint.prototype.getOrder = function () {
-			return this.data.order;
+		IkConstraint.prototype.isActive = function () {
+			return this.active;
 		};
 		IkConstraint.prototype.apply = function () {
 			this.update();
@@ -2908,19 +2954,20 @@ var spine;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var IkConstraintData = (function () {
+	var IkConstraintData = (function (_super) {
+		__extends(IkConstraintData, _super);
 		function IkConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.bendDirection = 1;
-			this.compress = false;
-			this.stretch = false;
-			this.uniform = false;
-			this.mix = 1;
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			_this.bendDirection = 1;
+			_this.compress = false;
+			_this.stretch = false;
+			_this.uniform = false;
+			_this.mix = 1;
+			return _this;
 		}
 		return IkConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.IkConstraintData = IkConstraintData;
 })(spine || (spine = {}));
 var spine;
@@ -2937,6 +2984,7 @@ var spine;
 			this.curves = new Array();
 			this.lengths = new Array();
 			this.segments = new Array();
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -2951,6 +2999,9 @@ var spine;
 			this.rotateMix = data.rotateMix;
 			this.translateMix = data.translateMix;
 		}
+		PathConstraint.prototype.isActive = function () {
+			return this.active;
+		};
 		PathConstraint.prototype.apply = function () {
 			this.update();
 		};
@@ -3306,9 +3357,6 @@ var spine;
 					out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
 			}
 		};
-		PathConstraint.prototype.getOrder = function () {
-			return this.data.order;
-		};
 		PathConstraint.NONE = -1;
 		PathConstraint.BEFORE = -2;
 		PathConstraint.AFTER = -3;
@@ -3319,14 +3367,15 @@ var spine;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var PathConstraintData = (function () {
+	var PathConstraintData = (function (_super) {
+		__extends(PathConstraintData, _super);
 		function PathConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			return _this;
 		}
 		return PathConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.PathConstraintData = PathConstraintData;
 	var PositionMode;
 	(function (PositionMode) {
@@ -3543,8 +3592,22 @@ var spine;
 			updateCache.length = 0;
 			this.updateCacheReset.length = 0;
 			var bones = this.bones;
-			for (var i = 0, n = bones.length; i < n; i++)
-				bones[i].sorted = false;
+			for (var i = 0, n = bones.length; i < n; i++) {
+				var bone = bones[i];
+				bone.sorted = bone.data.skinRequired;
+				bone.active = !bone.sorted;
+			}
+			if (this.skin != null) {
+				var skinBones = this.skin.bones;
+				for (var i = 0, n = this.skin.bones.length; i < n; i++) {
+					var bone = this.bones[skinBones[i].index];
+					do {
+						bone.sorted = false;
+						bone.active = true;
+						bone = bone.parent;
+					} while (bone != null);
+				}
+			}
 			var ikConstraints = this.ikConstraints;
 			var transformConstraints = this.transformConstraints;
 			var pathConstraints = this.pathConstraints;
@@ -3577,6 +3640,9 @@ var spine;
 				this.sortBone(bones[i]);
 		};
 		Skeleton.prototype.sortIkConstraint = function (constraint) {
+			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			var target = constraint.target;
 			this.sortBone(target);
 			var constrained = constraint.bones;
@@ -3592,6 +3658,9 @@ var spine;
 			constrained[constrained.length - 1].sorted = true;
 		};
 		Skeleton.prototype.sortPathConstraint = function (constraint) {
+			constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			var slot = constraint.target;
 			var slotIndex = slot.data.index;
 			var slotBone = slot.bone;
@@ -3615,6 +3684,9 @@ var spine;
 				constrained[i].sorted = true;
 		};
 		Skeleton.prototype.sortTransformConstraint = function (constraint) {
+			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active)
+				return;
 			this.sortBone(constraint.target);
 			var constrained = constraint.bones;
 			var boneCount = constrained.length;
@@ -3675,6 +3747,8 @@ var spine;
 		Skeleton.prototype.sortReset = function (bones) {
 			for (var i = 0, n = bones.length; i < n; i++) {
 				var bone = bones[i];
+				if (!bone.update)
+					continue;
 				if (bone.sorted)
 					this.sortReset(bone.children);
 				bone.sorted = false;
@@ -3790,6 +3864,8 @@ var spine;
 			this.setSkin(skin);
 		};
 		Skeleton.prototype.setSkin = function (newSkin) {
+			if (newSkin == this.skin)
+				return;
 			if (newSkin != null) {
 				if (this.skin != null)
 					newSkin.attachAll(this, this.skin);
@@ -3807,6 +3883,7 @@ var spine;
 				}
 			}
 			this.skin = newSkin;
+			this.updateCache();
 		};
 		Skeleton.prototype.getAttachmentByName = function (slotName, attachmentName) {
 			return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName);
@@ -4555,6 +4632,7 @@ var spine;
 					data.shearX = this.getValue(boneMap, "shearX", 0);
 					data.shearY = this.getValue(boneMap, "shearY", 0);
 					data.transformMode = SkeletonJson.transformModeFromString(this.getValue(boneMap, "transform", "normal"));
+					data.skinRequired = this.getValue(boneMap, "skin", false);
 					skeletonData.bones.push(data);
 				}
 			}
@@ -4585,6 +4663,7 @@ var spine;
 					var constraintMap = root.ik[i];
 					var data = new spine.IkConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4609,6 +4688,7 @@ var spine;
 					var constraintMap = root.transform[i];
 					var data = new spine.TransformConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4640,6 +4720,7 @@ var spine;
 					var constraintMap = root.path[i];
 					var data = new spine.PathConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 					for (var j = 0; j < constraintMap.bones.length; j++) {
 						var boneName = constraintMap.bones[j];
 						var bone = skeletonData.findBone(boneName);
@@ -4667,18 +4748,50 @@ var spine;
 				}
 			}
 			if (root.skins) {
-				for (var skinName in root.skins) {
-					var skinMap = root.skins[skinName];
-					var skin = new spine.Skin(skinName);
-					for (var slotName in skinMap) {
-						var slotIndex = skeletonData.findSlotIndex(slotName);
-						if (slotIndex == -1)
+				for (var i = 0; i < root.skins.length; i++) {
+					var skinMap = root.skins[i];
+					var skin = new spine.Skin(skinMap.name);
+					if (skinMap.bones) {
+						for (var ii = 0; ii < skinMap.bones.length; ii++) {
+							var bone = skeletonData.findBone(skinMap.bones[ii]);
+							if (bone == null)
+								throw new Error("Skin bone not found: " + skinMap.bones[i]);
+							skin.bones.push(bone);
+						}
+					}
+					if (skinMap.ik) {
+						for (var ii = 0; ii < skinMap.ik.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.ik[ii]);
+							if (constraint == null)
+								throw new Error("Skin IK constraint not found: " + skinMap.ik[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					if (skinMap.transform) {
+						for (var ii = 0; ii < skinMap.transform.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.transform[ii]);
+							if (constraint == null)
+								throw new Error("Skin transform constraint not found: " + skinMap.transform[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					if (skinMap.path) {
+						for (var ii = 0; ii < skinMap.path.length; ii++) {
+							var constraint = skeletonData.findIkConstraint(skinMap.path[ii]);
+							if (constraint == null)
+								throw new Error("Skin path constraint not found: " + skinMap.path[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+					for (var slotName in skinMap.attachments) {
+						var slot = skeletonData.findSlot(slotName);
+						if (slot == null)
 							throw new Error("Slot not found: " + slotName);
-						var slotMap = skinMap[slotName];
+						var slotMap = skinMap.attachments[slotName];
 						for (var entryName in slotMap) {
-							var attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName, skeletonData);
+							var attachment = this.readAttachment(slotMap[entryName], skin, slot.index, entryName, skeletonData);
 							if (attachment != null)
-								skin.setAttachment(slotIndex, entryName, attachment);
+								skin.setAttachment(slot.index, entryName, attachment);
 						}
 					}
 					skeletonData.skins.push(skin);
@@ -4878,7 +4991,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex++, valueMap.time, valueMap.name);
+								timeline.setFrame(frameIndex++, this.getValue(valueMap, "time", 0), valueMap.name);
 							}
 							timelines.push(timeline);
 							duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
@@ -4891,7 +5004,7 @@ var spine;
 								var valueMap = timelineMap[i];
 								var color = new spine.Color();
 								color.setFromString(valueMap.color);
-								timeline.setFrame(frameIndex, valueMap.time, color.r, color.g, color.b, color.a);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), color.r, color.g, color.b, color.a);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4908,7 +5021,7 @@ var spine;
 								var dark = new spine.Color();
 								light.setFromString(valueMap.light);
 								dark.setFromString(valueMap.dark);
-								timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4934,7 +5047,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, valueMap.angle);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "angle", 0));
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4943,9 +5056,11 @@ var spine;
 						}
 						else if (timelineName === "translate" || timelineName === "scale" || timelineName === "shear") {
 							var timeline = null;
-							var timelineScale = 1;
-							if (timelineName === "scale")
+							var timelineScale = 1, defaultValue = 0;
+							if (timelineName === "scale") {
 								timeline = new spine.ScaleTimeline(timelineMap.length);
+								defaultValue = 1;
+							}
 							else if (timelineName === "shear")
 								timeline = new spine.ShearTimeline(timelineMap.length);
 							else {
@@ -4956,8 +5071,8 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								var x = this.getValue(valueMap, "x", 0), y = this.getValue(valueMap, "y", 0);
-								timeline.setFrame(frameIndex, valueMap.time, x * timelineScale, y * timelineScale);
+								var x = this.getValue(valueMap, "x", defaultValue), y = this.getValue(valueMap, "y", defaultValue);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), x * timelineScale, y * timelineScale);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -4978,7 +5093,7 @@ var spine;
 					var frameIndex = 0;
 					for (var i = 0; i < constraintMap.length; i++) {
 						var valueMap = constraintMap[i];
-						timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false));
+						timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false));
 						this.readCurve(valueMap, timeline, frameIndex);
 						frameIndex++;
 					}
@@ -4995,7 +5110,7 @@ var spine;
 					var frameIndex = 0;
 					for (var i = 0; i < constraintMap.length; i++) {
 						var valueMap = constraintMap[i];
-						timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1));
+						timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1));
 						this.readCurve(valueMap, timeline, frameIndex);
 						frameIndex++;
 					}
@@ -5003,9 +5118,9 @@ var spine;
 					duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TransformConstraintTimeline.ENTRIES]);
 				}
 			}
-			if (map.paths) {
-				for (var constraintName in map.paths) {
-					var constraintMap = map.paths[constraintName];
+			if (map.path) {
+				for (var constraintName in map.path) {
+					var constraintMap = map.path[constraintName];
 					var index = skeletonData.findPathConstraintIndex(constraintName);
 					if (index == -1)
 						throw new Error("Path constraint not found: " + constraintName);
@@ -5029,7 +5144,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, timelineName, 0) * timelineScale);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, timelineName, 0) * timelineScale);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5042,7 +5157,7 @@ var spine;
 							var frameIndex = 0;
 							for (var i = 0; i < timelineMap.length; i++) {
 								var valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1));
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1));
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5094,7 +5209,7 @@ var spine;
 											deform[i] += vertices[i];
 									}
 								}
-								timeline.setFrame(frameIndex, valueMap.time, deform);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), deform);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -5134,7 +5249,7 @@ var spine;
 							if (drawOrder[i] == -1)
 								drawOrder[i] = unchanged[--unchangedIndex];
 					}
-					timeline.setFrame(frameIndex++, drawOrderMap.time, drawOrder);
+					timeline.setFrame(frameIndex++, this.getValue(drawOrderMap, "time", 0), drawOrder);
 				}
 				timelines.push(timeline);
 				duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
@@ -5147,7 +5262,7 @@ var spine;
 					var eventData = skeletonData.findEvent(eventMap.name);
 					if (eventData == null)
 						throw new Error("Event not found: " + eventMap.name);
-					var event_5 = new spine.Event(spine.Utils.toSinglePrecision(eventMap.time), eventData);
+					var event_5 = new spine.Event(spine.Utils.toSinglePrecision(this.getValue(eventMap, "time", 0)), eventData);
 					event_5.intValue = this.getValue(eventMap, "int", eventData.intValue);
 					event_5.floatValue = this.getValue(eventMap, "float", eventData.floatValue);
 					event_5.stringValue = this.getValue(eventMap, "string", eventData.stringValue);
@@ -5168,11 +5283,11 @@ var spine;
 		SkeletonJson.prototype.readCurve = function (map, timeline, frameIndex) {
 			if (!map.curve)
 				return;
-			if (map.curve === "stepped")
+			if (map.curve == "stepped")
 				timeline.setStepped(frameIndex);
 			else if (Object.prototype.toString.call(map.curve) === '[object Array]') {
 				var curve = map.curve;
-				timeline.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]);
+				timeline.setCurve(frameIndex, curve, this.getValue(map, "c2", 0), this.getValue(map, "c3", 1), this.getValue(map, "c4", 1));
 			}
 		};
 		SkeletonJson.prototype.getValue = function (map, prop, defaultValue) {
@@ -5725,6 +5840,7 @@ var spine;
 			this.scaleMix = 0;
 			this.shearMix = 0;
 			this.temp = new spine.Vector2();
+			this.active = false;
 			if (data == null)
 				throw new Error("data cannot be null.");
 			if (skeleton == null)
@@ -5739,6 +5855,9 @@ var spine;
 				this.bones.push(skeleton.findBone(data.bones[i].name));
 			this.target = skeleton.findBone(data.target.name);
 		}
+		TransformConstraint.prototype.isActive = function () {
+			return this.active;
+		};
 		TransformConstraint.prototype.apply = function () {
 			this.update();
 		};
@@ -5948,37 +6067,33 @@ var spine;
 				bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
 			}
 		};
-		TransformConstraint.prototype.getOrder = function () {
-			return this.data.order;
-		};
 		return TransformConstraint;
 	}());
 	spine.TransformConstraint = TransformConstraint;
 })(spine || (spine = {}));
 var spine;
 (function (spine) {
-	var TransformConstraintData = (function () {
+	var TransformConstraintData = (function (_super) {
+		__extends(TransformConstraintData, _super);
 		function TransformConstraintData(name) {
-			this.order = 0;
-			this.bones = new Array();
-			this.rotateMix = 0;
-			this.translateMix = 0;
-			this.scaleMix = 0;
-			this.shearMix = 0;
-			this.offsetRotation = 0;
-			this.offsetX = 0;
-			this.offsetY = 0;
-			this.offsetScaleX = 0;
-			this.offsetScaleY = 0;
-			this.offsetShearY = 0;
-			this.relative = false;
-			this.local = false;
-			if (name == null)
-				throw new Error("name cannot be null.");
-			this.name = name;
+			var _this = _super.call(this, name, 0, false) || this;
+			_this.bones = new Array();
+			_this.rotateMix = 0;
+			_this.translateMix = 0;
+			_this.scaleMix = 0;
+			_this.shearMix = 0;
+			_this.offsetRotation = 0;
+			_this.offsetX = 0;
+			_this.offsetY = 0;
+			_this.offsetScaleX = 0;
+			_this.offsetScaleY = 0;
+			_this.offsetShearY = 0;
+			_this.relative = false;
+			_this.local = false;
+			return _this;
 		}
 		return TransformConstraintData;
-	}());
+	}(spine.ConstraintData));
 	spine.TransformConstraintData = TransformConstraintData;
 })(spine || (spine = {}));
 var spine;
@@ -6428,6 +6543,14 @@ var spine;
 		};
 		Utils.webkit602BugfixHelper = function (alpha, blend) {
 		};
+		Utils.contains = function (array, element, identity) {
+			if (identity === void 0) { identity = true; }
+			for (var i = 0; i < array.length; i++) {
+				if (array[i] == element)
+					return true;
+			}
+			return false;
+		};
 		Utils.SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== "undefined";
 		return Utils;
 	}());
@@ -9169,6 +9292,8 @@ var spine;
 					var slots = skeleton.slots;
 					for (var i = 0, n = slots.length; i < n; i++) {
 						var slot = slots[i];
+						if (!slot.bone.active)
+							continue;
 						var attachment = slot.getAttachment();
 						if (!(attachment instanceof spine.MeshAttachment))
 							continue;
@@ -9214,6 +9339,8 @@ var spine;
 					var slots = skeleton.slots;
 					for (var i = 0, n = slots.length; i < n; i++) {
 						var slot = slots[i];
+						if (!slot.bone.active)
+							continue;
 						var attachment = slot.getAttachment();
 						if (!(attachment instanceof spine.PathAttachment))
 							continue;
@@ -9262,6 +9389,8 @@ var spine;
 					shapes.setColor(this.clipColor);
 					for (var i = 0, n = slots.length; i < n; i++) {
 						var slot = slots[i];
+						if (!slot.bone.active)
+							continue;
 						var attachment = slot.getAttachment();
 						if (!(attachment instanceof spine.ClippingAttachment))
 							continue;
@@ -9345,6 +9474,10 @@ var spine;
 				for (var i = 0, n = drawOrder.length; i < n; i++) {
 					var clippedVertexSize = clipper.isClipping() ? 2 : vertexSize;
 					var slot = drawOrder[i];
+					if (!slot.bone.active) {
+						clipper.clipEndWithSlot(slot);
+						continue;
+					}
 					if (slotRangeStart >= 0 && slotRangeStart == slot.data.index) {
 						inRange = true;
 					}

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
spine-ts/build/spine-webgl.js.map


Разница между файлами не показана из-за своего большого размера
+ 209 - 390
spine-ts/canvas/example/assets/spineboy-ess.json


+ 51 - 51
spine-ts/canvas/example/assets/spineboy.atlas

@@ -6,280 +6,280 @@ filter: Linear,Linear
 repeat: none
 crosshair
   rotate: false
-  xy: 352, 7
+  xy: 976, 69
   size: 45, 45
   orig: 45, 45
   offset: 0, 0
   index: -1
 eye-indifferent
-  rotate: false
-  xy: 862, 105
+  rotate: true
+  xy: 967, 116
   size: 47, 45
   orig: 47, 45
   offset: 0, 0
   index: -1
 eye-surprised
   rotate: false
-  xy: 505, 79
+  xy: 434, 68
   size: 47, 45
   orig: 47, 45
   offset: 0, 0
   index: -1
 front-bracer
   rotate: false
-  xy: 826, 66
+  xy: 582, 78
   size: 29, 40
   orig: 29, 40
   offset: 0, 0
   index: -1
 front-fist-closed
   rotate: false
-  xy: 786, 65
+  xy: 825, 33
   size: 38, 41
   orig: 38, 41
   offset: 0, 0
   index: -1
 front-fist-open
-  rotate: true
-  xy: 710, 51
+  rotate: false
+  xy: 67, 53
   size: 43, 44
   orig: 43, 44
   offset: 0, 0
   index: -1
 front-foot
   rotate: false
-  xy: 210, 6
+  xy: 2, 62
   size: 63, 35
   orig: 63, 35
   offset: 0, 0
   index: -1
 front-shin
   rotate: true
-  xy: 665, 128
+  xy: 488, 77
   size: 41, 92
   orig: 41, 92
   offset: 0, 0
   index: -1
 front-thigh
-  rotate: true
-  xy: 2, 2
+  rotate: false
+  xy: 112, 41
   size: 23, 56
   orig: 23, 56
   offset: 0, 0
   index: -1
 front-upper-arm
   rotate: false
-  xy: 250, 205
+  xy: 865, 25
   size: 23, 49
   orig: 23, 49
   offset: 0, 0
   index: -1
 goggles
-  rotate: false
-  xy: 665, 171
+  rotate: true
+  xy: 743, 117
   size: 131, 83
   orig: 131, 83
   offset: 0, 0
   index: -1
 gun
-  rotate: false
-  xy: 798, 152
+  rotate: true
+  xy: 828, 143
   size: 105, 102
   orig: 105, 102
   offset: 0, 0
   index: -1
 head
   rotate: false
-  xy: 2, 27
+  xy: 2, 99
   size: 136, 149
   orig: 136, 149
   offset: 0, 0
   index: -1
 hoverboard-board
-  rotate: false
-  xy: 2, 178
+  rotate: true
+  xy: 140, 2
   size: 246, 76
   orig: 246, 76
   offset: 0, 0
   index: -1
 hoverboard-thruster
-  rotate: true
-  xy: 722, 96
+  rotate: false
+  xy: 987, 167
   size: 30, 32
   orig: 30, 32
   offset: 0, 0
   index: -1
 hoverglow-small
   rotate: false
-  xy: 275, 81
+  xy: 828, 103
   size: 137, 38
   orig: 137, 38
   offset: 0, 0
   index: -1
 mouth-grind
   rotate: false
-  xy: 614, 97
+  xy: 365, 41
   size: 47, 30
   orig: 47, 30
   offset: 0, 0
   index: -1
 mouth-oooo
   rotate: false
-  xy: 612, 65
+  xy: 602, 40
   size: 47, 30
   orig: 47, 30
   offset: 0, 0
   index: -1
 mouth-smile
   rotate: false
-  xy: 661, 64
+  xy: 651, 40
   size: 47, 30
   orig: 47, 30
   offset: 0, 0
   index: -1
 muzzle-glow
   rotate: false
-  xy: 382, 54
+  xy: 976, 42
   size: 25, 25
   orig: 25, 25
   offset: 0, 0
   index: -1
 muzzle-ring
   rotate: true
-  xy: 275, 54
+  xy: 799, 76
   size: 25, 105
   orig: 25, 105
   offset: 0, 0
   index: -1
 muzzle01
-  rotate: true
-  xy: 911, 95
+  rotate: false
+  xy: 365, 73
   size: 67, 40
   orig: 67, 40
   offset: 0, 0
   index: -1
 muzzle02
   rotate: false
-  xy: 792, 108
+  xy: 295, 71
   size: 68, 42
   orig: 68, 42
   offset: 0, 0
   index: -1
 muzzle03
   rotate: true
-  xy: 956, 171
+  xy: 932, 165
   size: 83, 53
   orig: 83, 53
   offset: 0, 0
   index: -1
 muzzle04
   rotate: false
-  xy: 275, 7
+  xy: 218, 68
   size: 75, 45
   orig: 75, 45
   offset: 0, 0
   index: -1
 muzzle05
   rotate: false
-  xy: 140, 3
+  xy: 906, 63
   size: 68, 38
   orig: 68, 38
   offset: 0, 0
   index: -1
 neck
   rotate: false
-  xy: 250, 182
+  xy: 1003, 46
   size: 18, 21
   orig: 18, 21
   offset: 0, 0
   index: -1
 portal-bg
   rotate: false
-  xy: 140, 43
+  xy: 218, 115
   size: 133, 133
   orig: 133, 133
   offset: 0, 0
   index: -1
 portal-flare1
   rotate: false
-  xy: 554, 65
+  xy: 767, 44
   size: 56, 30
   orig: 56, 30
   offset: 0, 0
   index: -1
 portal-flare2
-  rotate: true
-  xy: 759, 112
+  rotate: false
+  xy: 483, 44
   size: 57, 31
   orig: 57, 31
   offset: 0, 0
   index: -1
 portal-flare3
   rotate: false
-  xy: 554, 97
+  xy: 542, 45
   size: 58, 30
   orig: 58, 30
   offset: 0, 0
   index: -1
 portal-shade
   rotate: false
-  xy: 275, 121
+  xy: 353, 115
   size: 133, 133
   orig: 133, 133
   offset: 0, 0
   index: -1
 portal-streaks1
   rotate: false
-  xy: 410, 126
+  xy: 488, 120
   size: 126, 128
   orig: 126, 128
   offset: 0, 0
   index: -1
 portal-streaks2
   rotate: false
-  xy: 538, 129
+  xy: 616, 123
   size: 125, 125
   orig: 125, 125
   offset: 0, 0
   index: -1
 rear-bracer
   rotate: false
-  xy: 857, 67
+  xy: 295, 33
   size: 28, 36
   orig: 28, 36
   offset: 0, 0
   index: -1
 rear-foot
   rotate: false
-  xy: 663, 96
+  xy: 708, 45
   size: 57, 30
   orig: 57, 30
   offset: 0, 0
   index: -1
 rear-shin
   rotate: true
-  xy: 414, 86
+  xy: 708, 77
   size: 38, 89
   orig: 38, 89
   offset: 0, 0
   index: -1
 rear-thigh
   rotate: false
-  xy: 756, 63
+  xy: 987, 201
   size: 28, 47
   orig: 28, 47
   offset: 0, 0
   index: -1
 rear-upper-arm
-  rotate: true
-  xy: 60, 5
+  rotate: false
+  xy: 325, 25
   size: 20, 44
   orig: 20, 44
   offset: 0, 0
   index: -1
 torso
-  rotate: false
-  xy: 905, 164
+  rotate: true
+  xy: 616, 72
   size: 49, 90
   orig: 49, 90
   offset: 0, 0

BIN
spine-ts/canvas/example/assets/spineboy.png


+ 1 - 0
spine-ts/canvas/src/SkeletonRenderer.ts

@@ -57,6 +57,7 @@ module spine.canvas {
 			ctx.save();
 			for (let i = 0, n = drawOrder.length; i < n; i++) {
 				let slot = drawOrder[i];
+				if (!slot.bone.active) continue;
 				let attachment = slot.getAttachment();
 				let regionAttachment: RegionAttachment = null;
 				let region: TextureAtlasRegion = null;

+ 13 - 1
spine-ts/core/src/Animation.ts

@@ -219,6 +219,7 @@ module spine {
 			let frames = this.frames;
 
 			let bone = skeleton.bones[this.boneIndex];
+			if (!bone.active) return;
 			if (time < frames[0]) {
 				switch (blend) {
 				case MixBlend.setup:
@@ -298,6 +299,7 @@ module spine {
 			let frames = this.frames;
 
 			let bone = skeleton.bones[this.boneIndex];
+			if (!bone.active) return;
 			if (time < frames[0]) {
 				switch (blend) {
 				case MixBlend.setup:
@@ -357,6 +359,7 @@ module spine {
 			let frames = this.frames;
 
 			let bone = skeleton.bones[this.boneIndex];
+			if (!bone.active) return;
 			if (time < frames[0]) {
 				switch (blend) {
 				case MixBlend.setup:
@@ -456,6 +459,7 @@ module spine {
 			let frames = this.frames;
 
 			let bone = skeleton.bones[this.boneIndex];
+			if (!bone.active) return;
 			if (time < frames[0]) {
 				switch (blend) {
 				case MixBlend.setup:
@@ -531,6 +535,7 @@ module spine {
 
 		apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
 			let slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active) return;
 			let frames = this.frames;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -611,6 +616,7 @@ module spine {
 
 		apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
 			let slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active) return;
 			let frames = this.frames;
 			if (time < frames[0]) {
 				switch (blend) {
@@ -700,6 +706,7 @@ module spine {
 
 		apply (skeleton: Skeleton, lastTime: number, time: number, events: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
 			let slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active) return;
 			if (direction == MixDirection.mixOut && blend == MixBlend.setup) {
 				let attachmentName = slot.data.attachmentName;
 				slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName));
@@ -754,6 +761,7 @@ module spine {
 
 		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
 			let slot: Slot = skeleton.slots[this.slotIndex];
+			if (!slot.bone.active) return;
 			let slotAttachment: Attachment = slot.getAttachment();
 			if (!(slotAttachment instanceof VertexAttachment) || !((<VertexAttachment>slotAttachment).deformAttachment == this.attachment)) return;
 
@@ -1065,6 +1073,7 @@ module spine {
 		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
 			let frames = this.frames;
 			let constraint: IkConstraint = skeleton.ikConstraints[this.ikConstraintIndex];
+			if (!constraint.active) return;
 			if (time < frames[0]) {
 				switch (blend) {
 				case MixBlend.setup:
@@ -1165,6 +1174,7 @@ module spine {
 			let frames = this.frames;
 
 			let constraint: TransformConstraint = skeleton.transformConstraints[this.transformConstraintIndex];
+			if (!constraint.active) return;
 			if (time < frames[0]) {
 				let data = constraint.data;
 				switch (blend) {
@@ -1249,6 +1259,7 @@ module spine {
 		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
 			let frames = this.frames;
 			let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active) return;
 			if (time < frames[0]) {
 				switch (blend) {
 				case MixBlend.setup:
@@ -1292,6 +1303,7 @@ module spine {
 		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
 			let frames = this.frames;
 			let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex];
+			if (!constraint.active) return;
 			if (time < frames[0]) {
 				switch (blend) {
 				case MixBlend.setup:
@@ -1353,7 +1365,7 @@ module spine {
 		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
 			let frames = this.frames;
 			let constraint: PathConstraint = skeleton.pathConstraints[this.pathConstraintIndex];
-
+			if (!constraint.active) return;
 			if (time < frames[0]) {
 				switch (blend) {
 				case MixBlend.setup:

+ 1 - 0
spine-ts/core/src/AnimationState.ts

@@ -291,6 +291,7 @@ module spine {
 			let rotateTimeline = timeline as RotateTimeline;
 			let frames = rotateTimeline.frames;
 			let bone = skeleton.bones[rotateTimeline.boneIndex];
+			if (!bone.active) return;
 			let r1 = 0, r2 = 0;
 			if (time < frames[0]) {
 				switch (blend) {

+ 5 - 0
spine-ts/core/src/Bone.ts

@@ -41,6 +41,7 @@ module spine {
 		c = 0; d = 0; worldY = 0;
 
 		sorted = false;
+		active = false;
 
 		/** @param parent May be null. */
 		constructor (data: BoneData, skeleton: Skeleton, parent: Bone) {
@@ -52,6 +53,10 @@ module spine {
 			this.setToSetupPose();
 		}
 
+		isActive () {
+			return this.active;
+		}
+
 		/** Same as {@link #updateWorldTransform()}. This method exists for Bone to implement {@link Updatable}. */
 		update () {
 			this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY);

+ 1 - 0
spine-ts/core/src/BoneData.ts

@@ -35,6 +35,7 @@ module spine {
 		length: number;
 		x = 0; y = 0; rotation = 0; scaleX = 1; scaleY = 1; shearX = 0; shearY = 0;
 		transformMode = TransformMode.Normal;
+		skinRequired = false;
 
 		constructor (index: number, name: string, parent: BoneData) {
 			if (index < 0) throw new Error("index must be >= 0.");

+ 2 - 2
spine-ts/core/src/Constraint.ts

@@ -28,7 +28,7 @@
  *****************************************************************************/
 
 module spine {
-	export interface Constraint extends Updatable {
-		getOrder(): number;
+	export abstract class ConstraintData {
+		constructor(public name: string, public order: number, public skinRequired: boolean) { }
 	}
 }

+ 4 - 3
spine-ts/core/src/IkConstraint.ts

@@ -28,7 +28,7 @@
  *****************************************************************************/
 
 module spine {
-	export class IkConstraint implements Constraint {
+	export class IkConstraint implements Updatable {
 		data: IkConstraintData;
 		bones: Array<Bone>;
 		target: Bone;
@@ -36,6 +36,7 @@ module spine {
 		compress = false;
 		stretch = false;
 		mix = 1;
+		active = false;
 
 		constructor (data: IkConstraintData, skeleton: Skeleton) {
 			if (data == null) throw new Error("data cannot be null.");
@@ -52,8 +53,8 @@ module spine {
 			this.target = skeleton.findBone(data.target.name);
 		}
 
-		getOrder () {
-			return this.data.order;
+		isActive () {
+			return this.active;
 		}
 
 		apply () {

+ 2 - 4
spine-ts/core/src/IkConstraintData.ts

@@ -28,9 +28,7 @@
  *****************************************************************************/
 
 module spine {
-	export class IkConstraintData {
-		name: string;
-		order = 0;
+	export class IkConstraintData extends ConstraintData {
 		bones = new Array<BoneData>();
 		target: BoneData;
 		bendDirection = 1;
@@ -40,7 +38,7 @@ module spine {
 		mix = 1;
 
 		constructor (name: string) {
-			this.name = name;
+			super(name, 0, false);
 		}
 	}
 }

+ 7 - 5
spine-ts/core/src/PathConstraint.ts

@@ -28,7 +28,7 @@
  *****************************************************************************/
 
 module spine {
-	export class PathConstraint implements Constraint {
+	export class PathConstraint implements Updatable {
 		static NONE = -1; static BEFORE = -2; static AFTER = -3;
 		static epsilon = 0.00001;
 
@@ -41,6 +41,8 @@ module spine {
 		world = new Array<number>(); curves = new Array<number>(); lengths = new Array<number>();
 		segments = new Array<number>();
 
+		active = false;
+
 		constructor (data: PathConstraintData, skeleton: Skeleton) {
 			if (data == null) throw new Error("data cannot be null.");
 			if (skeleton == null) throw new Error("skeleton cannot be null.");
@@ -55,6 +57,10 @@ module spine {
 			this.translateMix = data.translateMix;
 		}
 
+		isActive () {
+			return this.active;
+		}
+
 		apply () {
 			this.update();
 		}
@@ -417,9 +423,5 @@ module spine {
 					out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
 			}
 		}
-
-		getOrder () {
-			return this.data.order;
-		}
 	}
 }

+ 2 - 4
spine-ts/core/src/PathConstraintData.ts

@@ -28,9 +28,7 @@
  *****************************************************************************/
 
 module spine {
-	export class PathConstraintData {
-		name: string;
-		order = 0;
+	export class PathConstraintData extends ConstraintData {
 		bones = new Array<BoneData>();
 		target: SlotData;
 		positionMode: PositionMode;
@@ -40,7 +38,7 @@ module spine {
 		position: number; spacing: number; rotateMix: number; translateMix: number;
 
 		constructor (name: string) {
-			this.name = name;
+			super(name, 0, false);
 		}
 	}
 

+ 29 - 2
spine-ts/core/src/Skeleton.ts

@@ -100,8 +100,23 @@ module spine {
 			this.updateCacheReset.length = 0;
 
 			let bones = this.bones;
-			for (let i = 0, n = bones.length; i < n; i++)
-				bones[i].sorted = false;
+			for (let i = 0, n = bones.length; i < n; i++) {
+				let bone = bones[i];
+				bone.sorted = bone.data.skinRequired;
+				bone.active = !bone.sorted;
+			}
+
+			if (this.skin != null) {
+				let skinBones = this.skin.bones;
+				for (let i = 0, n = this.skin.bones.length; i < n; i++) {
+					let bone = this.bones[skinBones[i].index];
+					do {
+						bone.sorted = false;
+						bone.active = true;
+						bone = bone.parent;
+					} while (bone != null);
+				}
+			}
 
 			// IK first, lowest hierarchy depth first.
 			let ikConstraints = this.ikConstraints;
@@ -140,6 +155,9 @@ module spine {
 		}
 
 		sortIkConstraint (constraint: IkConstraint) {
+			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active) return;
+
 			let target = constraint.target;
 			this.sortBone(target);
 
@@ -159,6 +177,9 @@ module spine {
 		}
 
 		sortPathConstraint (constraint: PathConstraint) {
+			constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin != null && Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active) return;
+
 			let slot = constraint.target;
 			let slotIndex = slot.data.index;
 			let slotBone = slot.bone;
@@ -185,6 +206,9 @@ module spine {
 		}
 
 		sortTransformConstraint (constraint: TransformConstraint) {
+			constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && Utils.contains(this.skin.constraints, constraint.data, true)));
+			if (!constraint.active) return;
+
 			this.sortBone(constraint.target);
 
 			let constrained = constraint.bones;
@@ -246,6 +270,7 @@ module spine {
 		sortReset (bones: Array<Bone>) {
 			for (let i = 0, n = bones.length; i < n; i++) {
 				let bone = bones[i];
+				if (!bone.update) continue;
 				if (bone.sorted) this.sortReset(bone.children);
 				bone.sorted = false;
 			}
@@ -378,6 +403,7 @@ module spine {
 		 * old skin, each slot's setup mode attachment is attached from the new skin.
 		 * @param newSkin May be null. */
 		setSkin (newSkin: Skin) {
+			if (newSkin == this.skin) return;
 			if (newSkin != null) {
 				if (this.skin != null)
 					newSkin.attachAll(this, this.skin);
@@ -394,6 +420,7 @@ module spine {
 				}
 			}
 			this.skin = newSkin;
+			this.updateCache();
 		}
 
 		/** @return May be null. */

+ 69 - 31
spine-ts/core/src/SkeletonJson.ts

@@ -76,6 +76,7 @@ module spine {
 					data.shearX = this.getValue(boneMap, "shearX", 0);
 					data.shearY = this.getValue(boneMap, "shearY", 0);
 					data.transformMode = SkeletonJson.transformModeFromString(this.getValue(boneMap, "transform", "normal"));
+					data.skinRequired = this.getValue(boneMap, "skin", false);
 
 					skeletonData.bones.push(data);
 				}
@@ -112,6 +113,7 @@ module spine {
 					let constraintMap = root.ik[i];
 					let data = new IkConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 
 					for (let j = 0; j < constraintMap.bones.length; j++) {
 						let boneName = constraintMap.bones[j];
@@ -140,6 +142,7 @@ module spine {
 					let constraintMap = root.transform[i];
 					let data = new TransformConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 
 					for (let j = 0; j < constraintMap.bones.length; j++) {
 						let boneName = constraintMap.bones[j];
@@ -176,6 +179,7 @@ module spine {
 					let constraintMap = root.path[i];
 					let data = new PathConstraintData(constraintMap.name);
 					data.order = this.getValue(constraintMap, "order", 0);
+					data.skinRequired = this.getValue(constraintMap, "skin", false);
 
 					for (let j = 0; j < constraintMap.bones.length; j++) {
 						let boneName = constraintMap.bones[j];
@@ -205,16 +209,49 @@ module spine {
 
 			// Skins.
 			if (root.skins) {
-				for (let skinName in root.skins) {
-					let skinMap = root.skins[skinName]
-					let skin = new Skin(skinName);
-					for (let slotName in skinMap) {
-						let slotIndex = skeletonData.findSlotIndex(slotName);
-						if (slotIndex == -1) throw new Error("Slot not found: " + slotName);
-						let slotMap = skinMap[slotName];
+				for (let i = 0; i < root.skins.length; i++) {
+					let skinMap = root.skins[i]
+					let skin = new Skin(skinMap.name);
+
+					if (skinMap.bones) {
+						for (let ii = 0; ii < skinMap.bones.length; ii++) {
+							let bone = skeletonData.findBone(skinMap.bones[ii]);
+							if (bone == null) throw new Error("Skin bone not found: " + skinMap.bones[i]);
+							skin.bones.push(bone);
+						}
+					}
+
+					if (skinMap.ik) {
+						for (let ii = 0; ii < skinMap.ik.length; ii++) {
+							let constraint = skeletonData.findIkConstraint(skinMap.ik[ii]);
+							if (constraint == null) throw new Error("Skin IK constraint not found: " + skinMap.ik[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+
+					if (skinMap.transform) {
+						for (let ii = 0; ii < skinMap.transform.length; ii++) {
+							let constraint = skeletonData.findIkConstraint(skinMap.transform[ii]);
+							if (constraint == null) throw new Error("Skin transform constraint not found: " + skinMap.transform[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+
+					if (skinMap.path) {
+						for (let ii = 0; ii < skinMap.path.length; ii++) {
+							let constraint = skeletonData.findIkConstraint(skinMap.path[ii]);
+							if (constraint == null) throw new Error("Skin path constraint not found: " + skinMap.path[i]);
+							skin.constraints.push(constraint);
+						}
+					}
+
+					for (let slotName in skinMap.attachments) {
+						let slot = skeletonData.findSlot(slotName);
+						if (slot == null) throw new Error("Slot not found: " + slotName);
+						let slotMap = skinMap.attachments[slotName];
 						for (let entryName in slotMap) {
-							let attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName, skeletonData);
-							if (attachment != null) skin.setAttachment(slotIndex, entryName, attachment);
+							let attachment = this.readAttachment(slotMap[entryName], skin, slot.index, entryName, skeletonData);
+							if (attachment != null) skin.setAttachment(slot.index, entryName, attachment);
 						}
 					}
 					skeletonData.skins.push(skin);
@@ -426,7 +463,7 @@ module spine {
 							let frameIndex = 0;
 							for (let i = 0; i < timelineMap.length; i++) {
 								let valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex++, valueMap.time, valueMap.name);
+								timeline.setFrame(frameIndex++, this.getValue(valueMap, "time", 0), valueMap.name);
 							}
 							timelines.push(timeline);
 							duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
@@ -439,7 +476,7 @@ module spine {
 								let valueMap = timelineMap[i];
 								let color = new Color();
 								color.setFromString(valueMap.color);
-								timeline.setFrame(frameIndex, valueMap.time, color.r, color.g, color.b, color.a);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), color.r, color.g, color.b, color.a);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -457,7 +494,7 @@ module spine {
 								let dark = new Color();
 								light.setFromString(valueMap.light);
 								dark.setFromString(valueMap.dark);
-								timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -485,7 +522,7 @@ module spine {
 							let frameIndex = 0;
 							for (let i = 0; i < timelineMap.length; i++) {
 								let valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, valueMap.angle);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "angle", 0));
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -494,10 +531,11 @@ module spine {
 
 						} else if (timelineName === "translate" || timelineName === "scale" || timelineName === "shear") {
 							let timeline: TranslateTimeline = null;
-							let timelineScale = 1;
-							if (timelineName === "scale")
+							let timelineScale = 1, defaultValue = 0;
+							if (timelineName === "scale") {
 								timeline = new ScaleTimeline(timelineMap.length);
-							else if (timelineName === "shear")
+								defaultValue = 1;
+							} else if (timelineName === "shear")
 								timeline = new ShearTimeline(timelineMap.length);
 							else {
 								timeline = new TranslateTimeline(timelineMap.length);
@@ -508,8 +546,8 @@ module spine {
 							let frameIndex = 0;
 							for (let i = 0; i < timelineMap.length; i++) {
 								let valueMap = timelineMap[i];
-								let x = this.getValue(valueMap, "x", 0), y = this.getValue(valueMap, "y", 0);
-								timeline.setFrame(frameIndex, valueMap.time, x * timelineScale, y * timelineScale);
+								let x = this.getValue(valueMap, "x", defaultValue), y = this.getValue(valueMap, "y", defaultValue);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), x * timelineScale, y * timelineScale);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -532,7 +570,7 @@ module spine {
 					let frameIndex = 0;
 					for (let i = 0; i < constraintMap.length; i++) {
 						let valueMap = constraintMap[i];
-						timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1),
+						timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "mix", 1),
 							this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false));
 						this.readCurve(valueMap, timeline, frameIndex);
 						frameIndex++;
@@ -552,7 +590,7 @@ module spine {
 					let frameIndex = 0;
 					for (let i = 0; i < constraintMap.length; i++) {
 						let valueMap = constraintMap[i];
-						timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1),
+						timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1),
 							this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1));
 						this.readCurve(valueMap, timeline, frameIndex);
 						frameIndex++;
@@ -564,9 +602,9 @@ module spine {
 			}
 
 			// Path constraint timelines.
-			if (map.paths) {
-				for (let constraintName in map.paths) {
-					let constraintMap = map.paths[constraintName];
+			if (map.path) {
+				for (let constraintName in map.path) {
+					let constraintMap = map.path[constraintName];
 					let index = skeletonData.findPathConstraintIndex(constraintName);
 					if (index == -1) throw new Error("Path constraint not found: " + constraintName);
 					let data = skeletonData.pathConstraints[index];
@@ -586,7 +624,7 @@ module spine {
 							let frameIndex = 0;
 							for (let i = 0; i < timelineMap.length; i++) {
 								let valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, timelineName, 0) * timelineScale);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, timelineName, 0) * timelineScale);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -599,7 +637,7 @@ module spine {
 							let frameIndex = 0;
 							for (let i = 0; i < timelineMap.length; i++) {
 								let valueMap = timelineMap[i];
-								timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1),
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1),
 									this.getValue(valueMap, "translateMix", 1));
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
@@ -655,7 +693,7 @@ module spine {
 									}
 								}
 
-								timeline.setFrame(frameIndex, valueMap.time, deform);
+								timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), deform);
 								this.readCurve(valueMap, timeline, frameIndex);
 								frameIndex++;
 							}
@@ -698,7 +736,7 @@ module spine {
 						for (let i = slotCount - 1; i >= 0; i--)
 							if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex];
 					}
-					timeline.setFrame(frameIndex++, drawOrderMap.time, drawOrder);
+					timeline.setFrame(frameIndex++, this.getValue(drawOrderMap, "time", 0), drawOrder);
 				}
 				timelines.push(timeline);
 				duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
@@ -712,7 +750,7 @@ module spine {
 					let eventMap = map.events[i];
 					let eventData = skeletonData.findEvent(eventMap.name);
 					if (eventData == null) throw new Error("Event not found: " + eventMap.name);
-					let event = new Event(Utils.toSinglePrecision(eventMap.time), eventData);
+					let event = new Event(Utils.toSinglePrecision(this.getValue(eventMap, "time", 0)), eventData);
 					event.intValue = this.getValue(eventMap, "int", eventData.intValue);
 					event.floatValue = this.getValue(eventMap, "float", eventData.floatValue);
 					event.stringValue = this.getValue(eventMap, "string", eventData.stringValue);
@@ -735,11 +773,11 @@ module spine {
 
 		readCurve (map: any, timeline: CurveTimeline, frameIndex: number) {
 			if (!map.curve) return;
-			if (map.curve === "stepped")
+			if (map.curve == "stepped")
 				timeline.setStepped(frameIndex);
 			else if (Object.prototype.toString.call(map.curve) === '[object Array]') {
-				let curve: Array<number> = map.curve;
-				timeline.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]);
+				let curve: number = map.curve;
+				timeline.setCurve(frameIndex, curve, this.getValue(map, "c2", 0), this.getValue(map, "c3", 1), this.getValue(map, "c4", 1));
 			}
 		}
 

+ 1 - 1
spine-ts/core/src/Skin.ts

@@ -36,7 +36,7 @@ module spine {
 		name: string;
 		attachments = new Array<Map<Attachment>>();
 		bones = Array<BoneData>();
-		constraints = new Array<Constraint>();
+		constraints = new Array<ConstraintData>();
 
 		constructor (name: string) {
 			if (name == null) throw new Error("name cannot be null.");

+ 6 - 5
spine-ts/core/src/TransformConstraint.ts

@@ -28,12 +28,13 @@
  *****************************************************************************/
 
 module spine {
-	export class TransformConstraint implements Constraint {
+	export class TransformConstraint implements Updatable {
 		data: TransformConstraintData;
 		bones: Array<Bone>;
 		target: Bone;
 		rotateMix = 0; translateMix = 0; scaleMix = 0; shearMix = 0;
 		temp = new Vector2();
+		active = false;
 
 		constructor (data: TransformConstraintData, skeleton: Skeleton) {
 			if (data == null) throw new Error("data cannot be null.");
@@ -49,6 +50,10 @@ module spine {
 			this.target = skeleton.findBone(data.target.name);
 		}
 
+		isActive () {
+			return this.active;
+		}
+
 		apply () {
 			this.update();
 		}
@@ -267,9 +272,5 @@ module spine {
 				bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
 			}
 		}
-
-		getOrder () {
-			return this.data.order;
-		}
 	}
 }

+ 2 - 5
spine-ts/core/src/TransformConstraintData.ts

@@ -28,9 +28,7 @@
  *****************************************************************************/
 
 module spine {
-	export class TransformConstraintData {
-		name: string;
-		order = 0;
+	export class TransformConstraintData extends ConstraintData {
 		bones = new Array<BoneData>();
 		target: BoneData;
 		rotateMix = 0; translateMix = 0; scaleMix = 0; shearMix = 0;
@@ -39,8 +37,7 @@ module spine {
 		local = false;
 
 		constructor (name: string) {
-			if (name == null) throw new Error("name cannot be null.");
-			this.name = name;
+			super(name, 0, false);
 		}
 	}
 }

+ 2 - 0
spine-ts/core/src/Updatable.ts

@@ -30,5 +30,7 @@
 module spine {
 	export interface Updatable {
 		update(): void;
+
+		isActive(): boolean;
 	}
 }

+ 7 - 0
spine-ts/core/src/Utils.ts

@@ -263,6 +263,13 @@ module spine {
 		static webkit602BugfixHelper (alpha: number, blend: MixBlend) {
 
 		}
+
+		static contains<T> (array: Array<T>, element: T, identity = true) {
+			for (var i = 0; i < array.length; i++) {
+				if (array[i] == element) return true;
+			}
+			return false;
+		}
 	}
 
 	export class DebugUtils {

+ 58 - 58
spine-ts/player/example/assets/raptor-pma.atlas

@@ -6,266 +6,266 @@ filter: Linear,Linear
 repeat: none
 back-arm
   rotate: false
-  xy: 895, 295
+  xy: 518, 9
   size: 46, 25
   orig: 46, 25
   offset: 0, 0
   index: -1
 back-bracer
-  rotate: true
-  xy: 992, 216
+  rotate: false
+  xy: 566, 6
   size: 39, 28
   orig: 39, 28
   offset: 0, 0
   index: -1
 back-hand
   rotate: false
-  xy: 594, 58
+  xy: 663, 5
   size: 36, 34
   orig: 36, 34
   offset: 0, 0
   index: -1
 back-knee
-  rotate: true
-  xy: 729, 86
+  rotate: false
+  xy: 801, 47
   size: 49, 67
   orig: 49, 67
   offset: 0, 0
   index: -1
 back-thigh
   rotate: false
-  xy: 379, 2
+  xy: 279, 9
   size: 39, 24
   orig: 39, 24
   offset: 0, 0
   index: -1
 eyes-open
-  rotate: true
-  xy: 902, 194
+  rotate: false
+  xy: 955, 3
   size: 47, 45
   orig: 47, 45
   offset: 0, 0
   index: -1
 front-arm
   rotate: false
-  xy: 945, 306
+  xy: 613, 13
   size: 48, 26
   orig: 48, 26
   offset: 0, 0
   index: -1
 front-bracer
   rotate: false
-  xy: 949, 197
+  xy: 475, 5
   size: 41, 29
   orig: 41, 29
   offset: 0, 0
   index: -1
 front-hand
   rotate: false
-  xy: 949, 266
+  xy: 977, 344
   size: 41, 38
   orig: 41, 38
   offset: 0, 0
   index: -1
 front-open-hand
   rotate: false
-  xy: 875, 148
+  xy: 977, 434
   size: 43, 44
   orig: 43, 44
   offset: 0, 0
   index: -1
 front-thigh
-  rotate: true
-  xy: 793, 171
+  rotate: false
+  xy: 367, 11
   size: 57, 29
   orig: 57, 29
   offset: 0, 0
   index: -1
 gun
-  rotate: true
-  xy: 379, 28
+  rotate: false
+  xy: 506, 140
   size: 107, 103
   orig: 107, 103
   offset: 0, 0
   index: -1
 gun-nohand
   rotate: false
-  xy: 487, 87
+  xy: 506, 36
   size: 105, 102
   orig: 105, 102
   offset: 0, 0
   index: -1
 head
   rotate: false
-  xy: 807, 361
+  xy: 853, 136
   size: 136, 149
   orig: 136, 149
   offset: 0, 0
   index: -1
 lower-leg
-  rotate: false
-  xy: 827, 195
+  rotate: true
+  xy: 613, 41
   size: 73, 98
   orig: 73, 98
   offset: 0, 0
   index: -1
 mouth-grind
-  rotate: true
-  xy: 920, 145
+  rotate: false
+  xy: 801, 15
   size: 47, 30
   orig: 47, 30
   offset: 0, 0
   index: -1
 mouth-smile
-  rotate: true
-  xy: 992, 257
+  rotate: false
+  xy: 426, 10
   size: 47, 30
   orig: 47, 30
   offset: 0, 0
   index: -1
 neck
   rotate: false
-  xy: 359, 114
+  xy: 991, 275
   size: 18, 21
   orig: 18, 21
   offset: 0, 0
   index: -1
 raptor-back-arm
-  rotate: false
-  xy: 653, 142
+  rotate: true
+  xy: 713, 32
   size: 82, 86
   orig: 82, 86
   offset: 0, 0
   index: -1
 raptor-body
   rotate: false
-  xy: 2, 277
+  xy: 2, 245
   size: 632, 233
   orig: 632, 233
   offset: 0, 0
   index: -1
 raptor-front-arm
   rotate: true
-  xy: 484, 4
+  xy: 175, 34
   size: 81, 102
   orig: 81, 102
   offset: 0, 0
   index: -1
 raptor-front-leg
-  rotate: false
-  xy: 2, 18
+  rotate: true
+  xy: 636, 287
   size: 191, 257
   orig: 191, 257
   offset: 0, 0
   index: -1
 raptor-hindleg-back
-  rotate: false
-  xy: 636, 295
+  rotate: true
+  xy: 636, 116
   size: 169, 215
   orig: 169, 215
   offset: 0, 0
   index: -1
 raptor-horn
-  rotate: false
-  xy: 195, 22
+  rotate: true
+  xy: 895, 296
   size: 182, 80
   orig: 182, 80
   offset: 0, 0
   index: -1
 raptor-horn-back
-  rotate: true
-  xy: 945, 334
+  rotate: false
+  xy: 315, 166
   size: 176, 77
   orig: 176, 77
   offset: 0, 0
   index: -1
 raptor-jaw
-  rotate: false
-  xy: 359, 137
+  rotate: true
+  xy: 175, 117
   size: 126, 138
   orig: 126, 138
   offset: 0, 0
   index: -1
 raptor-jaw-tooth
-  rotate: true
-  xy: 895, 322
+  rotate: false
+  xy: 977, 384
   size: 37, 48
   orig: 37, 48
   offset: 0, 0
   index: -1
 raptor-mouth-inside
-  rotate: true
-  xy: 949, 228
+  rotate: false
+  xy: 464, 58
   size: 36, 41
   orig: 36, 41
   offset: 0, 0
   index: -1
 raptor-saddle-strap-back
   rotate: true
-  xy: 653, 86
+  xy: 95, 25
   size: 54, 74
   orig: 54, 74
   offset: 0, 0
   index: -1
 raptor-saddle-strap-front
-  rotate: false
-  xy: 594, 94
+  rotate: true
+  xy: 367, 42
   size: 57, 95
   orig: 57, 95
   offset: 0, 0
   index: -1
 raptor-saddle-w-shadow
-  rotate: false
-  xy: 195, 104
+  rotate: true
+  xy: 2, 81
   size: 162, 171
   orig: 162, 171
   offset: 0, 0
   index: -1
 raptor-tail-shadow
   rotate: false
-  xy: 636, 230
+  xy: 315, 101
   size: 189, 63
   orig: 189, 63
   offset: 0, 0
   index: -1
 raptor-tongue
   rotate: false
-  xy: 807, 295
+  xy: 279, 35
   size: 86, 64
   orig: 86, 64
   offset: 0, 0
   index: -1
 stirrup-back
   rotate: true
-  xy: 952, 151
+  xy: 977, 298
   size: 44, 35
   orig: 44, 35
   offset: 0, 0
   index: -1
 stirrup-front
-  rotate: false
-  xy: 902, 243
+  rotate: true
+  xy: 903, 3
   size: 45, 50
   orig: 45, 50
   offset: 0, 0
   index: -1
 stirrup-strap
   rotate: false
-  xy: 824, 147
+  xy: 852, 2
   size: 49, 46
   orig: 49, 46
   offset: 0, 0
   index: -1
 torso
-  rotate: false
-  xy: 737, 137
+  rotate: true
+  xy: 2, 25
   size: 54, 91
   orig: 54, 91
   offset: 0, 0
   index: -1
 visor
   rotate: false
-  xy: 487, 191
+  xy: 853, 50
   size: 131, 84
   orig: 131, 84
   offset: 0, 0

BIN
spine-ts/player/example/assets/raptor-pma.png


Разница между файлами не показана из-за своего большого размера
+ 73 - 74
spine-ts/player/example/assets/raptor-pro.json


+ 51 - 51
spine-ts/player/example/assets/spineboy-pma.atlas

@@ -6,280 +6,280 @@ filter: Linear,Linear
 repeat: none
 crosshair
   rotate: false
-  xy: 352, 7
+  xy: 976, 69
   size: 45, 45
   orig: 45, 45
   offset: 0, 0
   index: -1
 eye-indifferent
-  rotate: false
-  xy: 862, 105
+  rotate: true
+  xy: 967, 116
   size: 47, 45
   orig: 47, 45
   offset: 0, 0
   index: -1
 eye-surprised
   rotate: false
-  xy: 505, 79
+  xy: 434, 68
   size: 47, 45
   orig: 47, 45
   offset: 0, 0
   index: -1
 front-bracer
   rotate: false
-  xy: 826, 66
+  xy: 582, 78
   size: 29, 40
   orig: 29, 40
   offset: 0, 0
   index: -1
 front-fist-closed
   rotate: false
-  xy: 786, 65
+  xy: 825, 33
   size: 38, 41
   orig: 38, 41
   offset: 0, 0
   index: -1
 front-fist-open
-  rotate: true
-  xy: 710, 51
+  rotate: false
+  xy: 67, 53
   size: 43, 44
   orig: 43, 44
   offset: 0, 0
   index: -1
 front-foot
   rotate: false
-  xy: 210, 6
+  xy: 2, 62
   size: 63, 35
   orig: 63, 35
   offset: 0, 0
   index: -1
 front-shin
   rotate: true
-  xy: 665, 128
+  xy: 488, 77
   size: 41, 92
   orig: 41, 92
   offset: 0, 0
   index: -1
 front-thigh
-  rotate: true
-  xy: 2, 2
+  rotate: false
+  xy: 112, 41
   size: 23, 56
   orig: 23, 56
   offset: 0, 0
   index: -1
 front-upper-arm
   rotate: false
-  xy: 250, 205
+  xy: 865, 25
   size: 23, 49
   orig: 23, 49
   offset: 0, 0
   index: -1
 goggles
-  rotate: false
-  xy: 665, 171
+  rotate: true
+  xy: 743, 117
   size: 131, 83
   orig: 131, 83
   offset: 0, 0
   index: -1
 gun
-  rotate: false
-  xy: 798, 152
+  rotate: true
+  xy: 828, 143
   size: 105, 102
   orig: 105, 102
   offset: 0, 0
   index: -1
 head
   rotate: false
-  xy: 2, 27
+  xy: 2, 99
   size: 136, 149
   orig: 136, 149
   offset: 0, 0
   index: -1
 hoverboard-board
-  rotate: false
-  xy: 2, 178
+  rotate: true
+  xy: 140, 2
   size: 246, 76
   orig: 246, 76
   offset: 0, 0
   index: -1
 hoverboard-thruster
-  rotate: true
-  xy: 722, 96
+  rotate: false
+  xy: 987, 167
   size: 30, 32
   orig: 30, 32
   offset: 0, 0
   index: -1
 hoverglow-small
   rotate: false
-  xy: 275, 81
+  xy: 828, 103
   size: 137, 38
   orig: 137, 38
   offset: 0, 0
   index: -1
 mouth-grind
   rotate: false
-  xy: 614, 97
+  xy: 365, 41
   size: 47, 30
   orig: 47, 30
   offset: 0, 0
   index: -1
 mouth-oooo
   rotate: false
-  xy: 612, 65
+  xy: 602, 40
   size: 47, 30
   orig: 47, 30
   offset: 0, 0
   index: -1
 mouth-smile
   rotate: false
-  xy: 661, 64
+  xy: 651, 40
   size: 47, 30
   orig: 47, 30
   offset: 0, 0
   index: -1
 muzzle-glow
   rotate: false
-  xy: 382, 54
+  xy: 976, 42
   size: 25, 25
   orig: 25, 25
   offset: 0, 0
   index: -1
 muzzle-ring
   rotate: true
-  xy: 275, 54
+  xy: 799, 76
   size: 25, 105
   orig: 25, 105
   offset: 0, 0
   index: -1
 muzzle01
-  rotate: true
-  xy: 911, 95
+  rotate: false
+  xy: 365, 73
   size: 67, 40
   orig: 67, 40
   offset: 0, 0
   index: -1
 muzzle02
   rotate: false
-  xy: 792, 108
+  xy: 295, 71
   size: 68, 42
   orig: 68, 42
   offset: 0, 0
   index: -1
 muzzle03
   rotate: true
-  xy: 956, 171
+  xy: 932, 165
   size: 83, 53
   orig: 83, 53
   offset: 0, 0
   index: -1
 muzzle04
   rotate: false
-  xy: 275, 7
+  xy: 218, 68
   size: 75, 45
   orig: 75, 45
   offset: 0, 0
   index: -1
 muzzle05
   rotate: false
-  xy: 140, 3
+  xy: 906, 63
   size: 68, 38
   orig: 68, 38
   offset: 0, 0
   index: -1
 neck
   rotate: false
-  xy: 250, 182
+  xy: 1003, 46
   size: 18, 21
   orig: 18, 21
   offset: 0, 0
   index: -1
 portal-bg
   rotate: false
-  xy: 140, 43
+  xy: 218, 115
   size: 133, 133
   orig: 133, 133
   offset: 0, 0
   index: -1
 portal-flare1
   rotate: false
-  xy: 554, 65
+  xy: 767, 44
   size: 56, 30
   orig: 56, 30
   offset: 0, 0
   index: -1
 portal-flare2
-  rotate: true
-  xy: 759, 112
+  rotate: false
+  xy: 483, 44
   size: 57, 31
   orig: 57, 31
   offset: 0, 0
   index: -1
 portal-flare3
   rotate: false
-  xy: 554, 97
+  xy: 542, 45
   size: 58, 30
   orig: 58, 30
   offset: 0, 0
   index: -1
 portal-shade
   rotate: false
-  xy: 275, 121
+  xy: 353, 115
   size: 133, 133
   orig: 133, 133
   offset: 0, 0
   index: -1
 portal-streaks1
   rotate: false
-  xy: 410, 126
+  xy: 488, 120
   size: 126, 128
   orig: 126, 128
   offset: 0, 0
   index: -1
 portal-streaks2
   rotate: false
-  xy: 538, 129
+  xy: 616, 123
   size: 125, 125
   orig: 125, 125
   offset: 0, 0
   index: -1
 rear-bracer
   rotate: false
-  xy: 857, 67
+  xy: 295, 33
   size: 28, 36
   orig: 28, 36
   offset: 0, 0
   index: -1
 rear-foot
   rotate: false
-  xy: 663, 96
+  xy: 708, 45
   size: 57, 30
   orig: 57, 30
   offset: 0, 0
   index: -1
 rear-shin
   rotate: true
-  xy: 414, 86
+  xy: 708, 77
   size: 38, 89
   orig: 38, 89
   offset: 0, 0
   index: -1
 rear-thigh
   rotate: false
-  xy: 756, 63
+  xy: 987, 201
   size: 28, 47
   orig: 28, 47
   offset: 0, 0
   index: -1
 rear-upper-arm
-  rotate: true
-  xy: 60, 5
+  rotate: false
+  xy: 325, 25
   size: 20, 44
   orig: 20, 44
   offset: 0, 0
   index: -1
 torso
-  rotate: false
-  xy: 905, 164
+  rotate: true
+  xy: 616, 72
   size: 49, 90
   orig: 49, 90
   offset: 0, 0

BIN
spine-ts/player/example/assets/spineboy-pma.png


Разница между файлами не показана из-за своего большого размера
+ 85 - 103
spine-ts/player/example/assets/spineboy-pro.json


Разница между файлами не показана из-за своего большого размера
+ 73 - 74
spine-ts/threejs/example/assets/raptor-pro.json


+ 58 - 58
spine-ts/threejs/example/assets/raptor.atlas

@@ -6,266 +6,266 @@ filter: Linear,Linear
 repeat: none
 back-arm
   rotate: false
-  xy: 895, 295
+  xy: 518, 9
   size: 46, 25
   orig: 46, 25
   offset: 0, 0
   index: -1
 back-bracer
-  rotate: true
-  xy: 992, 216
+  rotate: false
+  xy: 566, 6
   size: 39, 28
   orig: 39, 28
   offset: 0, 0
   index: -1
 back-hand
   rotate: false
-  xy: 594, 58
+  xy: 663, 5
   size: 36, 34
   orig: 36, 34
   offset: 0, 0
   index: -1
 back-knee
-  rotate: true
-  xy: 729, 86
+  rotate: false
+  xy: 801, 47
   size: 49, 67
   orig: 49, 67
   offset: 0, 0
   index: -1
 back-thigh
   rotate: false
-  xy: 379, 2
+  xy: 279, 9
   size: 39, 24
   orig: 39, 24
   offset: 0, 0
   index: -1
 eyes-open
-  rotate: true
-  xy: 902, 194
+  rotate: false
+  xy: 955, 3
   size: 47, 45
   orig: 47, 45
   offset: 0, 0
   index: -1
 front-arm
   rotate: false
-  xy: 945, 306
+  xy: 613, 13
   size: 48, 26
   orig: 48, 26
   offset: 0, 0
   index: -1
 front-bracer
   rotate: false
-  xy: 949, 197
+  xy: 475, 5
   size: 41, 29
   orig: 41, 29
   offset: 0, 0
   index: -1
 front-hand
   rotate: false
-  xy: 949, 266
+  xy: 977, 344
   size: 41, 38
   orig: 41, 38
   offset: 0, 0
   index: -1
 front-open-hand
   rotate: false
-  xy: 875, 148
+  xy: 977, 434
   size: 43, 44
   orig: 43, 44
   offset: 0, 0
   index: -1
 front-thigh
-  rotate: true
-  xy: 793, 171
+  rotate: false
+  xy: 367, 11
   size: 57, 29
   orig: 57, 29
   offset: 0, 0
   index: -1
 gun
-  rotate: true
-  xy: 379, 28
+  rotate: false
+  xy: 506, 140
   size: 107, 103
   orig: 107, 103
   offset: 0, 0
   index: -1
 gun-nohand
   rotate: false
-  xy: 487, 87
+  xy: 506, 36
   size: 105, 102
   orig: 105, 102
   offset: 0, 0
   index: -1
 head
   rotate: false
-  xy: 807, 361
+  xy: 853, 136
   size: 136, 149
   orig: 136, 149
   offset: 0, 0
   index: -1
 lower-leg
-  rotate: false
-  xy: 827, 195
+  rotate: true
+  xy: 613, 41
   size: 73, 98
   orig: 73, 98
   offset: 0, 0
   index: -1
 mouth-grind
-  rotate: true
-  xy: 920, 145
+  rotate: false
+  xy: 801, 15
   size: 47, 30
   orig: 47, 30
   offset: 0, 0
   index: -1
 mouth-smile
-  rotate: true
-  xy: 992, 257
+  rotate: false
+  xy: 426, 10
   size: 47, 30
   orig: 47, 30
   offset: 0, 0
   index: -1
 neck
   rotate: false
-  xy: 359, 114
+  xy: 991, 275
   size: 18, 21
   orig: 18, 21
   offset: 0, 0
   index: -1
 raptor-back-arm
-  rotate: false
-  xy: 653, 142
+  rotate: true
+  xy: 713, 32
   size: 82, 86
   orig: 82, 86
   offset: 0, 0
   index: -1
 raptor-body
   rotate: false
-  xy: 2, 277
+  xy: 2, 245
   size: 632, 233
   orig: 632, 233
   offset: 0, 0
   index: -1
 raptor-front-arm
   rotate: true
-  xy: 484, 4
+  xy: 175, 34
   size: 81, 102
   orig: 81, 102
   offset: 0, 0
   index: -1
 raptor-front-leg
-  rotate: false
-  xy: 2, 18
+  rotate: true
+  xy: 636, 287
   size: 191, 257
   orig: 191, 257
   offset: 0, 0
   index: -1
 raptor-hindleg-back
-  rotate: false
-  xy: 636, 295
+  rotate: true
+  xy: 636, 116
   size: 169, 215
   orig: 169, 215
   offset: 0, 0
   index: -1
 raptor-horn
-  rotate: false
-  xy: 195, 22
+  rotate: true
+  xy: 895, 296
   size: 182, 80
   orig: 182, 80
   offset: 0, 0
   index: -1
 raptor-horn-back
-  rotate: true
-  xy: 945, 334
+  rotate: false
+  xy: 315, 166
   size: 176, 77
   orig: 176, 77
   offset: 0, 0
   index: -1
 raptor-jaw
-  rotate: false
-  xy: 359, 137
+  rotate: true
+  xy: 175, 117
   size: 126, 138
   orig: 126, 138
   offset: 0, 0
   index: -1
 raptor-jaw-tooth
-  rotate: true
-  xy: 895, 322
+  rotate: false
+  xy: 977, 384
   size: 37, 48
   orig: 37, 48
   offset: 0, 0
   index: -1
 raptor-mouth-inside
-  rotate: true
-  xy: 949, 228
+  rotate: false
+  xy: 464, 58
   size: 36, 41
   orig: 36, 41
   offset: 0, 0
   index: -1
 raptor-saddle-strap-back
   rotate: true
-  xy: 653, 86
+  xy: 95, 25
   size: 54, 74
   orig: 54, 74
   offset: 0, 0
   index: -1
 raptor-saddle-strap-front
-  rotate: false
-  xy: 594, 94
+  rotate: true
+  xy: 367, 42
   size: 57, 95
   orig: 57, 95
   offset: 0, 0
   index: -1
 raptor-saddle-w-shadow
-  rotate: false
-  xy: 195, 104
+  rotate: true
+  xy: 2, 81
   size: 162, 171
   orig: 162, 171
   offset: 0, 0
   index: -1
 raptor-tail-shadow
   rotate: false
-  xy: 636, 230
+  xy: 315, 101
   size: 189, 63
   orig: 189, 63
   offset: 0, 0
   index: -1
 raptor-tongue
   rotate: false
-  xy: 807, 295
+  xy: 279, 35
   size: 86, 64
   orig: 86, 64
   offset: 0, 0
   index: -1
 stirrup-back
   rotate: true
-  xy: 952, 151
+  xy: 977, 298
   size: 44, 35
   orig: 44, 35
   offset: 0, 0
   index: -1
 stirrup-front
-  rotate: false
-  xy: 902, 243
+  rotate: true
+  xy: 903, 3
   size: 45, 50
   orig: 45, 50
   offset: 0, 0
   index: -1
 stirrup-strap
   rotate: false
-  xy: 824, 147
+  xy: 852, 2
   size: 49, 46
   orig: 49, 46
   offset: 0, 0
   index: -1
 torso
-  rotate: false
-  xy: 737, 137
+  rotate: true
+  xy: 2, 25
   size: 54, 91
   orig: 54, 91
   offset: 0, 0
   index: -1
 visor
   rotate: false
-  xy: 487, 191
+  xy: 853, 50
   size: 131, 84
   orig: 131, 84
   offset: 0, 0

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


+ 1 - 0
spine-ts/threejs/src/SkeletonMesh.ts

@@ -147,6 +147,7 @@ module spine.threejs {
 			for (let i = 0, n = drawOrder.length; i < n; i++) {
 				let vertexSize = clipper.isClipping() ? 2 : SkeletonMesh.VERTEX_SIZE;
 				let slot = drawOrder[i];
+				if (!slot.bone.active) continue;
 				let attachment = slot.getAttachment();
 				let attachmentColor: Color = null;
 				let texture: ThreeJsTexture = null;

+ 9 - 9
spine-ts/webgl/example/assets/coin-pma.atlas

@@ -6,49 +6,49 @@ filter: Linear,Linear
 repeat: none
 coin-front-logo
   rotate: false
-  xy: 2, 609
+  xy: 2, 266
   size: 305, 302
   orig: 305, 302
   offset: 0, 0
   index: -1
 coin-front-shine-logo
   rotate: false
-  xy: 309, 629
+  xy: 616, 286
   size: 282, 282
   orig: 282, 282
   offset: 0, 0
   index: -1
 coin-front-shine-spineboy
   rotate: false
-  xy: 2, 21
+  xy: 616, 2
   size: 282, 282
   orig: 282, 282
   offset: 0, 0
   index: -1
 coin-front-spineboy
   rotate: false
-  xy: 2, 305
+  xy: 309, 266
   size: 305, 302
   orig: 305, 302
   offset: 0, 0
   index: -1
 coin-side-round
-  rotate: false
-  xy: 309, 345
+  rotate: true
+  xy: 2, 120
   size: 144, 282
   orig: 144, 282
   offset: 0, 0
   index: -1
 coin-side-straight
   rotate: true
-  xy: 2, 2
+  xy: 286, 173
   size: 17, 282
   orig: 17, 282
   offset: 0, 0
   index: -1
 shine
-  rotate: false
-  xy: 593, 666
+  rotate: true
+  xy: 286, 192
   size: 72, 245
   orig: 72, 245
   offset: 0, 0

BIN
spine-ts/webgl/example/assets/coin-pma.png


+ 75 - 181
spine-ts/webgl/example/assets/coin-pro.json

@@ -1,7 +1,7 @@
 {
 "skeleton": {
-	"hash": "MYibQXspGhD4XDqbsmKCI3XfquU",
-	"spine": "3.8.05-beta",
+	"hash": "0H+pv527+rRzP6WoyKyXdHVJU6g",
+	"spine": "3.8.13-beta",
 	"x": -152.5,
 	"y": -151,
 	"width": 305,
@@ -26,42 +26,45 @@
 	{ "name": "clipping", "bone": "clipping", "attachment": "clipping" },
 	{ "name": "shine", "bone": "shine", "color": "ffffff60", "attachment": "shine", "blend": "additive" }
 ],
-"skins": {
-	"default": {
-		"clipping": {
+"skins": [
+	{
+		"name": "default",
+		"attachments": {
 			"clipping": {
-				"type": "clipping",
-				"end": "clipping",
-				"vertexCount": 39,
-				"vertices": [ 0.1, 140.26, -26.4, 138.14, -50.51, 131.25, -75.42, 119.06, -98.21, 101.04, -115.44, 82.22, -127.63, 62.08, -136.11, 39.03, -140.08, 19.68, -141.41, -0.19, -140.08, -22.98, -134.78, -45.5, -125.24, -66.44, -113.32, -84.19, -98.21, -101.95, -80.46, -116.52, -61.38, -127.39, -38.92, -134.81, -18.22, -139.27, -0.14, -140.58, 24.23, -138.48, 45.45, -132.46, 67.98, -122.5, 86.58, -110.19, 102.56, -95.25, 115.4, -78.75, 125.36, -61.72, 134, -42.33, 138.46, -22.15, 139.24, -0.15, 138.46, 20.29, 133.48, 39.94, 127.19, 58.54, 117.5, 76.1, 104.4, 92.86, 88.42, 108.32, 69.03, 121.42, 50.43, 130.85, 26.32, 137.4 ],
-				"color": "ce3a3aff"
+				"clipping": {
+					"type": "clipping",
+					"end": "clipping",
+					"vertexCount": 39,
+					"vertices": [ 0.1, 140.26, -26.4, 138.14, -50.51, 131.25, -75.42, 119.06, -98.21, 101.04, -115.44, 82.22, -127.63, 62.08, -136.11, 39.03, -140.08, 19.68, -141.41, -0.19, -140.08, -22.98, -134.78, -45.5, -125.24, -66.44, -113.32, -84.19, -98.21, -101.95, -80.46, -116.52, -61.38, -127.39, -38.92, -134.81, -18.22, -139.27, -0.14, -140.58, 24.23, -138.48, 45.45, -132.46, 67.98, -122.5, 86.58, -110.19, 102.56, -95.25, 115.4, -78.75, 125.36, -61.72, 134, -42.33, 138.46, -22.15, 139.24, -0.15, 138.46, 20.29, 133.48, 39.94, 127.19, 58.54, 117.5, 76.1, 104.4, 92.86, 88.42, 108.32, 69.03, 121.42, 50.43, 130.85, 26.32, 137.4 ],
+					"color": "ce3a3aff"
+				}
+			},
+			"coin-front-shine": {
+				"coin-front-shine-logo": { "width": 282, "height": 282 },
+				"coin-front-shine-spineboy": { "width": 282, "height": 282 }
+			},
+			"coin-front-texture": {
+				"coin-front-logo": { "width": 305, "height": 302 },
+				"coin-front-spineboy": { "width": 305, "height": 302 }
+			},
+			"coin-side": {
+				"coin-side-straight": { "x": 0.5, "width": 17, "height": 282 }
+			},
+			"coin-side-round": {
+				"coin-side-round": { "x": -69.43, "width": 144, "height": 282 }
+			},
+			"shine": {
+				"shine": { "y": 0.5, "scaleX": 1.6004, "scaleY": 1.6004, "width": 72, "height": 245 }
 			}
-		},
-		"coin-front-shine": {
-			"coin-front-shine-logo": { "width": 282, "height": 282 },
-			"coin-front-shine-spineboy": { "width": 282, "height": 282 }
-		},
-		"coin-front-texture": {
-			"coin-front-logo": { "width": 305, "height": 302 },
-			"coin-front-spineboy": { "width": 305, "height": 302 }
-		},
-		"coin-side": {
-			"coin-side-straight": { "x": 0.5, "width": 17, "height": 282 }
-		},
-		"coin-side-round": {
-			"coin-side-round": { "x": -69.43, "width": 144, "height": 282 }
-		},
-		"shine": {
-			"shine": { "y": 0.5, "scaleX": 1.6, "scaleY": 1.6, "width": 72, "height": 245 }
 		}
 	}
-},
+],
 "animations": {
 	"animation": {
 		"slots": {
 			"coin-front-shine": {
 				"twoColor": [
-					{ "time": 0, "light": "7d7d7dff", "dark": "000000" },
+					{ "light": "7d7d7dff", "dark": "000000" },
 					{ "time": 0.2667, "light": "000000ff", "dark": "7e7e7e" },
 					{ "time": 0.664, "light": "000000ff", "dark": "000000" },
 					{ "time": 1.0333, "light": "7f7f7fff", "dark": "000000" },
@@ -78,13 +81,9 @@
 			},
 			"coin-front-texture": {
 				"color": [
-					{ "time": 0, "color": "858585ff" },
+					{ "color": "858585ff" },
 					{ "time": 0.4, "color": "ffffffff" },
-					{
-						"time": 0.6696,
-						"color": "858585ff",
-						"curve": [ 0.188, 0.15, 0.75, 1 ]
-					},
+					{ "time": 0.6696, "color": "858585ff", "curve": 0.188, "c2": 0.15, "c3": 0.75 },
 					{ "time": 0.9667, "color": "ffffffff" },
 					{ "time": 1.3318, "color": "858585ff", "curve": "stepped" },
 					{ "time": 1.3333, "color": "858585ff" },
@@ -103,164 +102,59 @@
 		"bones": {
 			"coin-front": {
 				"translate": [
-					{ "time": 0, "x": 0, "y": 0 },
-					{ "time": 0.664, "x": 8.3, "y": 0, "curve": "stepped" },
-					{
-						"time": 0.6696,
-						"x": -8.3,
-						"y": 0,
-						"curve": [ 0.188, 0.15, 0.75, 1 ]
-					},
-					{ "time": 1.3333, "x": 0, "y": 0 },
-					{ "time": 1.9982, "x": 8.3, "y": 0, "curve": "stepped" },
-					{ "time": 2.0022, "x": -8.3, "y": 0 },
-					{ "time": 2.6667, "x": 0, "y": 0 }
+					{},
+					{ "time": 0.664, "x": 8.3, "curve": "stepped" },
+					{ "time": 0.6696, "x": -8.3, "curve": 0.188, "c2": 0.15, "c3": 0.75 },
+					{ "time": 1.3333 },
+					{ "time": 1.9982, "x": 8.3, "curve": "stepped" },
+					{ "time": 2.0022, "x": -8.3 },
+					{ "time": 2.6667 }
 				],
 				"scale": [
-					{
-						"time": 0,
-						"x": 1,
-						"y": 1,
-						"curve": [ 0.247, 0, 0.729, 0.91 ]
-					},
-					{ "time": 0.664, "x": 0, "y": 1, "curve": "stepped" },
-					{
-						"time": 0.6696,
-						"x": 0.003,
-						"y": 1,
-						"curve": [ 0.175, 0.15, 0.75, 1 ]
-					},
-					{
-						"time": 1.3333,
-						"x": 1,
-						"y": 1,
-						"curve": [ 0.163, 0.01, 0.789, 0.9 ]
-					},
-					{ "time": 1.9982, "x": 0.003, "y": 1, "curve": "stepped" },
-					{
-						"time": 2.0022,
-						"x": 0.003,
-						"y": 1,
-						"curve": [ 0.182, 0.15, 0.75, 1 ]
-					},
-					{ "time": 2.6667, "x": 1, "y": 1 }
+					{ "curve": 0.247, "c3": 0.729, "c4": 0.91 },
+					{ "time": 0.664, "x": 0, "curve": "stepped" },
+					{ "time": 0.6696, "x": 0.003, "curve": 0.175, "c2": 0.15, "c3": 0.75 },
+					{ "time": 1.3333, "curve": 0.163, "c2": 0.01, "c3": 0.789, "c4": 0.9 },
+					{ "time": 1.9982, "x": 0.003, "curve": "stepped" },
+					{ "time": 2.0022, "x": 0.003, "curve": 0.182, "c2": 0.15, "c3": 0.75 },
+					{ "time": 2.6667 }
 				]
 			},
 			"coin-side-round": {
 				"translate": [
-					{ "time": 0, "x": 0, "y": 0 },
-					{ "time": 0.664, "x": -6.75, "y": 0, "curve": "stepped" },
-					{
-						"time": 0.6696,
-						"x": 7.03,
-						"y": 0,
-						"curve": [ 0.188, 0.15, 0.75, 1 ]
-					},
-					{ "time": 1.3333, "x": 0, "y": 0 },
-					{ "time": 1.9982, "x": -6.75, "y": 0, "curve": "stepped" },
-					{ "time": 2.0022, "x": 7.03, "y": 0 },
-					{ "time": 2.6667, "x": 0, "y": 0 }
+					{},
+					{ "time": 0.664, "x": -6.75, "curve": "stepped" },
+					{ "time": 0.6696, "x": 7.03, "curve": 0.188, "c2": 0.15, "c3": 0.75 },
+					{ "time": 1.3333 },
+					{ "time": 1.9982, "x": -6.75, "curve": "stepped" },
+					{ "time": 2.0022, "x": 7.03 },
+					{ "time": 2.6667 }
 				],
 				"scale": [
-					{
-						"time": 0,
-						"x": 1,
-						"y": 1,
-						"curve": [ 0.254, 0, 0.621, 0.47 ]
-					},
-					{
-						"time": 0.3333,
-						"x": 0.555,
-						"y": 1,
-						"curve": [ 0.349, 0.38, 0.707, 0.8 ]
-					},
-					{ "time": 0.664, "x": 0.014, "y": 1, "curve": "stepped" },
-					{
-						"time": 0.6696,
-						"x": -0.028,
-						"y": 1,
-						"curve": [ 0.163, 0.17, 0.59, 0.58 ]
-					},
-					{
-						"time": 1,
-						"x": -0.609,
-						"y": 1,
-						"curve": [ 0.158, 0.43, 0.875, 0.99 ]
-					},
-					{ "time": 1.3318, "x": -1, "y": 1, "curve": "stepped" },
-					{
-						"time": 1.3333,
-						"x": 1,
-						"y": 1,
-						"curve": [ 0.306, 0.02, 0.636, 0.41 ]
-					},
-					{
-						"time": 1.5,
-						"x": 0.852,
-						"y": 1,
-						"curve": [ 0.212, 0.19, 0.678, 0.64 ]
-					},
-					{
-						"time": 1.8,
-						"x": 0.315,
-						"y": 1,
-						"curve": [ 0.366, 0.62, 0.942, 1 ]
-					},
-					{ "time": 1.9982, "x": 0.014, "y": 1, "curve": "stepped" },
-					{
-						"time": 2.0022,
-						"x": -0.028,
-						"y": 1,
-						"curve": [ 0.184, 0.13, 0.604, 0.63 ]
-					},
-					{
-						"time": 2.2018,
-						"x": -0.365,
-						"y": 1,
-						"curve": [ 0.34, 0.4, 0.683, 0.74 ]
-					},
-					{
-						"time": 2.4,
-						"x": -0.731,
-						"y": 1,
-						"curve": [ 0.399, 0.52, 0.754, 0.86 ]
-					},
-					{
-						"time": 2.6592,
-						"x": -1,
-						"y": 1,
-						"curve": [ 0.25, 0, 0.75, 1 ]
-					},
-					{ "time": 2.6667, "x": 1, "y": 1 }
+					{ "curve": 0.254, "c3": 0.621, "c4": 0.47 },
+					{ "time": 0.3333, "x": 0.555, "curve": 0.349, "c2": 0.38, "c3": 0.707, "c4": 0.8 },
+					{ "time": 0.664, "x": 0.014, "curve": "stepped" },
+					{ "time": 0.6696, "x": -0.028, "curve": 0.163, "c2": 0.17, "c3": 0.59, "c4": 0.58 },
+					{ "time": 1, "x": -0.609, "curve": 0.158, "c2": 0.43, "c3": 0.875, "c4": 0.99 },
+					{ "time": 1.3318, "x": -1, "curve": "stepped" },
+					{ "time": 1.3333, "curve": 0.306, "c2": 0.02, "c3": 0.636, "c4": 0.41 },
+					{ "time": 1.5, "x": 0.852, "curve": 0.212, "c2": 0.19, "c3": 0.678, "c4": 0.64 },
+					{ "time": 1.8, "x": 0.315, "curve": 0.366, "c2": 0.62, "c3": 0.942 },
+					{ "time": 1.9982, "x": 0.014, "curve": "stepped" },
+					{ "time": 2.0022, "x": -0.028, "curve": 0.184, "c2": 0.13, "c3": 0.604, "c4": 0.63 },
+					{ "time": 2.2018, "x": -0.365, "curve": 0.34, "c2": 0.4, "c3": 0.683, "c4": 0.74 },
+					{ "time": 2.4, "x": -0.731, "curve": 0.399, "c2": 0.52, "c3": 0.754, "c4": 0.86 },
+					{ "time": 2.6592, "x": -1, "curve": 0.25, "c3": 0.75 },
+					{ "time": 2.6667 }
 				]
 			},
 			"shine": {
 				"translate": [
-					{
-						"time": 0,
-						"x": 0,
-						"y": 0,
-						"curve": [ 0.25, 0, 0.75, 1 ]
-					},
-					{
-						"time": 0.6667,
-						"x": -473.39,
-						"y": 0,
-						"curve": [ 0.25, 0, 0.75, 1 ]
-					},
-					{
-						"time": 1.3333,
-						"x": -33.16,
-						"y": 0,
-						"curve": [ 0.25, 0, 0.75, 1 ]
-					},
-					{
-						"time": 2,
-						"x": -473.39,
-						"y": 0,
-						"curve": [ 0.25, 0, 0.75, 1 ]
-					},
-					{ "time": 2.6667, "x": 0, "y": 0 }
+					{ "curve": 0.25, "c3": 0.75 },
+					{ "time": 0.6667, "x": -473.39, "curve": 0.25, "c3": 0.75 },
+					{ "time": 1.3333, "x": -33.16, "curve": 0.25, "c3": 0.75 },
+					{ "time": 2, "x": -473.39, "curve": 0.25, "c3": 0.75 },
+					{ "time": 2.6667 }
 				]
 			}
 		},

+ 60 - 60
spine-ts/webgl/example/assets/goblins-pma.atlas

@@ -6,280 +6,280 @@ filter: Linear,Linear
 repeat: none
 dagger
   rotate: true
-  xy: 372, 100
+  xy: 477, 26
   size: 26, 108
   orig: 26, 108
   offset: 0, 0
   index: -1
 goblin/eyes-closed
   rotate: false
-  xy: 2, 7
+  xy: 282, 12
   size: 34, 12
   orig: 34, 12
   offset: 0, 0
   index: -1
 goblin/head
   rotate: false
-  xy: 107, 36
+  xy: 2, 36
   size: 103, 66
   orig: 103, 66
   offset: 0, 0
   index: -1
 goblin/left-arm
   rotate: false
-  xy: 901, 56
+  xy: 782, 19
   size: 37, 35
   orig: 37, 35
   offset: 0, 0
   index: -1
 goblin/left-foot
-  rotate: false
-  xy: 929, 95
+  rotate: true
+  xy: 962, 61
   size: 65, 31
   orig: 65, 31
   offset: 0, 0
   index: -1
 goblin/left-hand
   rotate: false
-  xy: 452, 2
+  xy: 669, 21
   size: 36, 41
   orig: 36, 41
   offset: 0, 0
   index: -1
 goblin/left-lower-leg
-  rotate: true
-  xy: 713, 93
+  rotate: false
+  xy: 549, 56
   size: 33, 70
   orig: 33, 70
   offset: 0, 0
   index: -1
 goblin/left-shoulder
   rotate: false
-  xy: 610, 44
+  xy: 890, 17
   size: 29, 44
   orig: 29, 44
   offset: 0, 0
   index: -1
 goblin/left-upper-leg
-  rotate: true
-  xy: 638, 93
+  rotate: false
+  xy: 715, 53
   size: 33, 73
   orig: 33, 73
   offset: 0, 0
   index: -1
 goblin/neck
   rotate: false
-  xy: 490, 2
+  xy: 707, 10
   size: 36, 41
   orig: 36, 41
   offset: 0, 0
   index: -1
 goblin/pelvis
-  rotate: false
-  xy: 482, 45
+  rotate: true
+  xy: 625, 64
   size: 62, 43
   orig: 62, 43
   offset: 0, 0
   index: -1
 goblin/right-arm
-  rotate: true
-  xy: 690, 2
+  rotate: false
+  xy: 921, 11
   size: 23, 50
   orig: 23, 50
   offset: 0, 0
   index: -1
 goblin/right-foot
-  rotate: false
-  xy: 771, 58
+  rotate: true
+  xy: 892, 63
   size: 63, 33
   orig: 63, 33
   offset: 0, 0
   index: -1
 goblin/right-hand
   rotate: false
-  xy: 940, 56
+  xy: 378, 6
   size: 36, 37
   orig: 36, 37
   offset: 0, 0
   index: -1
 goblin/right-lower-leg
-  rotate: true
-  xy: 482, 90
+  rotate: false
+  xy: 303, 26
   size: 36, 76
   orig: 36, 76
   offset: 0, 0
   index: -1
 goblin/right-shoulder
-  rotate: true
-  xy: 602, 3
+  rotate: false
+  xy: 587, 3
   size: 39, 45
   orig: 39, 45
   offset: 0, 0
   index: -1
 goblin/right-upper-leg
-  rotate: true
-  xy: 641, 57
+  rotate: false
+  xy: 820, 63
   size: 34, 63
   orig: 34, 63
   offset: 0, 0
   index: -1
 goblin/torso
   rotate: true
-  xy: 212, 34
+  xy: 107, 34
   size: 68, 96
   orig: 68, 96
   offset: 0, 0
   index: -1
 goblin/undie-straps
   rotate: false
-  xy: 380, 5
+  xy: 69, 13
   size: 55, 19
   orig: 55, 19
   offset: 0, 0
   index: -1
 goblin/undies
-  rotate: false
-  xy: 174, 5
+  rotate: true
+  xy: 946, 23
   size: 36, 29
   orig: 36, 29
   offset: 0, 0
   index: -1
 goblingirl/eyes-closed
   rotate: false
-  xy: 269, 11
+  xy: 243, 11
   size: 37, 21
   orig: 37, 21
   offset: 0, 0
   index: -1
 goblingirl/head
   rotate: false
-  xy: 2, 21
+  xy: 372, 45
   size: 103, 81
   orig: 103, 81
   offset: 0, 0
   index: -1
 goblingirl/left-arm
-  rotate: true
-  xy: 978, 56
+  rotate: false
+  xy: 821, 26
   size: 37, 35
   orig: 37, 35
   offset: 0, 0
   index: -1
 goblingirl/left-foot
   rotate: false
-  xy: 107, 3
+  xy: 2, 3
   size: 65, 31
   orig: 65, 31
   offset: 0, 0
   index: -1
 goblingirl/left-hand
   rotate: false
-  xy: 565, 2
+  xy: 341, 3
   size: 35, 40
   orig: 35, 40
   offset: 0, 0
   index: -1
 goblingirl/left-lower-leg
-  rotate: true
-  xy: 785, 93
+  rotate: false
+  xy: 750, 56
   size: 33, 70
   orig: 33, 70
   offset: 0, 0
   index: -1
 goblingirl/left-shoulder
-  rotate: true
-  xy: 690, 27
+  rotate: false
+  xy: 860, 15
   size: 28, 46
   orig: 28, 46
   offset: 0, 0
   index: -1
 goblingirl/left-upper-leg
-  rotate: true
-  xy: 857, 93
+  rotate: false
+  xy: 785, 56
   size: 33, 70
   orig: 33, 70
   offset: 0, 0
   index: -1
 goblingirl/neck
   rotate: false
-  xy: 528, 2
+  xy: 745, 10
   size: 35, 41
   orig: 35, 41
   offset: 0, 0
   index: -1
 goblingirl/pelvis
-  rotate: false
-  xy: 546, 45
+  rotate: true
+  xy: 670, 64
   size: 62, 43
   orig: 62, 43
   offset: 0, 0
   index: -1
 goblingirl/right-arm
   rotate: false
-  xy: 452, 48
+  xy: 341, 52
   size: 28, 50
   orig: 28, 50
   offset: 0, 0
   index: -1
 goblingirl/right-foot
-  rotate: false
-  xy: 836, 58
+  rotate: true
+  xy: 927, 63
   size: 63, 33
   orig: 63, 33
   offset: 0, 0
   index: -1
 goblingirl/right-hand
-  rotate: true
-  xy: 771, 20
+  rotate: false
+  xy: 416, 6
   size: 36, 37
   orig: 36, 37
   offset: 0, 0
   index: -1
 goblingirl/right-lower-leg
-  rotate: true
-  xy: 560, 90
+  rotate: false
+  xy: 587, 50
   size: 36, 76
   orig: 36, 76
   offset: 0, 0
   index: -1
 goblingirl/right-shoulder
   rotate: false
-  xy: 649, 10
+  xy: 628, 17
   size: 39, 45
   orig: 39, 45
   offset: 0, 0
   index: -1
 goblingirl/right-upper-leg
-  rotate: true
-  xy: 706, 57
+  rotate: false
+  xy: 856, 63
   size: 34, 63
   orig: 34, 63
   offset: 0, 0
   index: -1
 goblingirl/torso
-  rotate: false
-  xy: 310, 2
+  rotate: true
+  xy: 205, 34
   size: 68, 96
   orig: 68, 96
   offset: 0, 0
   index: -1
 goblingirl/undie-straps
   rotate: false
-  xy: 212, 13
+  xy: 126, 13
   size: 55, 19
   orig: 55, 19
   offset: 0, 0
   index: -1
 goblingirl/undies
   rotate: false
-  xy: 810, 27
+  xy: 205, 3
   size: 36, 29
   orig: 36, 29
   offset: 0, 0
   index: -1
 shield
   rotate: false
-  xy: 380, 26
+  xy: 477, 54
   size: 70, 72
   orig: 70, 72
   offset: 0, 0

BIN
spine-ts/webgl/example/assets/goblins-pma.png


Разница между файлами не показана из-за своего большого размера
+ 382 - 474
spine-ts/webgl/example/assets/goblins-pro.json


+ 35 - 35
spine-ts/webgl/example/assets/owl-pma.atlas

@@ -6,189 +6,189 @@ filter: Linear,Linear
 repeat: none
 L_eye-closed
   rotate: false
-  xy: 508, 115
+  xy: 114, 106
   size: 90, 86
   orig: 90, 86
   offset: 0, 0
   index: -1
 L_eye-iris
   rotate: false
-  xy: 826, 183
+  xy: 206, 106
   size: 90, 86
   orig: 90, 86
   offset: 0, 0
   index: -1
 L_eye-light
   rotate: false
-  xy: 1001, 488
+  xy: 983, 230
   size: 21, 20
   orig: 21, 20
   offset: 0, 0
   index: -1
 L_eye-pupil
   rotate: false
-  xy: 752, 154
+  xy: 939, 294
   size: 63, 60
   orig: 63, 60
   offset: 0, 0
   index: -1
 L_foot
   rotate: false
-  xy: 817, 133
+  xy: 307, 56
   size: 64, 48
   orig: 64, 48
   offset: 0, 0
   index: -1
 L_wing
-  rotate: false
-  xy: 342, 91
+  rotate: true
+  xy: 871, 166
   size: 81, 110
   orig: 81, 110
   offset: 0, 0
   index: -1
 R_eye-closed
   rotate: false
-  xy: 508, 27
+  xy: 298, 106
   size: 90, 86
   orig: 90, 86
   offset: 0, 0
   index: -1
 R_eye-iris
-  rotate: true
-  xy: 600, 111
+  rotate: false
+  xy: 390, 106
   size: 90, 86
   orig: 90, 86
   offset: 0, 0
   index: -1
 R_eye-light
   rotate: false
-  xy: 1001, 466
+  xy: 983, 208
   size: 21, 20
   orig: 21, 20
   offset: 0, 0
   index: -1
 R_eye-pupil
-  rotate: true
-  xy: 691, 72
+  rotate: false
+  xy: 181, 44
   size: 63, 60
   orig: 63, 60
   offset: 0, 0
   index: -1
 R_foot
   rotate: false
-  xy: 814, 83
+  xy: 373, 56
   size: 64, 48
   orig: 64, 48
   offset: 0, 0
   index: -1
 R_wing
-  rotate: false
-  xy: 425, 91
+  rotate: true
+  xy: 2, 111
   size: 81, 110
   orig: 81, 110
   offset: 0, 0
   index: -1
 beak
   rotate: false
-  xy: 883, 140
+  xy: 939, 251
   size: 39, 41
   orig: 39, 41
   offset: 0, 0
   index: -1
 beak-down
-  rotate: true
-  xy: 753, 53
+  rotate: false
+  xy: 980, 252
   size: 37, 40
   orig: 37, 40
   offset: 0, 0
   index: -1
 body
   rotate: false
-  xy: 2, 5
+  xy: 621, 2
   size: 248, 196
   orig: 248, 196
   offset: 0, 0
   index: -1
 feather-1
   rotate: false
-  xy: 753, 92
+  xy: 246, 44
   size: 59, 60
   orig: 59, 60
   offset: 0, 0
   index: -1
 feather-2
   rotate: false
-  xy: 688, 137
+  xy: 950, 356
   size: 62, 65
   orig: 62, 65
   offset: 0, 0
   index: -1
 feather-3
-  rotate: true
-  xy: 600, 2
+  rotate: false
+  xy: 950, 423
   size: 56, 76
   orig: 56, 76
   offset: 0, 0
   index: -1
 head-base
-  rotate: false
-  xy: 621, 271
+  rotate: true
+  xy: 621, 200
   size: 299, 237
   orig: 299, 237
   offset: 0, 0
   index: -1
 leaf-1
-  rotate: false
-  xy: 922, 273
+  rotate: true
+  xy: 482, 116
   size: 76, 101
   orig: 76, 101
   offset: 0, 0
   index: -1
 leaf-2
   rotate: true
-  xy: 621, 204
+  xy: 871, 99
   size: 65, 95
   orig: 65, 95
   offset: 0, 0
   index: -1
 leaf-3
   rotate: true
-  xy: 922, 376
+  xy: 860, 249
   size: 132, 77
   orig: 132, 77
   offset: 0, 0
   index: -1
 leaf-4
   rotate: false
-  xy: 600, 60
+  xy: 90, 55
   size: 89, 49
   orig: 89, 49
   offset: 0, 0
   index: -1
 leaf-5
   rotate: true
-  xy: 718, 216
+  xy: 482, 61
   size: 53, 106
   orig: 53, 106
   offset: 0, 0
   index: -1
 leaf-6
   rotate: false
-  xy: 252, 85
+  xy: 860, 383
   size: 88, 116
   orig: 88, 116
   offset: 0, 0
   index: -1
 leaf-7
   rotate: true
-  xy: 252, 29
+  xy: 2, 55
   size: 54, 86
   orig: 54, 86
   offset: 0, 0
   index: -1
 wood
   rotate: false
-  xy: 2, 203
+  xy: 2, 194
   size: 617, 305
   orig: 617, 305
   offset: 0, 0

BIN
spine-ts/webgl/example/assets/owl-pma.png


Разница между файлами не показана из-за своего большого размера
+ 148 - 151
spine-ts/webgl/example/assets/owl-pro.json


+ 58 - 58
spine-ts/webgl/example/assets/raptor-pma.atlas

@@ -6,266 +6,266 @@ filter: Linear,Linear
 repeat: none
 back-arm
   rotate: false
-  xy: 895, 295
+  xy: 518, 9
   size: 46, 25
   orig: 46, 25
   offset: 0, 0
   index: -1
 back-bracer
-  rotate: true
-  xy: 992, 216
+  rotate: false
+  xy: 566, 6
   size: 39, 28
   orig: 39, 28
   offset: 0, 0
   index: -1
 back-hand
   rotate: false
-  xy: 594, 58
+  xy: 663, 5
   size: 36, 34
   orig: 36, 34
   offset: 0, 0
   index: -1
 back-knee
-  rotate: true
-  xy: 729, 86
+  rotate: false
+  xy: 801, 47
   size: 49, 67
   orig: 49, 67
   offset: 0, 0
   index: -1
 back-thigh
   rotate: false
-  xy: 379, 2
+  xy: 279, 9
   size: 39, 24
   orig: 39, 24
   offset: 0, 0
   index: -1
 eyes-open
-  rotate: true
-  xy: 902, 194
+  rotate: false
+  xy: 955, 3
   size: 47, 45
   orig: 47, 45
   offset: 0, 0
   index: -1
 front-arm
   rotate: false
-  xy: 945, 306
+  xy: 613, 13
   size: 48, 26
   orig: 48, 26
   offset: 0, 0
   index: -1
 front-bracer
   rotate: false
-  xy: 949, 197
+  xy: 475, 5
   size: 41, 29
   orig: 41, 29
   offset: 0, 0
   index: -1
 front-hand
   rotate: false
-  xy: 949, 266
+  xy: 977, 344
   size: 41, 38
   orig: 41, 38
   offset: 0, 0
   index: -1
 front-open-hand
   rotate: false
-  xy: 875, 148
+  xy: 977, 434
   size: 43, 44
   orig: 43, 44
   offset: 0, 0
   index: -1
 front-thigh
-  rotate: true
-  xy: 793, 171
+  rotate: false
+  xy: 367, 11
   size: 57, 29
   orig: 57, 29
   offset: 0, 0
   index: -1
 gun
-  rotate: true
-  xy: 379, 28
+  rotate: false
+  xy: 506, 140
   size: 107, 103
   orig: 107, 103
   offset: 0, 0
   index: -1
 gun-nohand
   rotate: false
-  xy: 487, 87
+  xy: 506, 36
   size: 105, 102
   orig: 105, 102
   offset: 0, 0
   index: -1
 head
   rotate: false
-  xy: 807, 361
+  xy: 853, 136
   size: 136, 149
   orig: 136, 149
   offset: 0, 0
   index: -1
 lower-leg
-  rotate: false
-  xy: 827, 195
+  rotate: true
+  xy: 613, 41
   size: 73, 98
   orig: 73, 98
   offset: 0, 0
   index: -1
 mouth-grind
-  rotate: true
-  xy: 920, 145
+  rotate: false
+  xy: 801, 15
   size: 47, 30
   orig: 47, 30
   offset: 0, 0
   index: -1
 mouth-smile
-  rotate: true
-  xy: 992, 257
+  rotate: false
+  xy: 426, 10
   size: 47, 30
   orig: 47, 30
   offset: 0, 0
   index: -1
 neck
   rotate: false
-  xy: 359, 114
+  xy: 991, 275
   size: 18, 21
   orig: 18, 21
   offset: 0, 0
   index: -1
 raptor-back-arm
-  rotate: false
-  xy: 653, 142
+  rotate: true
+  xy: 713, 32
   size: 82, 86
   orig: 82, 86
   offset: 0, 0
   index: -1
 raptor-body
   rotate: false
-  xy: 2, 277
+  xy: 2, 245
   size: 632, 233
   orig: 632, 233
   offset: 0, 0
   index: -1
 raptor-front-arm
   rotate: true
-  xy: 484, 4
+  xy: 175, 34
   size: 81, 102
   orig: 81, 102
   offset: 0, 0
   index: -1
 raptor-front-leg
-  rotate: false
-  xy: 2, 18
+  rotate: true
+  xy: 636, 287
   size: 191, 257
   orig: 191, 257
   offset: 0, 0
   index: -1
 raptor-hindleg-back
-  rotate: false
-  xy: 636, 295
+  rotate: true
+  xy: 636, 116
   size: 169, 215
   orig: 169, 215
   offset: 0, 0
   index: -1
 raptor-horn
-  rotate: false
-  xy: 195, 22
+  rotate: true
+  xy: 895, 296
   size: 182, 80
   orig: 182, 80
   offset: 0, 0
   index: -1
 raptor-horn-back
-  rotate: true
-  xy: 945, 334
+  rotate: false
+  xy: 315, 166
   size: 176, 77
   orig: 176, 77
   offset: 0, 0
   index: -1
 raptor-jaw
-  rotate: false
-  xy: 359, 137
+  rotate: true
+  xy: 175, 117
   size: 126, 138
   orig: 126, 138
   offset: 0, 0
   index: -1
 raptor-jaw-tooth
-  rotate: true
-  xy: 895, 322
+  rotate: false
+  xy: 977, 384
   size: 37, 48
   orig: 37, 48
   offset: 0, 0
   index: -1
 raptor-mouth-inside
-  rotate: true
-  xy: 949, 228
+  rotate: false
+  xy: 464, 58
   size: 36, 41
   orig: 36, 41
   offset: 0, 0
   index: -1
 raptor-saddle-strap-back
   rotate: true
-  xy: 653, 86
+  xy: 95, 25
   size: 54, 74
   orig: 54, 74
   offset: 0, 0
   index: -1
 raptor-saddle-strap-front
-  rotate: false
-  xy: 594, 94
+  rotate: true
+  xy: 367, 42
   size: 57, 95
   orig: 57, 95
   offset: 0, 0
   index: -1
 raptor-saddle-w-shadow
-  rotate: false
-  xy: 195, 104
+  rotate: true
+  xy: 2, 81
   size: 162, 171
   orig: 162, 171
   offset: 0, 0
   index: -1
 raptor-tail-shadow
   rotate: false
-  xy: 636, 230
+  xy: 315, 101
   size: 189, 63
   orig: 189, 63
   offset: 0, 0
   index: -1
 raptor-tongue
   rotate: false
-  xy: 807, 295
+  xy: 279, 35
   size: 86, 64
   orig: 86, 64
   offset: 0, 0
   index: -1
 stirrup-back
   rotate: true
-  xy: 952, 151
+  xy: 977, 298
   size: 44, 35
   orig: 44, 35
   offset: 0, 0
   index: -1
 stirrup-front
-  rotate: false
-  xy: 902, 243
+  rotate: true
+  xy: 903, 3
   size: 45, 50
   orig: 45, 50
   offset: 0, 0
   index: -1
 stirrup-strap
   rotate: false
-  xy: 824, 147
+  xy: 852, 2
   size: 49, 46
   orig: 49, 46
   offset: 0, 0
   index: -1
 torso
-  rotate: false
-  xy: 737, 137
+  rotate: true
+  xy: 2, 25
   size: 54, 91
   orig: 54, 91
   offset: 0, 0
   index: -1
 visor
   rotate: false
-  xy: 487, 191
+  xy: 853, 50
   size: 131, 84
   orig: 131, 84
   offset: 0, 0

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


Разница между файлами не показана из-за своего большого размера
+ 73 - 74
spine-ts/webgl/example/assets/raptor-pro.json


+ 51 - 51
spine-ts/webgl/example/assets/spineboy-pma.atlas

@@ -6,280 +6,280 @@ filter: Linear,Linear
 repeat: none
 crosshair
   rotate: false
-  xy: 352, 7
+  xy: 976, 69
   size: 45, 45
   orig: 45, 45
   offset: 0, 0
   index: -1
 eye-indifferent
-  rotate: false
-  xy: 862, 105
+  rotate: true
+  xy: 967, 116
   size: 47, 45
   orig: 47, 45
   offset: 0, 0
   index: -1
 eye-surprised
   rotate: false
-  xy: 505, 79
+  xy: 434, 68
   size: 47, 45
   orig: 47, 45
   offset: 0, 0
   index: -1
 front-bracer
   rotate: false
-  xy: 826, 66
+  xy: 582, 78
   size: 29, 40
   orig: 29, 40
   offset: 0, 0
   index: -1
 front-fist-closed
   rotate: false
-  xy: 786, 65
+  xy: 825, 33
   size: 38, 41
   orig: 38, 41
   offset: 0, 0
   index: -1
 front-fist-open
-  rotate: true
-  xy: 710, 51
+  rotate: false
+  xy: 67, 53
   size: 43, 44
   orig: 43, 44
   offset: 0, 0
   index: -1
 front-foot
   rotate: false
-  xy: 210, 6
+  xy: 2, 62
   size: 63, 35
   orig: 63, 35
   offset: 0, 0
   index: -1
 front-shin
   rotate: true
-  xy: 665, 128
+  xy: 488, 77
   size: 41, 92
   orig: 41, 92
   offset: 0, 0
   index: -1
 front-thigh
-  rotate: true
-  xy: 2, 2
+  rotate: false
+  xy: 112, 41
   size: 23, 56
   orig: 23, 56
   offset: 0, 0
   index: -1
 front-upper-arm
   rotate: false
-  xy: 250, 205
+  xy: 865, 25
   size: 23, 49
   orig: 23, 49
   offset: 0, 0
   index: -1
 goggles
-  rotate: false
-  xy: 665, 171
+  rotate: true
+  xy: 743, 117
   size: 131, 83
   orig: 131, 83
   offset: 0, 0
   index: -1
 gun
-  rotate: false
-  xy: 798, 152
+  rotate: true
+  xy: 828, 143
   size: 105, 102
   orig: 105, 102
   offset: 0, 0
   index: -1
 head
   rotate: false
-  xy: 2, 27
+  xy: 2, 99
   size: 136, 149
   orig: 136, 149
   offset: 0, 0
   index: -1
 hoverboard-board
-  rotate: false
-  xy: 2, 178
+  rotate: true
+  xy: 140, 2
   size: 246, 76
   orig: 246, 76
   offset: 0, 0
   index: -1
 hoverboard-thruster
-  rotate: true
-  xy: 722, 96
+  rotate: false
+  xy: 987, 167
   size: 30, 32
   orig: 30, 32
   offset: 0, 0
   index: -1
 hoverglow-small
   rotate: false
-  xy: 275, 81
+  xy: 828, 103
   size: 137, 38
   orig: 137, 38
   offset: 0, 0
   index: -1
 mouth-grind
   rotate: false
-  xy: 614, 97
+  xy: 365, 41
   size: 47, 30
   orig: 47, 30
   offset: 0, 0
   index: -1
 mouth-oooo
   rotate: false
-  xy: 612, 65
+  xy: 602, 40
   size: 47, 30
   orig: 47, 30
   offset: 0, 0
   index: -1
 mouth-smile
   rotate: false
-  xy: 661, 64
+  xy: 651, 40
   size: 47, 30
   orig: 47, 30
   offset: 0, 0
   index: -1
 muzzle-glow
   rotate: false
-  xy: 382, 54
+  xy: 976, 42
   size: 25, 25
   orig: 25, 25
   offset: 0, 0
   index: -1
 muzzle-ring
   rotate: true
-  xy: 275, 54
+  xy: 799, 76
   size: 25, 105
   orig: 25, 105
   offset: 0, 0
   index: -1
 muzzle01
-  rotate: true
-  xy: 911, 95
+  rotate: false
+  xy: 365, 73
   size: 67, 40
   orig: 67, 40
   offset: 0, 0
   index: -1
 muzzle02
   rotate: false
-  xy: 792, 108
+  xy: 295, 71
   size: 68, 42
   orig: 68, 42
   offset: 0, 0
   index: -1
 muzzle03
   rotate: true
-  xy: 956, 171
+  xy: 932, 165
   size: 83, 53
   orig: 83, 53
   offset: 0, 0
   index: -1
 muzzle04
   rotate: false
-  xy: 275, 7
+  xy: 218, 68
   size: 75, 45
   orig: 75, 45
   offset: 0, 0
   index: -1
 muzzle05
   rotate: false
-  xy: 140, 3
+  xy: 906, 63
   size: 68, 38
   orig: 68, 38
   offset: 0, 0
   index: -1
 neck
   rotate: false
-  xy: 250, 182
+  xy: 1003, 46
   size: 18, 21
   orig: 18, 21
   offset: 0, 0
   index: -1
 portal-bg
   rotate: false
-  xy: 140, 43
+  xy: 218, 115
   size: 133, 133
   orig: 133, 133
   offset: 0, 0
   index: -1
 portal-flare1
   rotate: false
-  xy: 554, 65
+  xy: 767, 44
   size: 56, 30
   orig: 56, 30
   offset: 0, 0
   index: -1
 portal-flare2
-  rotate: true
-  xy: 759, 112
+  rotate: false
+  xy: 483, 44
   size: 57, 31
   orig: 57, 31
   offset: 0, 0
   index: -1
 portal-flare3
   rotate: false
-  xy: 554, 97
+  xy: 542, 45
   size: 58, 30
   orig: 58, 30
   offset: 0, 0
   index: -1
 portal-shade
   rotate: false
-  xy: 275, 121
+  xy: 353, 115
   size: 133, 133
   orig: 133, 133
   offset: 0, 0
   index: -1
 portal-streaks1
   rotate: false
-  xy: 410, 126
+  xy: 488, 120
   size: 126, 128
   orig: 126, 128
   offset: 0, 0
   index: -1
 portal-streaks2
   rotate: false
-  xy: 538, 129
+  xy: 616, 123
   size: 125, 125
   orig: 125, 125
   offset: 0, 0
   index: -1
 rear-bracer
   rotate: false
-  xy: 857, 67
+  xy: 295, 33
   size: 28, 36
   orig: 28, 36
   offset: 0, 0
   index: -1
 rear-foot
   rotate: false
-  xy: 663, 96
+  xy: 708, 45
   size: 57, 30
   orig: 57, 30
   offset: 0, 0
   index: -1
 rear-shin
   rotate: true
-  xy: 414, 86
+  xy: 708, 77
   size: 38, 89
   orig: 38, 89
   offset: 0, 0
   index: -1
 rear-thigh
   rotate: false
-  xy: 756, 63
+  xy: 987, 201
   size: 28, 47
   orig: 28, 47
   offset: 0, 0
   index: -1
 rear-upper-arm
-  rotate: true
-  xy: 60, 5
+  rotate: false
+  xy: 325, 25
   size: 20, 44
   orig: 20, 44
   offset: 0, 0
   index: -1
 torso
-  rotate: false
-  xy: 905, 164
+  rotate: true
+  xy: 616, 72
   size: 49, 90
   orig: 49, 90
   offset: 0, 0

BIN
spine-ts/webgl/example/assets/spineboy-pma.png


Разница между файлами не показана из-за своего большого размера
+ 85 - 103
spine-ts/webgl/example/assets/spineboy-pro.json


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


+ 5 - 5
spine-ts/webgl/example/assets/stretchyman-pma.atlas

@@ -6,35 +6,35 @@ filter: Linear,Linear
 repeat: none
 back-arm
   rotate: true
-  xy: 679, 173
+  xy: 679, 58
   size: 72, 202
   orig: 72, 202
   offset: 0, 0
   index: -1
 back-leg
   rotate: true
-  xy: 2, 2
+  xy: 679, 132
   size: 100, 318
   orig: 100, 318
   offset: 0, 0
   index: -1
 body
   rotate: true
-  xy: 2, 104
+  xy: 2, 91
   size: 141, 452
   orig: 141, 452
   offset: 0, 0
   index: -1
 front-arm
   rotate: true
-  xy: 456, 100
+  xy: 456, 87
   size: 145, 221
   orig: 145, 221
   offset: 0, 0
   index: -1
 head
   rotate: true
-  xy: 322, 15
+  xy: 2, 2
   size: 87, 102
   orig: 87, 102
   offset: 0, 0

BIN
spine-ts/webgl/example/assets/stretchyman-pma.png


Разница между файлами не показана из-за своего большого размера
+ 17 - 20
spine-ts/webgl/example/assets/stretchyman-pro.json


Разница между файлами не показана из-за своего большого размера
+ 17 - 20
spine-ts/webgl/example/assets/stretchyman-stretchy-ik-pro.json


+ 36 - 36
spine-ts/webgl/example/assets/tank-pma.atlas

@@ -5,169 +5,169 @@ format: RGBA8888
 filter: Linear,Linear
 repeat: none
 antenna
-  rotate: true
-  xy: 650, 857
+  rotate: false
+  xy: 836, 72
   size: 11, 152
   orig: 11, 152
   offset: 0, 0
   index: -1
 cannon
   rotate: true
-  xy: 434, 376
+  xy: 863, 66
   size: 466, 29
   orig: 466, 29
   offset: 0, 0
   index: -1
 cannon-connector
-  rotate: true
-  xy: 349, 241
+  rotate: false
+  xy: 778, 2
   size: 56, 68
   orig: 56, 68
   offset: 0, 0
   index: -1
 ground
-  rotate: true
-  xy: 255, 330
+  rotate: false
+  xy: 2, 307
   size: 512, 177
   orig: 512, 177
   offset: 0, 0
   index: -1
 guntower
-  rotate: false
-  xy: 650, 870
+  rotate: true
+  xy: 650, 167
   size: 365, 145
   orig: 365, 145
   offset: 0, 0
   index: -1
 machinegun
-  rotate: false
-  xy: 255, 299
+  rotate: true
+  xy: 803, 74
   size: 166, 29
   orig: 166, 29
   offset: 0, 0
   index: -1
 machinegun-mount
-  rotate: true
-  xy: 2, 2
+  rotate: false
+  xy: 134, 4
   size: 36, 48
   orig: 36, 48
   offset: 0, 0
   index: -1
 rock
   rotate: true
-  xy: 465, 552
+  xy: 797, 242
   size: 290, 64
   orig: 290, 64
   offset: 0, 0
   index: -1
 smoke-glow
   rotate: false
-  xy: 531, 563
+  xy: 82, 2
   size: 50, 50
   orig: 50, 50
   offset: 0, 0
   index: -1
 smoke-puff01-bg
-  rotate: true
-  xy: 465, 458
+  rotate: false
+  xy: 516, 324
   size: 92, 62
   orig: 92, 62
   offset: 0, 0
   index: -1
 smoke-puff01-fg
-  rotate: false
-  xy: 115, 138
+  rotate: true
+  xy: 838, 534
   size: 88, 59
   orig: 88, 59
   offset: 0, 0
   index: -1
 smoke-puff02-fg
   rotate: false
-  xy: 255, 235
+  xy: 650, 534
   size: 92, 62
   orig: 92, 62
   offset: 0, 0
   index: -1
 smoke-puff03-fg
   rotate: false
-  xy: 531, 685
+  xy: 744, 534
   size: 92, 62
   orig: 92, 62
   offset: 0, 0
   index: -1
 smoke-puff04-fg
-  rotate: true
-  xy: 465, 378
+  rotate: false
+  xy: 2, 4
   size: 78, 48
   orig: 78, 48
   offset: 0, 0
   index: -1
 tank-bottom
-  rotate: true
-  xy: 115, 199
+  rotate: false
+  xy: 2, 167
   size: 643, 138
   orig: 643, 138
   offset: 0, 0
   index: -1
 tank-bottom-shadow
   rotate: false
-  xy: 2, 844
+  xy: 2, 486
   size: 646, 171
   orig: 646, 171
   offset: 0, 0
   index: -1
 tank-top
-  rotate: true
-  xy: 2, 138
+  rotate: false
+  xy: 2, 54
   size: 704, 111
   orig: 704, 111
   offset: 0, 0
   index: -1
 tread
-  rotate: true
-  xy: 626, 794
+  rotate: false
+  xy: 210, 37
   size: 48, 15
   orig: 48, 15
   offset: 0, 0
   index: -1
 tread-inside
   rotate: false
-  xy: 434, 360
+  xy: 516, 308
   size: 13, 14
   orig: 13, 14
   offset: 0, 0
   index: -1
 wheel-big
   rotate: false
-  xy: 2, 40
+  xy: 516, 388
   size: 96, 96
   orig: 96, 96
   offset: 0, 0
   index: -1
 wheel-big-overlay
   rotate: false
-  xy: 531, 749
+  xy: 708, 72
   size: 93, 93
   orig: 93, 93
   offset: 0, 0
   index: -1
 wheel-mid
   rotate: false
-  xy: 100, 68
+  xy: 894, 66
   size: 68, 68
   orig: 68, 68
   offset: 0, 0
   index: -1
 wheel-mid-overlay
   rotate: false
-  xy: 531, 615
+  xy: 708, 2
   size: 68, 68
   orig: 68, 68
   offset: 0, 0
   index: -1
 wheel-small
   rotate: false
-  xy: 205, 161
+  xy: 172, 16
   size: 36, 36
   orig: 36, 36
   offset: 0, 0

BIN
spine-ts/webgl/example/assets/tank-pma.png


Разница между файлами не показана из-за своего большого размера
+ 1773 - 1788
spine-ts/webgl/example/assets/tank-pro.json


+ 3 - 3
spine-ts/webgl/example/assets/vine-pma.atlas

@@ -1,12 +1,12 @@
 
 vine-pma.png
-size: 128,1024
+size: 1024,128
 format: RGBA8888
 filter: Linear,Linear
 repeat: none
 vine
-  rotate: false
-  xy: 2, 2
+  rotate: true
+  xy: 2, 3
   size: 68, 962
   orig: 68, 962
   offset: 0, 0

BIN
spine-ts/webgl/example/assets/vine-pma.png


Разница между файлами не показана из-за своего большого размера
+ 6 - 9
spine-ts/webgl/example/assets/vine-pro.json


+ 1 - 0
spine-ts/webgl/example/index.html

@@ -238,6 +238,7 @@ function setupUI () {
 function render () {
 	var now = Date.now() / 1000;
 	var delta = now - lastFrameTime;
+	delta = 0.016;
 	lastFrameTime = now;
 
 	// Update the MVP matrix to adjust for canvas size changes

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

@@ -102,6 +102,7 @@ module spine.webgl {
 				let slots = skeleton.slots;
 				for (let i = 0, n = slots.length; i < n; i++) {
 					let slot = slots[i];
+					if (!slot.bone.active) continue;
 					let attachment = slot.getAttachment();
 					if (!(attachment instanceof MeshAttachment)) continue;
 					let mesh = <MeshAttachment>attachment;
@@ -151,6 +152,7 @@ module spine.webgl {
 				let slots = skeleton.slots;
 				for (let i = 0, n = slots.length; i < n; i++) {
 					let slot = slots[i];
+					if (!slot.bone.active) continue;
 					let attachment = slot.getAttachment();
 					if (!(attachment instanceof PathAttachment)) continue;
 					let path = <PathAttachment>attachment;
@@ -199,6 +201,7 @@ module spine.webgl {
 				shapes.setColor(this.clipColor)
 				for (let i = 0, n = slots.length; i < n; i++) {
 					let slot = slots[i];
+					if (!slot.bone.active) continue;
 					let attachment = slot.getAttachment();
 					if (!(attachment instanceof ClippingAttachment)) continue;
 					let clip = <ClippingAttachment>attachment;

+ 4 - 0
spine-ts/webgl/src/SkeletonRenderer.ts

@@ -79,6 +79,10 @@ module spine.webgl {
 			for (let i = 0, n = drawOrder.length; i < n; i++) {
 				let clippedVertexSize = clipper.isClipping() ? 2 : vertexSize;
 				let slot = drawOrder[i];
+				if (!slot.bone.active) {
+					clipper.clipEndWithSlot(slot);
+					continue;
+				}
 
 				if (slotRangeStart >= 0 && slotRangeStart == slot.data.index) {
 					inRange = true;

Некоторые файлы не были показаны из-за большого количества измененных файлов