mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 14:24:53 +08:00
[as3][starling] Updated to 3.5, path constraint may still have an issue, see stretchyman
This commit is contained in:
parent
71702a451a
commit
8b327f3d54
@ -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/*
|
||||
|
||||
@ -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);
|
||||
_worldY = pc * x + pd * y + parent._worldY;
|
||||
|
||||
if (data.inheritRotation && data.inheritScale) {
|
||||
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 {
|
||||
|
||||
@ -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
spine-as3/spine-as3/src/spine/Constraint.as
Normal file
37
spine-as3/spine-as3/src/spine/Constraint.as
Normal file
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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,103 +98,112 @@ 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;
|
||||
}
|
||||
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);
|
||||
|
||||
updateCache.push(ikConstraint);
|
||||
|
||||
sortReset(parent.children);
|
||||
constrained[constrained.length - 1]._sorted = true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
var ikConstraints:Vector.<IkConstraint> = this.ikConstraints;
|
||||
var transformConstraints:Vector.<TransformConstraint> = this.transformConstraints;
|
||||
for (i = 0, n = transformConstraints.length; i < n; i++) {
|
||||
var transformConstraint:TransformConstraint = transformConstraints[i];
|
||||
|
||||
sortBone(transformConstraint.target);
|
||||
|
||||
constrained = transformConstraint.bones;
|
||||
boneCount = constrained.length;
|
||||
for (ii = 0; ii < boneCount; ii++)
|
||||
sortBone(constrained[ii]);
|
||||
|
||||
updateCache.push(transformConstraint);
|
||||
|
||||
for (ii = 0; ii < boneCount; ii++)
|
||||
sortReset(constrained[ii].children);
|
||||
for (ii = 0; ii < boneCount; ii++)
|
||||
constrained[ii]._sorted = true;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
var constrained:Vector.<Bone> = constraint.bones;
|
||||
var parent:Bone = constrained[0];
|
||||
sortBone(parent);
|
||||
|
||||
if (constrained.length > 1) {
|
||||
var child:Bone = constrained[constrained.length - 1];
|
||||
if (!(_updateCache.indexOf(child) > -1)) _updateCacheReset.push(child);
|
||||
}
|
||||
|
||||
_updateCache.push(constraint);
|
||||
|
||||
sortReset(parent.children);
|
||||
constrained[constrained.length - 1]._sorted = true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
private function sortTransformConstraint (constraint:TransformConstraint): void {
|
||||
sortBone(constraint.target);
|
||||
|
||||
var constrained:Vector.<Bone> = constraint.bones;
|
||||
var boneCount:Number = constrained.length;
|
||||
var ii:Number = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
private function sortPathConstraintAttachment (skin:Skin, slotIndex:int, slotBone:Bone) : void {
|
||||
var dict:Dictionary = skin.attachments[slotIndex];
|
||||
if (!dict) return;
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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 () {
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
spine-as3/spine-as3/src/spine/TransformMode.as
Normal file
41
spine-as3/spine-as3/src/spine/TransformMode.as
Normal file
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
spine-starling/spine-starling-example/src/stretchyman.atlas
Normal file
41
spine-starling/spine-starling-example/src/stretchyman.atlas
Normal file
@ -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
|
||||
773
spine-starling/spine-starling-example/src/stretchyman.json
Normal file
773
spine-starling/spine-starling-example/src/stretchyman.json
Normal file
File diff suppressed because one or more lines are too long
BIN
spine-starling/spine-starling-example/src/stretchyman.png
Normal file
BIN
spine-starling/spine-starling-example/src/stretchyman.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 131 KiB |
Loading…
x
Reference in New Issue
Block a user