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

[as3][starling] Updated to 3.5, path constraint may still have an issue, see stretchyman

badlogic 9 лет назад
Родитель
Сommit
8b327f3d54

+ 4 - 0
examples/export/runtimes.sh

@@ -152,6 +152,10 @@ cp -f ../vine/export/vine.json ../../spine-starling/spine-starling-example/src/
 cp -f ../vine/export/vine.atlas ../../spine-starling/spine-starling-example/src/
 cp -f ../vine/export/vine.png ../../spine-starling/spine-starling-example/src/
 
+cp -f ../stretchyman/export/stretchyman.json ../../spine-starling/spine-starling-example/src/
+cp -f ../stretchyman/export/stretchyman.atlas ../../spine-starling/spine-starling-example/src/
+cp -f ../stretchyman/export/stretchyman.png ../../spine-starling/spine-starling-example/src/
+
 
 echo "spine-ts"
 rm -f ../../spine-ts/webgl/example/assets/*

+ 138 - 118
spine-as3/spine-as3/src/spine/Bone.as

@@ -44,7 +44,14 @@ public class Bone implements Updatable {
 	public var scaleY:Number;
 	public var shearX:Number;
 	public var shearY:Number;
-	public var appliedRotation:Number;	
+	public var ax:Number;
+	public var ay:Number;
+	public var arotation:Number;
+	public var ascaleX:Number;
+	public var ascaleY:Number;
+	public var ashearX:Number;
+	public var ashearY:Number;
+	public var appliedValid:Boolean;	
 
 	internal var _a:Number;
 	internal var _b:Number;
@@ -52,8 +59,6 @@ public class Bone implements Updatable {
 	internal var _d:Number;
 	internal var _worldX:Number;
 	internal var _worldY:Number;
-	internal var _worldSignX:Number;
-	internal var _worldSignY:Number;
 	
 	internal var _sorted:Boolean;
 
@@ -79,14 +84,26 @@ public class Bone implements Updatable {
 
 	/** Computes the world SRT using the parent bone and the specified local SRT. */
 	public function updateWorldTransformWith (x:Number, y:Number, rotation:Number, scaleX:Number, scaleY:Number, shearX:Number, shearY:Number) : void {
-		appliedRotation = rotation;
-
-		var rotationY:Number = rotation + 90 + shearY;
-		var la:Number = MathUtils.cosDeg(rotation + shearX) * scaleX, lb:Number = MathUtils.cosDeg(rotationY) * scaleY;
-		var lc:Number = MathUtils.sinDeg(rotation + shearX) * scaleX, ld:Number = MathUtils.sinDeg(rotationY) * scaleY;
+		ax = x;
+		ay = y;
+		arotation = rotation;
+		ascaleX = scaleX;
+		ascaleY = scaleY;
+		ashearX = shearX;
+		ashearY = shearY;
+		appliedValid = true;
+		
+		var rotationY:Number = 0, la:Number = 0, lb:Number = 0, lc:Number = 0, ld:Number = 0;
+		var sin:Number = 0, cos:Number = 0;
+		var s:Number = 0;
 		
 		var parent:Bone = _parent;
 		if (!parent) { // Root bone.
+			rotationY = rotation + 90 + shearY;
+			la = MathUtils.cosDeg(rotation + shearX) * scaleX;
+			lb = MathUtils.cosDeg(rotationY) * scaleY;
+			lc = MathUtils.sinDeg(rotation + shearX) * scaleX;
+			ld = MathUtils.sinDeg(rotationY) * scaleY;
 			var skeleton:Skeleton = _skeleton;
 			if (skeleton.flipX) {
 				x = -x;
@@ -102,91 +119,103 @@ public class Bone implements Updatable {
 			_b = lb;
 			_c = lc;
 			_d = ld;
-			_worldX = x;
-			_worldY = y;
-			_worldSignX = scaleX < 0 ? -1 : 1;
-			_worldSignY = scaleY < 0 ? -1 : 1;
+			_worldX = x + skeleton.x;
+			_worldY = y + skeleton.y;	
 			return;
 		}
 
 		var pa:Number = parent._a, pb:Number = parent._b, pc:Number = parent._c, pd:Number = parent._d;
 		_worldX = pa * x + pb * y + parent._worldX;
-		_worldY = pc * x + pd * y + parent._worldY;
-		_worldSignX = parent._worldSignX * (scaleX < 0 ? -1 : 1);
-		_worldSignY = parent._worldSignY * (scaleY < 0 ? -1 : 1);
-
-		if (data.inheritRotation && data.inheritScale) {
+		_worldY = pc * x + pd * y + parent._worldY;		
+
+		switch (_data.transformMode) {
+		case TransformMode.normal: {
+			rotationY = rotation + 90 + shearY;
+			la = MathUtils.cosDeg(rotation + shearX) * scaleX;
+			lb = MathUtils.cosDeg(rotationY) * scaleY;
+			lc = MathUtils.sinDeg(rotation + shearX) * scaleX;
+			ld = MathUtils.sinDeg(rotationY) * scaleY;
 			_a = pa * la + pb * lc;
 			_b = pa * lb + pb * ld;
 			_c = pc * la + pd * lc;
 			_d = pc * lb + pd * ld;
-		} else {
-			if (data.inheritRotation) { // No scale inheritance.
-				pa = 1;
-				pb = 0;
-				pc = 0;
-				pd = 1;
-				do {
-					var cos:Number = MathUtils.cosDeg(parent.appliedRotation), sin:Number = MathUtils.sinDeg(parent.appliedRotation);
-					var temp:Number = pa * cos + pb * sin;
-					pb = pb * cos - pa * sin;
-					pa = temp;
-					temp = pc * cos + pd * sin;
-					pd = pd * cos - pc * sin;
-					pc = temp;
-	
-					if (!parent.data.inheritRotation) break;
-					parent = parent.parent;
-				} while (parent != null);
-				_a = pa * la + pb * lc;
-				_b = pa * lb + pb * ld;
-				_c = pc * la + pd * lc;
-				_d = pc * lb + pd * ld;
-			} else if (data.inheritScale) { // No rotation inheritance.
-				pa = 1;
-				pb = 0;
-				pc = 0;
-				pd = 1;
-				do {
-					cos = MathUtils.cosDeg(parent.appliedRotation), sin = MathUtils.sinDeg(parent.appliedRotation);
-					var psx:Number = parent.scaleX, psy:Number = parent.scaleY;
-					var za:Number = cos * psx, zb:Number = sin * psy, zc:Number = sin * psx, zd:Number = cos * psy;
-					temp = pa * za + pb * zc;
-					pb = pb * zd - pa * zb;
-					pa = temp;
-					temp = pc * za + pd * zc;
-					pd = pd * zd - pc * zb;
-					pc = temp;
-
-					if (psx >= 0) sin = -sin;
-					temp = pa * cos + pb * sin;
-					pb = pb * cos - pa * sin;
-					pa = temp;
-					temp = pc * cos + pd * sin;
-					pd = pd * cos - pc * sin;
-					pc = temp;
-	
-					if (!parent.data.inheritScale) break;
-					parent = parent.parent;
-				} while (parent != null);
-				_a = pa * la + pb * lc;
-				_b = pa * lb + pb * ld;
-				_c = pc * la + pd * lc;
-				_d = pc * lb + pd * ld;
+			return;
+		}
+		case TransformMode.onlyTranslation: {
+			rotationY = rotation + 90 + shearY;
+			_a = MathUtils.cosDeg(rotation + shearX) * scaleX;
+			_b = MathUtils.cosDeg(rotationY) * scaleY;
+			_c = MathUtils.sinDeg(rotation + shearX) * scaleX;
+			_d = MathUtils.sinDeg(rotationY) * scaleY;
+			break;
+		}
+		case TransformMode.noRotationOrReflection: {
+			var psx:Number = Math.sqrt(pa * pa + pc * pc);
+			var psy:Number = 0;
+			var prx:Number = 0;
+			if (psx > 0.0001) {
+				psy = Math.abs((pa * pd - pb * pc) / psx);
+				prx = Math.atan2(pc, pa) * MathUtils.radDeg;
 			} else {
-				_a = la;
-				_b = lb;
-				_c = lc;
-				_d = ld;
+				psx = 0;
+				psy = Math.sqrt(pb * pb + pd * pd);
+				prx = 90 - Math.atan2(pd, pb) * MathUtils.radDeg;
 			}
-			if (_skeleton.flipX) {
-				_a = -_a;
+			cos = MathUtils.cosDeg(prx);
+			sin = MathUtils.sinDeg(prx);
+			pa = cos * psx;
+			pb = -sin * psy;
+			pc = sin * psx;
+			pd = cos * psy;
+			var rx:Number = rotation + shearX - prx;
+			var ry:Number = rotation + shearY - prx + 90;
+			la = MathUtils.cosDeg(rx) * scaleX;
+			lb = MathUtils.cosDeg(ry) * scaleY;
+			lc = MathUtils.sinDeg(rx) * scaleX;
+			ld = MathUtils.sinDeg(ry) * scaleY;
+			_a = pa * la + pb * lc;
+			_b = pa * lb + pb * ld;
+			_c = pc * la + pd * lc;
+			_d = pc * lb + pd * ld;
+						
+			break;
+		}
+		case TransformMode.noScale:
+		case TransformMode.noScaleOrReflection: {
+			cos = MathUtils.cosDeg(rotation);
+			sin = MathUtils.sinDeg(rotation);
+			var za:Number = pa * cos + pb * sin;
+			var zc:Number = pc * cos + pd * sin;
+			s = Math.sqrt(za * za + zc * zc);
+			if (s > 0.00001) s = 1 / s;
+			za *= s;
+			zc *= s;
+			s = Math.sqrt(za * za + zc * zc);
+			var r:Number = Math.PI / 2 + Math.atan2(zc, za);
+			var zb:Number = Math.cos(r) * s;
+			var zd:Number = Math.sin(r) * s;
+			la = MathUtils.cosDeg(shearX) * scaleX;
+			lb = MathUtils.cosDeg(90 + shearY) * scaleY;
+			lc = MathUtils.sinDeg(shearX) * scaleX;
+			ld = MathUtils.sinDeg(90 + shearY) * scaleY;
+			_a = za * la + zb * lc;
+			_b = za * lb + zb * ld;
+			_c = zc * la + zd * lc;
+			_d = zc * lb + zd * ld;
+			if (_data.transformMode != TransformMode.noScaleOrReflection ? pa * pd - pb * pc < 0 : skeleton.flipX != skeleton.flipY) {
 				_b = -_b;
-			}
-			if (_skeleton.flipY != yDown) {
-				_c = -_c;
 				_d = -_d;
 			}
+			return;
+		}
+		}
+		if (_skeleton.flipX) {
+			_a = -_a;
+			_b = -_b;
+		}
+		if (_skeleton.flipY != yDown) {
+			_c = -_c;
+			_d = -_d;
 		}
 	}
 
@@ -240,14 +269,6 @@ public class Bone implements Updatable {
 		return _worldY;
 	}
 
-	public function get worldSignX () : Number {
-		return _worldSignX;
-	}
-
-	public function get worldSignY () : Number {
-		return _worldSignY;
-	}
-
 	public function get worldRotationX () : Number {
 		return Math.atan2(_c, _a) * MathUtils.radDeg;
 	}
@@ -257,23 +278,23 @@ public class Bone implements Updatable {
 	}
 
 	public function get worldScaleX () : Number {
-		return Math.sqrt(_a * _a + _b * _b) * _worldSignX;
+		return Math.sqrt(_a * _a + _c * _c);
 	}
 
 	public function get worldScaleY () : Number {
-		return Math.sqrt(_c * _c + _d * _d) * _worldSignY;
+		return Math.sqrt(_b * _b + _d * _d);
 	}
 	
 	public function worldToLocalRotationX () : Number {
 		var parent:Bone = _parent;
-		if (parent == null) return rotation;
+		if (parent == null) return arotation;
 		var pa:Number = parent.a, pb:Number = parent.b, pc:Number = parent.c, pd:Number = parent.d, a:Number = this.a, c:Number = this.c;
 		return Math.atan2(pa * c - pc * a, pd * a - pb * c) * MathUtils.radDeg;
 	}
 
 	public function worldToLocalRotationY () : Number {
 		var parent:Bone = _parent;
-		if (parent == null) return rotation;
+		if (parent == null) return arotation;
 		var pa:Number = parent.a, pb:Number = parent.b, pc:Number = parent.c, pd:Number = parent.d, b:Number = this.b, d:Number = this.d;
 		return Math.atan2(pa * d - pc * b, pd * b - pb * d) * MathUtils.radDeg;
 	}
@@ -285,31 +306,31 @@ public class Bone implements Updatable {
 		this._b = cos * b - sin * d;
 		this._c = sin * a + cos * c;
 		this._d = sin * b + cos * d;
+		this.appliedValid = false;
 	}
 
-	/** Computes the local transform from the world transform. This can be useful to perform processing on the local transform
-	 * after the world transform has been modified directly (eg, by a constraint).
+	/** Computes the individual applied transform values from the world transform. This can be useful to perform processing using
+	 * the applied transform after the world transform has been modified directly (eg, by a constraint).
 	 * <p>
-	 * Some redundant information is lost by the world transform, such as -1,-1 scale versus 180 rotation. The computed local
-	 * transform values may differ from the original values but are functionally the same. */
-	public function updateLocalTransform () : void {
+	 * Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. */
+	public function updateAppliedTransform () : void {
+		appliedValid = true;
 		var parent:Bone = this.parent;
 		if (parent == null) {
-			x = worldX;
-			y = worldY;
-			rotation = Math.atan2(c, a) * MathUtils.radDeg;
-			scaleX = Math.sqrt(a * a + c * c);
-			scaleY = Math.sqrt(b * b + d * d);
-			var det:Number = a * d - b * c;
-			shearX = 0;
-			shearY = Math.atan2(a * b + c * d, det) * MathUtils.radDeg;
+			ax = worldX;
+			ay = worldY;
+			arotation = Math.atan2(c, a) * MathUtils.radDeg;
+			ascaleX = Math.sqrt(a * a + c * c);
+			ascaleY = Math.sqrt(b * b + d * d);			
+			ashearX = 0;
+			ashearY = Math.atan2(a * b + c * d, a * d - b * c) * MathUtils.radDeg;
 			return;
 		}
 		var pa:Number = parent.a, pb:Number = parent.b, pc:Number = parent.c, pd:Number = parent.d;
 		var pid:Number = 1 / (pa * pd - pb * pc);
 		var dx:Number = worldX - parent.worldX, dy:Number = worldY - parent.worldY;
-		x = (dx * pd * pid - dy * pb * pid);
-		y = (dy * pa * pid - dx * pc * pid);
+		ax = (dx * pd * pid - dy * pb * pid);
+		ay = (dy * pa * pid - dx * pc * pid);
 		var ia:Number = pid * pd;
 		var id:Number = pid * pa;
 		var ib:Number = pid * pb;
@@ -318,20 +339,19 @@ public class Bone implements Updatable {
 		var rb:Number = ia * b - ib * d;
 		var rc:Number = id * c - ic * a;
 		var rd:Number = id * d - ic * b;
-		shearX = 0;
-		scaleX = Math.sqrt(ra * ra + rc * rc);
+		ashearX = 0;
+		ascaleX = Math.sqrt(ra * ra + rc * rc);
 		if (scaleX > 0.0001) {
-			det = ra * rd - rb * rc;
-			scaleY = det / scaleX;
-			shearY = Math.atan2(ra * rb + rc * rd, det) * MathUtils.radDeg;
-			rotation = Math.atan2(rc, ra) * MathUtils.radDeg;
+			var det:Number = ra * rd - rb * rc;
+			ascaleY = det /ascaleX;
+			ashearY = Math.atan2(ra * rb + rc * rd, det) * MathUtils.radDeg;
+			arotation = Math.atan2(rc, ra) * MathUtils.radDeg;
 		} else {
-			scaleX = 0;
-			scaleY = Math.sqrt(rb * rb + rd * rd);
-			shearY = 0;
-			rotation = 90 - Math.atan2(rd, rb) * MathUtils.radDeg;
-		}
-		appliedRotation = rotation;
+			ascaleX = 0;
+			ascaleY = Math.sqrt(rb * rb + rd * rd);
+			ashearY = 0;
+			arotation = 90 - Math.atan2(rd, rb) * MathUtils.radDeg;
+		}		
 	}
 
 	public function worldToLocal (world:Vector.<Number>) : void {

+ 1 - 2
spine-as3/spine-as3/src/spine/BoneData.as

@@ -42,8 +42,7 @@ public class BoneData {
 	public var scaleY:Number = 1;
 	public var shearX:Number;
 	public var shearY:Number;	
-	public var inheritRotation:Boolean = true;
-	public var inheritScale:Boolean = true;
+	public var transformMode:TransformMode = TransformMode.normal;
 
 	/** @param parent May be null. */
 	public function BoneData (index:int, name:String, parent:BoneData) {

+ 37 - 0
spine-as3/spine-as3/src/spine/Constraint.as

@@ -0,0 +1,37 @@
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ *
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+package spine {
+
+public interface Constraint extends Updatable {
+	function getOrder () : Number;
+}
+
+}

+ 24 - 19
spine-as3/spine-as3/src/spine/IkConstraint.as

@@ -30,14 +30,12 @@
 
 package spine {
 
-public class IkConstraint implements Updatable {
+public class IkConstraint implements Constraint {
 	internal var _data:IkConstraintData;
 	public var bones:Vector.<Bone>;
 	public var target:Bone;
 	public var mix:Number;
 	public var bendDirection:int;
-	
-	public var level:int;	
 
 	public function IkConstraint (data:IkConstraintData, skeleton:Skeleton) {
 		if (data == null) throw new ArgumentError("data cannot be null.");
@@ -66,6 +64,10 @@ public class IkConstraint implements Updatable {
 			break;
 		}
 	}
+	
+	public function getOrder() : Number {
+		return _data.order;
+	}
 
 	public function get data () : IkConstraintData {
 		return _data;
@@ -78,17 +80,18 @@ public class IkConstraint implements Updatable {
 	/** Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified in the world
 	 * coordinate system. */
 	static public function apply1 (bone:Bone, targetX:Number, targetY:Number, alpha:Number) : void {
-		var pp:Bone = bone.parent;
-		var id:Number = 1 / (pp.a * pp.d - pp.b * pp.c);
-		var x:Number = targetX - pp.worldX, y:Number = targetY - pp.worldY;
-		var tx:Number = (x * pp.d - y * pp.b) * id - bone.x, ty:Number = (y * pp.a - x * pp.c) * id - bone.y;
-		var rotationIK:Number = Math.atan2(ty, tx) * MathUtils.radDeg - bone.shearX - bone.rotation;
-		if (bone.scaleX < 0) rotationIK += 180;
+		if (!bone.appliedValid) bone.updateAppliedTransform();
+		var p:Bone = bone.parent;
+		var id:Number = 1 / (p.a * p.d - p.b * p.c);
+		var x:Number = targetX - p.worldX, y:Number = targetY - p.worldY;
+		var tx:Number = (x * p.d - y * p.b) * id - bone.ax, ty:Number = (y * p.a - x * p.c) * id - bone.ay;
+		var rotationIK:Number = Math.atan2(ty, tx) * MathUtils.radDeg - bone.ashearX - bone.arotation;
+		if (bone.ascaleX < 0) rotationIK += 180;
 		if (rotationIK > 180)
 			rotationIK -= 360;
 		else if (rotationIK < -180) rotationIK += 360;
-		bone.updateWorldTransformWith(bone.x, bone.y, bone.rotation + rotationIK * alpha, bone.scaleX, bone.scaleY, bone.shearX,
-			bone.shearY);
+		bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, bone.ascaleX, bone.ascaleY, bone.ashearX,
+			bone.ashearY);
 	}
 
 	/** Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as possible. The
@@ -99,7 +102,9 @@ public class IkConstraint implements Updatable {
 			child.updateWorldTransform();
 			return;
 		}
-		var px:Number = parent.x, py:Number = parent.y, psx:Number = parent.scaleX, psy:Number = parent.scaleY, csx:Number = child.scaleX;;
+		if (!parent.appliedValid) parent.updateAppliedTransform();
+		if (!child.appliedValid) child.updateAppliedTransform();
+		var px:Number = parent.ax, py:Number = parent.ay, psx:Number = parent.ascaleX, psy:Number = parent.ascaleY, csx:Number = child.ascaleX;
 		var os1:int, os2:int, s2:int;
 		if (psx < 0) {
 			psx = -psx;
@@ -118,14 +123,14 @@ public class IkConstraint implements Updatable {
 			os2 = 180;
 		} else
 			os2 = 0;
-		var cx:Number = child.x, cy:Number, cwx:Number, cwy:Number, a:Number = parent.a, b:Number = parent.b, c:Number = parent.c, d:Number = parent.d;
+		var cx:Number = child.ax, cy:Number, cwx:Number, cwy:Number, a:Number = parent.a, b:Number = parent.b, c:Number = parent.c, d:Number = parent.d;
 		var u:Boolean = Math.abs(psx - psy) <= 0.0001;
 		if (!u) {
 			cy = 0;
 			cwx = a * cx + parent.worldX;
 			cwy = c * cx + parent.worldY;
 		} else {
-			cy = child.y;
+			cy = child.ay;
 			cwx = a * cx + b * cy + parent.worldX;
 			cwy = c * cx + d * cy + parent.worldY;
 		}
@@ -212,18 +217,18 @@ public class IkConstraint implements Updatable {
 			}
 		}
 		var os:Number = Math.atan2(cy, cx) * s2;
-		var rotation:Number = parent.rotation;
+		var rotation:Number = parent.arotation;
 		a1 = (a1 - os) * MathUtils.radDeg + os1 - rotation;
 		if (a1 > 180)
 			a1 -= 360;
 		else if (a1 < -180) a1 += 360;
-		parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, parent.scaleX, parent.scaleY, 0, 0);
-		rotation = child.rotation;
-		a2 = ((a2 + os) * MathUtils.radDeg - child.shearX) * s2 + os2 - rotation;
+		parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, parent.ascaleX, parent.ascaleY, 0, 0);
+		rotation = child.arotation;
+		a2 = ((a2 + os) * MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation;
 		if (a2 > 180)
 			a2 -= 360;
 		else if (a2 < -180) a2 += 360;
-		child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.scaleX, child.scaleY, child.shearX, child.shearY);
+		child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY);
 	}
 }
 

+ 1 - 0
spine-as3/spine-as3/src/spine/IkConstraintData.as

@@ -32,6 +32,7 @@ package spine {
 
 public class IkConstraintData {
 	internal var _name:String;
+	public var order:Number;
 	public var bones:Vector.<BoneData> = new Vector.<BoneData>();
 	public var target:BoneData;
 	public var bendDirection:int = 1;

+ 10 - 7
spine-as3/spine-as3/src/spine/PathConstraint.as

@@ -31,7 +31,7 @@
 package spine {
 import spine.attachments.PathAttachment;
 
-public class PathConstraint implements Updatable {
+public class PathConstraint implements Constraint {
 	private static const NONE:int = -1, BEFORE:int = -2, AFTER:int = -3;
 
 	internal var _data:PathConstraintData;
@@ -100,16 +100,14 @@ public class PathConstraint implements Updatable {
 		}
 
 		var positions:Vector.<Number> = computeWorldPositions(attachment, spacesCount, tangents,
-			data.positionMode == PositionMode.percent, spacingMode == SpacingMode.percent);
-		var skeleton:Skeleton = target.skeleton;
-		var skeletonX:Number = skeleton.x, skeletonY:Number = skeleton.y;
+			data.positionMode == PositionMode.percent, spacingMode == SpacingMode.percent);		
 		var boneX:Number = positions[0], boneY:Number = positions[1], offsetRotation:Number = data.offsetRotation;
 		var tip:Boolean = rotateMode == RotateMode.chain && offsetRotation == 0;
 		var p:Number;
 		for (i = 0, p = 3; i < boneCount; i++, p += 3) {
 			bone = bones[i];
-			bone._worldX += (boneX - skeletonX - bone.worldX) * translateMix;
-			bone._worldY += (boneY - skeletonY - bone.worldY) * translateMix;
+			bone._worldX += (boneX - bone.worldX) * translateMix;
+			bone._worldY += (boneY - bone.worldY) * translateMix;
 			x = positions[p]; y = positions[p + 1]; var dx:Number = x - boneX, dy:Number = y - boneY;
 			if (scale) {
 				length = lengths[i];
@@ -149,6 +147,7 @@ public class PathConstraint implements Updatable {
 				bone._c = sin * a + cos * c;
 				bone._d = sin * b + cos * d;
 			}
+			bone.appliedValid = false;
 		}
 	}
 
@@ -394,7 +393,7 @@ public class PathConstraint implements Updatable {
 
 	private function addCurvePosition (p:Number, x1:Number, y1:Number, cx1:Number, cy1:Number, cx2:Number, cy2:Number, x2:Number, y2:Number,
 		out:Vector.<Number>, o:int, tangents:Boolean) : void {
-		if (p == 0) p = 0.0001;
+		if (p == 0 || isNaN(p)) p = 0.0001;
 		var tt:Number = p * p, ttt:Number = tt * p, u:Number = 1 - p, uu:Number = u * u, uuu:Number = uu * u;
 		var ut:Number = u * p, ut3:Number = ut * 3, uut3:Number = u * ut3, utt3:Number = ut3 * p;
 		var x:Number = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y:Number = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt;
@@ -410,6 +409,10 @@ public class PathConstraint implements Updatable {
 	public function get data () : PathConstraintData {
 		return _data;
 	}
+	
+	public function getOrder () : Number {
+		return _data.order;
+	}
 
 	public function toString () : String {
 		return _data.name;

+ 1 - 0
spine-as3/spine-as3/src/spine/PathConstraintData.as

@@ -32,6 +32,7 @@ package spine {
 
 public dynamic class PathConstraintData {
 	internal var _name:String;
+	public var order:Number;
 	internal var _bones:Vector.<BoneData> = new Vector.<BoneData>();
 	public var target:SlotData;
 	public var positionMode:PositionMode;

+ 103 - 83
spine-as3/spine-as3/src/spine/Skeleton.as

@@ -38,10 +38,11 @@ public class Skeleton {
 	public var bones:Vector.<Bone>;
 	public var slots:Vector.<Slot>;
 	public var drawOrder:Vector.<Slot>;
-	public var ikConstraints:Vector.<IkConstraint>, ikConstraintsSorted:Vector.<IkConstraint>;
+	public var ikConstraints:Vector.<IkConstraint>;
 	public var transformConstraints:Vector.<TransformConstraint>;
 	public var pathConstraints:Vector.<PathConstraint>;
 	private var _updateCache:Vector.<Updatable> = new Vector.<Updatable>();
+	private var _updateCacheReset:Vector.<Bone> = new Vector.<Bone>();
 	private var _skin:Skin;
 	public var r:Number = 1, g:Number = 1, b:Number = 1, a:Number = 1;
 	public var time:Number = 0;
@@ -75,8 +76,7 @@ public class Skeleton {
 			drawOrder[drawOrder.length] = slot;
 		}
 		
-		ikConstraints = new Vector.<IkConstraint>();
-		ikConstraintsSorted = new Vector.<IkConstraint>();
+		ikConstraints = new Vector.<IkConstraint>();		
 		for each (var ikConstraintData:IkConstraintData in data.ikConstraints)
 			ikConstraints.push(new IkConstraint(ikConstraintData, this));
 		
@@ -98,101 +98,110 @@ public class Skeleton {
 		updateCache.length = 0;
 
 		var bones:Vector.<Bone> = this.bones;
-		for (var i:int = 0, n:int = bones.length; i < n; i++)
+		var i:Number = 0;
+		var n:Number = 0;
+		for (i = 0, n = bones.length; i < n; i++)
 			bones[i]._sorted = false;
 
 		// IK first, lowest hierarchy depth first.
-		var ikConstraints:Vector.<IkConstraint> = this.ikConstraintsSorted;
-		ikConstraints.length = 0;
-		for each (var c:IkConstraint in this.ikConstraints)
-			ikConstraints.push(c);
-		var ikCount:int = ikConstraints.length;
-		var level:int;
-		for (i = 0, n = ikCount; i < n; i++) {
-			var ik:IkConstraint = ikConstraints[i];
-			var bone:Bone = ik.bones[0].parent;
-			for (level = 0; bone != null; level++)
-				bone = bone.parent;
-			ik.level = level;
-		}
-		var ii:int;
-		for (i = 1; i < ikCount; i++) {
-			ik = ikConstraints[i];
-			level = ik.level;
-			for (ii = i - 1; ii >= 0; ii--) {
-				var other:IkConstraint = ikConstraints[ii];
-				if (other.level < level) break;
-				ikConstraints[ii + 1] = other;
+		var ikConstraints:Vector.<IkConstraint> = this.ikConstraints;
+		var transformConstraints:Vector.<TransformConstraint> = this.transformConstraints;
+		var pathConstraints:Vector.<PathConstraint> = this.pathConstraints;
+		var ikCount:Number = ikConstraints.length, transformCount:Number = transformConstraints.length, pathCount:Number = pathConstraints.length;
+		var constraintCount:Number = ikCount + transformCount + pathCount;
+		
+		outer:			
+		for (i = 0; i < constraintCount; i++) {
+			var ii:Number = 0;
+			for (ii = 0; ii < ikCount; ii++) {
+				var ikConstraint:IkConstraint = ikConstraints[ii];
+				if (ikConstraint.data.order == i) {
+					sortIkConstraint(ikConstraint);
+					continue outer;
+				}
+			}
+			for (ii = 0; ii < transformCount; ii++) {
+				var transformConstraint:TransformConstraint = transformConstraints[ii];
+				if (transformConstraint.data.order == i) {
+					sortTransformConstraint(transformConstraint);
+					continue outer;
+				}
+			}
+			for (ii = 0; ii < pathCount; ii++) {
+				var pathConstraint:PathConstraint = pathConstraints[ii];
+				if (pathConstraint.data.order == i) {
+					sortPathConstraint(pathConstraint);
+					continue outer;
+				}
 			}
-			ikConstraints[ii + 1] = ik;
 		}
-		for (i = 0, n = ikConstraints.length; i < n; i++) {
-			var ikConstraint:IkConstraint = ikConstraints[i];
-			var target:Bone = ikConstraint.target;
-			sortBone(target);
-
-			var constrained:Vector.<Bone> = ikConstraint.bones;
-			var parent:Bone = constrained[0];
-			sortBone(parent);
+		
+		for (i = 0, n = bones.length; i < n; i++)
+			sortBone(bones[i]);
+	}
+	
+	private function sortIkConstraint (constraint:IkConstraint): void {
+		var target:Bone = constraint.target;
+		sortBone(target);
 
-			updateCache.push(ikConstraint);
+		var constrained:Vector.<Bone> = constraint.bones;
+		var parent:Bone = constrained[0];
+		sortBone(parent);
 
-			sortReset(parent.children);
-			constrained[constrained.length - 1]._sorted = true;
+		if (constrained.length > 1) {
+			var child:Bone = constrained[constrained.length - 1];
+			if (!(_updateCache.indexOf(child) > -1)) _updateCacheReset.push(child);
 		}
 
-		var pathConstraints:Vector.<PathConstraint> = this.pathConstraints;
-		for (i = 0, n = pathConstraints.length; i < n; i++) {
-			var pathConstraint:PathConstraint = pathConstraints[i];
-
-			var slot:Slot = pathConstraint.target;
-			var slotIndex:int = slot.data.index;
-			var slotBone:Bone = slot.bone;
-			if (skin != null) sortPathConstraintAttachment(skin, slotIndex, slotBone);
-			if (_data.defaultSkin != null && _data.defaultSkin != skin)
-				sortPathConstraintAttachment(_data.defaultSkin, slotIndex, slotBone);
-				
-			var nn:int;
-			for (ii = 0, nn = _data.skins.length; ii < nn; ii++)
-				sortPathConstraintAttachment(_data.skins[ii], slotIndex, slotBone);
-
-			var attachment:PathAttachment = slot.attachment as PathAttachment;
-			if (attachment != null) sortPathConstraintAttachment2(attachment, slotBone);
-
-			constrained = pathConstraint.bones;
-			var boneCount:int = constrained.length;
-			for (ii = 0; ii < boneCount; ii++)
-				sortBone(constrained[ii]);
-
-			updateCache.push(pathConstraint);
-
-			for (ii = 0; ii < boneCount; ii++)
-				sortReset(constrained[ii].children);
-			for (ii = 0; ii < boneCount; ii++)
-				constrained[ii]._sorted = true;
-		}
+		_updateCache.push(constraint);
 
-		var transformConstraints:Vector.<TransformConstraint> = this.transformConstraints;
-		for (i = 0, n = transformConstraints.length; i < n; i++) {
-			var transformConstraint:TransformConstraint = transformConstraints[i];
+		sortReset(parent.children);
+		constrained[constrained.length - 1]._sorted = true;
+	}
 
-			sortBone(transformConstraint.target);
+	private function sortPathConstraint (constraint:PathConstraint): void {
+		var slot:Slot = constraint.target;
+		var slotIndex:Number = slot.data.index;
+		var slotBone:Bone = slot.bone;
+		if (skin != null) sortPathConstraintAttachment(skin, slotIndex, slotBone);
+		if (data.defaultSkin != null && data.defaultSkin != skin)
+			sortPathConstraintAttachment(data.defaultSkin, slotIndex, slotBone);
+		var ii:Number = 0;
+		var nn:Number = 0;		
+		for (ii = 0, nn = data.skins.length; ii < nn; ii++)
+			sortPathConstraintAttachment(data.skins[ii], slotIndex, slotBone);
+
+		var attachment:Attachment = slot.attachment;
+		if (attachment is PathAttachment) sortPathConstraintAttachment2(attachment, slotBone);
+
+		var constrained:Vector.<Bone> = constraint.bones;
+		var boneCount:Number = constrained.length;
+		for (ii = 0; ii < boneCount; ii++)
+			sortBone(constrained[ii]);
+
+		_updateCache.push(constraint);
+
+		for (ii = 0; ii < boneCount; ii++)
+			sortReset(constrained[ii].children);
+		for (ii = 0; ii < boneCount; ii++)
+			constrained[ii]._sorted = true;
+	}
 
-			constrained = transformConstraint.bones;
-			boneCount = constrained.length;
-			for (ii = 0; ii < boneCount; ii++)
-				sortBone(constrained[ii]);
+	private function sortTransformConstraint (constraint:TransformConstraint): void {
+		sortBone(constraint.target);
 
-			updateCache.push(transformConstraint);
+		var constrained:Vector.<Bone> = constraint.bones;
+		var boneCount:Number = constrained.length;
+		var ii:Number = 0;
+		for (ii = 0; ii < boneCount; ii++)
+			sortBone(constrained[ii]);
 
-			for (ii = 0; ii < boneCount; ii++)
-				sortReset(constrained[ii].children);
-			for (ii = 0; ii < boneCount; ii++)
-				constrained[ii]._sorted = true;
-		}
+		_updateCache.push(constraint);
 
-		for (i = 0, n = bones.length; i < n; i++)
-			sortBone(bones[i]);
+		for (ii = 0; ii < boneCount; ii++)
+			sortReset(constrained[ii].children);
+		for (ii = 0; ii < boneCount; ii++)
+			constrained[ii]._sorted = true;
 	}
 	
 	private function sortPathConstraintAttachment (skin:Skin, slotIndex:int, slotBone:Bone) : void {
@@ -240,6 +249,17 @@ public class Skeleton {
 
 	/** Updates the world transform for each bone and applies constraints. */
 	public function updateWorldTransform () : void {
+		var updateCacheReset:Vector.<Bone> = this._updateCacheReset;
+		for each (var bone:Bone in updateCacheReset) {
+			bone.ax = bone.x;
+			bone.ay = bone.y;
+			bone.arotation = bone.rotation;
+			bone.ascaleX = bone.scaleX;
+			bone.ascaleY = bone.scaleY;
+			bone.ashearX = bone.shearX;
+			bone.ashearY = bone.shearY;
+			bone.appliedValid = true;
+		}
 		for each (var updatable:Updatable in _updateCache)
 			updatable.update();
 	}

+ 3 - 0
spine-as3/spine-as3/src/spine/SkeletonData.as

@@ -46,6 +46,9 @@ public class SkeletonData {
 	public var width:Number, height:Number;
 	public var version:String, hash:String;
 	
+	public var fps:Number;
+	public var imagesPath:String;
+	
 	public function SkeletonData () {		
 	}
 

+ 7 - 3
spine-as3/spine-as3/src/spine/SkeletonJson.as

@@ -89,7 +89,9 @@ public class SkeletonJson {
 			skeletonData.hash = skeletonMap["hash"];
 			skeletonData.version = skeletonMap["spine"];
 			skeletonData.width = skeletonMap["width"] || 0;
-			skeletonData.height = skeletonMap["height"] || 0;			
+			skeletonData.height = skeletonMap["height"] || 0;
+			skeletonData.fps = skeletonMap["fps"] || 0;
+			skeletonData.imagesPath = skeletonMap["images"];		
 		}			
 
 		// Bones.
@@ -110,8 +112,7 @@ public class SkeletonJson {
 			boneData.scaleY = boneMap.hasOwnProperty("scaleY") ? boneMap["scaleY"] : 1;
 			boneData.shearX = Number(boneMap["shearX"] || 0);
 			boneData.shearY = Number(boneMap["shearY"] || 0);
-			boneData.inheritRotation = boneMap.hasOwnProperty("inheritRotation") ? Boolean(boneMap["inheritRotation"]) : true;
-			boneData.inheritScale = boneMap.hasOwnProperty("inheritScale") ? Boolean(boneMap["inheritScale"]) : true;			
+			boneData.transformMode = TransformMode[boneMap["transform"] || "normal"];			
 			skeletonData.bones.push(boneData);
 		}
 		
@@ -139,6 +140,7 @@ public class SkeletonJson {
 		// IK constraints.
 		for each (var constraintMap:Object in root["ik"]) {
 			var ikConstraintData:IkConstraintData = new IkConstraintData(constraintMap["name"]);
+			ikConstraintData.order = constraintMap["order"] || 0;
 
 			for each (boneName in constraintMap["bones"]) {
 				var bone:BoneData = skeletonData.findBone(boneName);
@@ -158,6 +160,7 @@ public class SkeletonJson {
 		// Transform constraints.
 		for each (constraintMap in root["transform"]) {
 			var transformConstraintData:TransformConstraintData = new TransformConstraintData(constraintMap["name"]);
+			transformConstraintData.order = constraintMap["order"] || 0;
 
 			for each (boneName in constraintMap["bones"]) {
 				bone = skeletonData.findBone(boneName);
@@ -186,6 +189,7 @@ public class SkeletonJson {
 		// Path constraints.
 		for each (constraintMap in root["path"]) {
 			var pathConstraintData:PathConstraintData = new PathConstraintData(constraintMap["name"]);
+			pathConstraintData.order = constraintMap["order"] || 0;
 
 			for each (boneName in constraintMap["bones"]) {
 				bone = skeletonData.findBone(boneName);

+ 18 - 7
spine-as3/spine-as3/src/spine/TransformConstraint.as

@@ -30,7 +30,7 @@
 
 package spine {
 
-public class TransformConstraint implements Updatable {
+public class TransformConstraint implements Constraint {
 	internal var _data:TransformConstraintData;
 	internal var _bones:Vector.<Bone>;
 	public var target:Bone;
@@ -65,8 +65,9 @@ public class TransformConstraint implements Updatable {
 		var bones:Vector.<Bone> = this._bones;
 		for (var i:int = 0, n:int = bones.length; i < n; i++) {
 			var bone:Bone = bones[i];
+			var modified:Boolean = false;
 
-			if (rotateMix > 0) {
+			if (rotateMix != 0) {
 				var a:Number = bone.a, b:Number = bone.b, c:Number = bone.c, d:Number = bone.d;
 				var r:Number = Math.atan2(tc, ta) - Math.atan2(c, a) + data.offsetRotation * MathUtils.degRad;
 				if (r > Math.PI)
@@ -78,27 +79,30 @@ public class TransformConstraint implements Updatable {
 				bone._b = cos * b - sin * d;
 				bone._c = sin * a + cos * c;
 				bone._d = sin * b + cos * d;
+				modified = true;
 			}
 
-			if (translateMix > 0) {
+			if (translateMix != 0) {
 				_temp[0] = data.offsetX;
 				_temp[1] = data.offsetY;
 				target.localToWorld(_temp);
 				bone._worldX += (_temp[0] - bone.worldX) * translateMix;
 				bone._worldY += (_temp[1] - bone.worldY) * translateMix;
+				modified = true;
 			}
 
 			if (scaleMix > 0) {
-				var bs:Number = Math.sqrt(bone.a * bone.a + bone.c * bone.c);
+				var s:Number = Math.sqrt(bone.a * bone.a + bone.c * bone.c);
 				var ts:Number = Math.sqrt(ta * ta + tc * tc);
-				var s:Number = bs > 0.00001 ? (bs + (ts - bs + data.offsetScaleX) * scaleMix) / bs : 0;
+				if (s > 0.00001) s = (s + (ts - s + data.offsetScaleX) * scaleMix) / s;
 				bone._a *= s;
 				bone._c *= s;
-				bs = Math.sqrt(bone.b * bone.b + bone.d * bone.d);
+				s = Math.sqrt(bone.b * bone.b + bone.d * bone.d);
 				ts = Math.sqrt(tb * tb + td * td);
-				s = bs > 0.00001 ? (bs + (ts - bs + data.offsetScaleY) * scaleMix) / bs : 0;
+				if (s > 0.00001) s = (s + (ts - s + data.offsetScaleY) * scaleMix) / s;
 				bone._b *= s;
 				bone._d *= s;
+				modified = true;
 			}
 
 			if (shearMix > 0) {
@@ -112,9 +116,16 @@ public class TransformConstraint implements Updatable {
 				s = Math.sqrt(b * b + d * d);
 				bone._b = Math.cos(r) * s;
 				bone._d = Math.sin(r) * s;
+				modified = true;
 			}
+			
+			if (modified) bone.appliedValid = false;
 		}
 	}
+	
+	public function getOrder () : Number {
+		return _data.order;
+	}
 
 	public function get data () : TransformConstraintData {
 		return _data;

+ 1 - 0
spine-as3/spine-as3/src/spine/TransformConstraintData.as

@@ -32,6 +32,7 @@ package spine {
 
 public class TransformConstraintData {
 	internal var _name:String;
+	public var order:Number;
 	internal var _bones:Vector.<BoneData> = new Vector.<BoneData>();
 	public var target:BoneData;
 	public var rotateMix:Number;

+ 41 - 0
spine-as3/spine-as3/src/spine/TransformMode.as

@@ -0,0 +1,41 @@
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ *
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+package spine {
+
+public class TransformMode {
+	public static const normal:TransformMode = new TransformMode();
+	public static const onlyTranslation:TransformMode = new TransformMode();
+	public static const noRotationOrReflection:TransformMode = new TransformMode();
+	public static const noScale:TransformMode = new TransformMode();
+	public static const noScaleOrReflection:TransformMode = new TransformMode();
+}
+
+}

+ 5 - 6
spine-as3/spine-as3/src/spine/attachments/VertexAttachment.as

@@ -53,8 +53,7 @@ public dynamic class VertexAttachment extends Attachment {
 	 * @param offset The worldVertices index to begin writing values. */
 	public function computeWorldVertices2 (slot:Slot, start:int, count:int, worldVertices:Vector.<Number>, offset:int): void {
 		count += offset;
-		var skeleton:Skeleton = slot.skeleton;
-		var x:Number = skeleton.x, y:Number = skeleton.y;
+		var skeleton:Skeleton = slot.skeleton;		
 		var deformArray:Vector.<Number> = slot.attachmentVertices;
 		var vertices:Vector.<Number> = this.vertices;
 		var bones:Vector.<int> = this.bones;
@@ -68,8 +67,8 @@ public dynamic class VertexAttachment extends Attachment {
 		if (bones == null) {
 			if (deformArray.length > 0) vertices = deformArray;
 			bone = slot.bone;
-			x += bone.worldX;
-			y += bone.worldY;
+			var x:Number = bone.worldX;
+			var y:Number = bone.worldY;
 			var a:Number = bone.a, bb:Number = bone.b, c:Number = bone.c, d:Number = bone.d;
 			for (v = start, w = offset; w < count; v += 2, w += 2) {
 				vx = vertices[v], vy = vertices[v + 1];
@@ -87,7 +86,7 @@ public dynamic class VertexAttachment extends Attachment {
 		var skeletonBones:Vector.<Bone> = skeleton.bones;
 		if (deformArray.length == 0) {
 			for (w = offset, b = skip * 3; w < count; w += 2) {
-				wx = x, wy = y;
+				wx = 0, wy = 0;
 				n = bones[v++];
 				n += v;
 				for (; v < n; v++, b += 3) {
@@ -102,7 +101,7 @@ public dynamic class VertexAttachment extends Attachment {
 		} else {
 			deform = deformArray;
 			for (w = offset, b = skip * 3, f = skip << 1; w < count; w += 2) {
-				wx = x; wy = y;
+				wx = 0; wy = 0;
 				n = bones[v++];
 				n += v;
 				for (; v < n; v++, b += 3, f += 2) {

+ 2 - 1
spine-starling/spine-starling-example/src/spine/examples/Main.as

@@ -43,8 +43,9 @@ public class Main extends Sprite {
 		// example = SpineboyExample;
 		// example = GoblinsExample;
 		// example = RaptorExample;
-		example = TankExample;
+		// example = TankExample;
 		// example = VineExample;
+		example = StretchymanExample;
 
 		_starling = new Starling(example, stage);
 		_starling.enableErrorChecking = true;

+ 94 - 0
spine-starling/spine-starling-example/src/spine/examples/StretchymanExample.as

@@ -0,0 +1,94 @@
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ *
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+package spine.examples {
+import spine.animation.AnimationStateData;
+import spine.*;
+import spine.atlas.Atlas;
+import spine.attachments.AtlasAttachmentLoader;
+import spine.attachments.AttachmentLoader;
+import spine.starling.SkeletonAnimation;
+import spine.starling.StarlingTextureLoader;
+
+import starling.core.Starling;
+import starling.display.Sprite;
+import starling.events.Touch;
+import starling.events.TouchEvent;
+import starling.events.TouchPhase;
+
+public class StretchymanExample extends Sprite {
+	[Embed(source = "/stretchyman.json", mimeType = "application/octet-stream")]
+	static public const StretchymanJson:Class;
+
+	[Embed(source = "/stretchyman.atlas", mimeType = "application/octet-stream")]
+	static public const StretchymanAtlas:Class;
+
+	[Embed(source = "/stretchyman.png")]
+	static public const StretchymanAtlasTexture:Class;
+
+	private var skeleton:SkeletonAnimation;
+
+	public function StretchymanExample () {
+		var spineAtlas:Atlas = new Atlas(new StretchymanAtlas(), new StarlingTextureLoader(new StretchymanAtlasTexture()));
+		var attachmentLoader:AttachmentLoader = new AtlasAttachmentLoader(spineAtlas);
+		var json:SkeletonJson = new SkeletonJson(attachmentLoader);
+		json.scale = 0.4;
+		var skeletonData:SkeletonData = json.readSkeletonData(new StretchymanJson());
+
+		var stateData:AnimationStateData = new AnimationStateData(skeletonData);
+
+		skeleton = new SkeletonAnimation(skeletonData, stateData);
+		skeleton.x = 100;
+		skeleton.y = 560;
+		
+		skeleton.state.timeScale = 0.1;
+		
+		skeleton.state.onStart.add(function (trackIndex:int) : void {
+			trace(trackIndex + " start: " + skeleton.state.getCurrent(trackIndex));
+		});
+		skeleton.state.onEnd.add(function (trackIndex:int) : void {
+			trace(trackIndex + " end: " + skeleton.state.getCurrent(trackIndex));
+		});
+		skeleton.state.onComplete.add(function (trackIndex:int, count:int) : void {
+			trace(trackIndex + " complete: " + skeleton.state.getCurrent(trackIndex) + ", " + count);
+		});
+		skeleton.state.onEvent.add(function (trackIndex:int, event:Event) : void {
+			trace(trackIndex + " event: " + skeleton.state.getCurrent(trackIndex) + ", "
+				+ event.data.name + ": " + event.intValue + ", " + event.floatValue + ", " + event.stringValue);
+		});
+
+		skeleton.skeleton.setToSetupPose();
+		skeleton.state.setAnimationByName(0, "sneak", true);
+
+		addChild(skeleton);
+		Starling.juggler.add(skeleton);		
+	}
+}
+}

+ 41 - 0
spine-starling/spine-starling-example/src/stretchyman.atlas

@@ -0,0 +1,41 @@
+
+stretchyman.png
+size: 1024,256
+format: RGBA8888
+filter: Linear,Linear
+repeat: none
+back arm
+  rotate: true
+  xy: 679, 173
+  size: 72, 202
+  orig: 72, 202
+  offset: 0, 0
+  index: -1
+back leg
+  rotate: true
+  xy: 2, 2
+  size: 100, 318
+  orig: 100, 318
+  offset: 0, 0
+  index: -1
+body
+  rotate: true
+  xy: 2, 104
+  size: 141, 452
+  orig: 141, 452
+  offset: 0, 0
+  index: -1
+front arm
+  rotate: true
+  xy: 456, 100
+  size: 145, 221
+  orig: 145, 221
+  offset: 0, 0
+  index: -1
+head
+  rotate: true
+  xy: 322, 15
+  size: 87, 102
+  orig: 87, 102
+  offset: 0, 0
+  index: -1

Разница между файлами не показана из-за своего большого размера
+ 202 - 0
spine-starling/spine-starling-example/src/stretchyman.json


BIN
spine-starling/spine-starling-example/src/stretchyman.png


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