mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-11 17:48:45 +08:00
[as3][starling] Ported 3.6 changes, two color timeline, changed updateWorldVertices to computeWorldVertices, point attachment, transform constraint local and relative mode. Does not actually render two color tinted slots yet.
This commit is contained in:
parent
e49b587fa8
commit
7ac7afac2c
Binary file not shown.
@ -1,2 +1,4 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/spine/animation/TwoColorTimeline.as=UTF-8
|
||||
encoding//src/spine/attachments/PointAttachment.as=UTF-8
|
||||
encoding/<project>=UTF-8
|
||||
|
||||
@ -53,12 +53,12 @@ public class Bone implements Updatable {
|
||||
public var ashearY:Number;
|
||||
public var appliedValid:Boolean;
|
||||
|
||||
internal var _a:Number;
|
||||
internal var _b:Number;
|
||||
internal var _c:Number;
|
||||
internal var _d:Number;
|
||||
internal var _worldX:Number;
|
||||
internal var _worldY:Number;
|
||||
public var a:Number;
|
||||
public var b:Number;
|
||||
public var c:Number;
|
||||
public var d:Number;
|
||||
public var worldX:Number;
|
||||
public var worldY:Number;
|
||||
|
||||
internal var _sorted:Boolean;
|
||||
|
||||
@ -115,38 +115,38 @@ public class Bone implements Updatable {
|
||||
lc = -lc;
|
||||
ld = -ld;
|
||||
}
|
||||
_a = la;
|
||||
_b = lb;
|
||||
_c = lc;
|
||||
_d = ld;
|
||||
_worldX = x + skeleton.x;
|
||||
_worldY = y + skeleton.y;
|
||||
this.a = la;
|
||||
this.b = lb;
|
||||
this.c = lc;
|
||||
this.d = ld;
|
||||
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;
|
||||
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;
|
||||
|
||||
switch (_data.transformMode) {
|
||||
switch (this.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;
|
||||
this.a = pa * la + pb * lc;
|
||||
this.b = pa * lb + pb * ld;
|
||||
this.c = pc * la + pd * lc;
|
||||
this.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;
|
||||
this.a = MathUtils.cosDeg(rotation + shearX) * scaleX;
|
||||
this.b = MathUtils.cosDeg(rotationY) * scaleY;
|
||||
this.c = MathUtils.sinDeg(rotation + shearX) * scaleX;
|
||||
this.d = MathUtils.sinDeg(rotationY) * scaleY;
|
||||
break;
|
||||
}
|
||||
case TransformMode.noRotationOrReflection: {
|
||||
@ -168,10 +168,10 @@ public class Bone implements Updatable {
|
||||
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;
|
||||
this.a = pa * la - pb * lc;
|
||||
this.b = pa * lb - pb * ld;
|
||||
this.c = pc * la + pd * lc;
|
||||
this.d = pc * lb + pd * ld;
|
||||
break;
|
||||
}
|
||||
case TransformMode.noScale:
|
||||
@ -192,35 +192,35 @@ public class Bone implements Updatable {
|
||||
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;
|
||||
_d = -_d;
|
||||
this.a = za * la + zb * lc;
|
||||
this.b = za * lb + zb * ld;
|
||||
this.c = zc * la + zd * lc;
|
||||
this.d = zc * lb + zd * ld;
|
||||
if (this.data.transformMode != TransformMode.noScaleOrReflection ? pa * pd - pb * pc < 0 : skeleton.flipX != skeleton.flipY) {
|
||||
this.b = -this.b;
|
||||
this.d = -this.d;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_skeleton.flipX) {
|
||||
_a = -_a;
|
||||
_b = -_b;
|
||||
this.a = -this.a;
|
||||
this.b = -this.b;
|
||||
}
|
||||
if (_skeleton.flipY != yDown) {
|
||||
_c = -_c;
|
||||
_d = -_d;
|
||||
this.c = -this.c;
|
||||
this.d = -this.d;
|
||||
}
|
||||
}
|
||||
|
||||
public function setToSetupPose () : void {
|
||||
x = _data.x;
|
||||
y = _data.y;
|
||||
rotation = _data.rotation;
|
||||
scaleX = _data.scaleX;
|
||||
scaleY = _data.scaleY;
|
||||
shearX = _data.shearX;
|
||||
shearY = _data.shearY;
|
||||
x = this.data.x;
|
||||
y = this.data.y;
|
||||
rotation = this.data.rotation;
|
||||
scaleX = this.data.scaleX;
|
||||
scaleY = this.data.scaleY;
|
||||
shearX = this.data.shearX;
|
||||
shearY = this.data.shearY;
|
||||
}
|
||||
|
||||
public function get data () : BoneData {
|
||||
@ -237,70 +237,22 @@ public class Bone implements Updatable {
|
||||
|
||||
public function get children () : Vector.<Bone> {;
|
||||
return _children;
|
||||
}
|
||||
|
||||
public function get a () : Number {
|
||||
return _a;
|
||||
}
|
||||
|
||||
public function get b () : Number {
|
||||
return _b;
|
||||
}
|
||||
|
||||
public function get c () : Number {
|
||||
return _c;
|
||||
}
|
||||
|
||||
public function get d () : Number {
|
||||
return _d;
|
||||
}
|
||||
|
||||
public function get worldX () : Number {
|
||||
return _worldX;
|
||||
}
|
||||
|
||||
public function get worldY () : Number {
|
||||
return _worldY;
|
||||
}
|
||||
}
|
||||
|
||||
public function get worldRotationX () : Number {
|
||||
return Math.atan2(_c, _a) * MathUtils.radDeg;
|
||||
return Math.atan2(this.c, this.a) * MathUtils.radDeg;
|
||||
}
|
||||
|
||||
public function get worldRotationY () : Number {
|
||||
return Math.atan2(_d, _b) * MathUtils.radDeg;
|
||||
return Math.atan2(this.d, this.b) * MathUtils.radDeg;
|
||||
}
|
||||
|
||||
public function get worldScaleX () : Number {
|
||||
return Math.sqrt(_a * _a + _c * _c);
|
||||
return Math.sqrt(this.a * this.a + this.c * this.c);
|
||||
}
|
||||
|
||||
public function get worldScaleY () : Number {
|
||||
return Math.sqrt(_b * _b + _d * _d);
|
||||
}
|
||||
|
||||
public function worldToLocalRotationX () : Number {
|
||||
var parent:Bone = _parent;
|
||||
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 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;
|
||||
}
|
||||
|
||||
public function rotateWorld (degrees:Number) : void {
|
||||
var a:Number = this.a, b:Number = this.b, c:Number = this.c, d:Number = this.d;
|
||||
var cos:Number = MathUtils.cosDeg(degrees), sin:Number = MathUtils.sinDeg(degrees);
|
||||
this._a = cos * a - sin * c;
|
||||
this._b = cos * b - sin * d;
|
||||
this._c = sin * a + cos * c;
|
||||
this._d = sin * b + cos * d;
|
||||
this.appliedValid = false;
|
||||
return Math.sqrt(this.b * this.b + this.d * this.d);
|
||||
}
|
||||
|
||||
/** Computes the individual applied transform values from the world transform. This can be useful to perform processing using
|
||||
@ -349,21 +301,41 @@ public class Bone implements Updatable {
|
||||
}
|
||||
|
||||
public function worldToLocal (world:Vector.<Number>) : void {
|
||||
var a:Number = _a, b:Number = _b, c:Number = _c, d:Number = _d;
|
||||
var a:Number = this.a, b:Number = this.b, c:Number = this.c, d:Number = this.d;
|
||||
var invDet:Number = 1 / (a * d - b * c);
|
||||
var x:Number = world[0] - _worldX, y:Number = world[1] - _worldY;
|
||||
var x:Number = world[0] - this.worldX, y:Number = world[1] - this.worldY;
|
||||
world[0] = (x * d * invDet - y * b * invDet);
|
||||
world[1] = (y * a * invDet - x * c * invDet);
|
||||
}
|
||||
|
||||
public function localToWorld (local:Vector.<Number>) : void {
|
||||
var localX:Number = local[0], localY:Number = local[1];
|
||||
local[0] = localX * _a + localY * _b + _worldX;
|
||||
local[1] = localX * _c + localY * _d + _worldY;
|
||||
local[0] = localX * this.a + localY * this.b + this.worldX;
|
||||
local[1] = localX * this.c + localY * this.d + this.worldY;
|
||||
}
|
||||
|
||||
public function worldToLocalRotation (worldRotation:Number) : Number {
|
||||
var sin:Number = MathUtils.sinDeg(worldRotation), cos:Number = MathUtils.cosDeg(worldRotation);
|
||||
return Math.atan2(this.a * sin - this.c * cos, this.d * cos - this.b * sin) * MathUtils.radDeg;
|
||||
}
|
||||
|
||||
public function localToWorldRotation (localRotation:Number) : Number {
|
||||
var sin:Number = MathUtils.sinDeg(localRotation), cos:Number = MathUtils.cosDeg(localRotation);
|
||||
return Math.atan2(cos * this.c + sin * this.d, cos * this.a + sin * this.b) * MathUtils.radDeg;
|
||||
}
|
||||
|
||||
public function rotateWorld (degrees:Number) : void {
|
||||
var a:Number = this.a, b:Number = this.b, c:Number = this.c, d:Number = this.d;
|
||||
var cos:Number = MathUtils.cosDeg(degrees), sin:Number = MathUtils.sinDeg(degrees);
|
||||
this.a = cos * a - sin * c;
|
||||
this.b = cos * b - sin * d;
|
||||
this.c = sin * a + cos * c;
|
||||
this.d = sin * b + cos * d;
|
||||
this.appliedValid = false;
|
||||
}
|
||||
|
||||
public function toString () : String {
|
||||
return _data._name;
|
||||
return this.data._name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
101
spine-as3/spine-as3/src/spine/Color.as
Normal file
101
spine-as3/spine-as3/src/spine/Color.as
Normal file
@ -0,0 +1,101 @@
|
||||
/******************************************************************************
|
||||
* 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 Color {
|
||||
public static var WHITE:Color = new Color(1, 1, 1, 1);
|
||||
public static var RED:Color = new Color(1, 0, 0, 1);
|
||||
public static var GREEN:Color = new Color(0, 1, 0, 1);
|
||||
public static var BLUE:Color = new Color(0, 0, 1, 1);
|
||||
public static var MAGENTA:Color = new Color(1, 0, 1, 1);
|
||||
|
||||
public var r:Number = 0;
|
||||
public var g:Number = 0;
|
||||
public var b:Number = 0;
|
||||
public var a:Number = 0;
|
||||
|
||||
public function Color (r:Number, g:Number, b:Number, a:Number = 0) {
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
public function setFrom (r:Number, g:Number, b:Number, a:Number): Color {
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
this.a = a;
|
||||
this.clamp();
|
||||
return this;
|
||||
}
|
||||
|
||||
public function setFromColor (c:Color): Color{
|
||||
this.r = c.r;
|
||||
this.g = c.g;
|
||||
this.b = c.b;
|
||||
this.a = c.a;
|
||||
return this;
|
||||
}
|
||||
|
||||
public function setFromString (hex:String): Color {
|
||||
hex = hex.charAt(0) == '#' ? hex.substr(1) : hex;
|
||||
this.r = parseInt(hex.substr(0, 2), 16) / 255.0;
|
||||
this.g = parseInt(hex.substr(2, 2), 16) / 255.0;
|
||||
this.b = parseInt(hex.substr(4, 2), 16) / 255.0;
|
||||
this.a = (hex.length != 8 ? 255 : parseInt(hex.substr(6, 2), 16)) / 255.0;
|
||||
return this;
|
||||
}
|
||||
|
||||
public function add (r:Number, g:Number, b:Number, a:Number): Color {
|
||||
this.r += r;
|
||||
this.g += g;
|
||||
this.b += b;
|
||||
this.a += a;
|
||||
this.clamp();
|
||||
return this;
|
||||
}
|
||||
|
||||
public function clamp (): Color {
|
||||
if (this.r < 0) this.r = 0;
|
||||
else if (this.r > 1) this.r = 1;
|
||||
|
||||
if (this.g < 0) this.g = 0;
|
||||
else if (this.g > 1) this.g = 1;
|
||||
|
||||
if (this.b < 0) this.b = 0;
|
||||
else if (this.b > 1) this.b = 1;
|
||||
|
||||
if (this.a < 0) this.a = 0;
|
||||
else if (this.a > 1) this.a = 1;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -57,10 +57,10 @@ public class IkConstraint implements Constraint {
|
||||
public function update () : void {
|
||||
switch (bones.length) {
|
||||
case 1:
|
||||
apply1(bones[0], target._worldX, target._worldY, mix);
|
||||
apply1(bones[0], target.worldX, target.worldY, mix);
|
||||
break;
|
||||
case 2:
|
||||
apply2(bones[0], bones[1], target._worldX, target._worldY, bendDirection, mix);
|
||||
apply2(bones[0], bones[1], target.worldX, target.worldY, bendDirection, mix);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,6 +31,8 @@
|
||||
package spine {
|
||||
|
||||
public class MathUtils {
|
||||
static public var PI:Number = Math.PI;
|
||||
static public var PI2:Number = Math.PI * 2;
|
||||
static public var radDeg:Number = 180 / Math.PI;
|
||||
static public var degRad:Number = Math.PI / 180;
|
||||
|
||||
|
||||
@ -89,10 +89,10 @@ public class PathConstraint implements Constraint {
|
||||
}
|
||||
for (var i:int = 0, n:int = spacesCount - 1; i < n;) {
|
||||
var bone:Bone = bones[i];
|
||||
var length:Number = bone.data.length, x:Number = length * bone.a, y:Number = length * bone.c;
|
||||
length = Math.sqrt(x * x + y * y);
|
||||
var setupLength:Number = bone.data.length, x:Number = setupLength * bone.a, y:Number = setupLength * bone.c;
|
||||
var length:Number = Math.sqrt(x * x + y * y);
|
||||
if (scale) lengths[i] = length;
|
||||
spaces[++i] = lengthSpacing ? Math.max(0, length + spacing) : spacing;
|
||||
spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength;
|
||||
}
|
||||
} else {
|
||||
for (i = 1; i < spacesCount; i++)
|
||||
@ -113,15 +113,15 @@ public class PathConstraint implements Constraint {
|
||||
var p:Number;
|
||||
for (i = 0, p = 3; i < boneCount; i++, p += 3) {
|
||||
bone = bones[i];
|
||||
bone._worldX += (boneX - bone.worldX) * translateMix;
|
||||
bone._worldY += (boneY - 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];
|
||||
if (length != 0) {
|
||||
var s:Number = (Math.sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1;
|
||||
bone._a *= s;
|
||||
bone._c *= s;
|
||||
bone.a *= s;
|
||||
bone.c *= s;
|
||||
}
|
||||
}
|
||||
boneX = x;
|
||||
@ -151,10 +151,10 @@ public class PathConstraint implements Constraint {
|
||||
r *= rotateMix;
|
||||
cos = Math.cos(r);
|
||||
sin = Math.sin(r);
|
||||
bone._a = cos * a - sin * c;
|
||||
bone._b = cos * b - sin * d;
|
||||
bone._c = sin * a + cos * c;
|
||||
bone._d = sin * b + cos * d;
|
||||
bone.a = cos * a - sin * c;
|
||||
bone.b = cos * b - sin * d;
|
||||
bone.c = sin * a + cos * c;
|
||||
bone.d = sin * b + cos * d;
|
||||
}
|
||||
bone.appliedValid = false;
|
||||
}
|
||||
@ -194,14 +194,14 @@ public class PathConstraint implements Constraint {
|
||||
} else if (p < 0) {
|
||||
if (prevCurve != BEFORE) {
|
||||
prevCurve = BEFORE;
|
||||
path.computeWorldVertices2(target, 2, 4, world, 0);
|
||||
path.computeWorldVertices(target, 2, 4, world, 0, 2);
|
||||
}
|
||||
addBeforePosition(p, world, 0, out, o);
|
||||
continue;
|
||||
} else if (p > pathLength) {
|
||||
if (prevCurve != AFTER) {
|
||||
prevCurve = AFTER;
|
||||
path.computeWorldVertices2(target, verticesLength - 6, 4, world, 0);
|
||||
path.computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2);
|
||||
}
|
||||
addAfterPosition(p - pathLength, world, 0, out, o);
|
||||
continue;
|
||||
@ -222,10 +222,10 @@ public class PathConstraint implements Constraint {
|
||||
if (curve != prevCurve) {
|
||||
prevCurve = curve;
|
||||
if (closed && curve == curveCount) {
|
||||
path.computeWorldVertices2(target, verticesLength - 4, 4, world, 0);
|
||||
path.computeWorldVertices2(target, 0, 4, world, 4);
|
||||
path.computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2);
|
||||
path.computeWorldVertices(target, 0, 4, world, 4, 2);
|
||||
} else
|
||||
path.computeWorldVertices2(target, curve * 6 + 2, 8, world, 0);
|
||||
path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2);
|
||||
}
|
||||
addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o,
|
||||
tangents || (i > 0 && space == 0));
|
||||
@ -238,8 +238,8 @@ public class PathConstraint implements Constraint {
|
||||
verticesLength += 2;
|
||||
this._world.length = verticesLength;
|
||||
world = this._world;
|
||||
path.computeWorldVertices2(target, 2, verticesLength - 4, world, 0);
|
||||
path.computeWorldVertices2(target, 0, 2, world, verticesLength - 4);
|
||||
path.computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2);
|
||||
path.computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2);
|
||||
world[verticesLength - 2] = world[0];
|
||||
world[verticesLength - 1] = world[1];
|
||||
} else {
|
||||
@ -247,7 +247,7 @@ public class PathConstraint implements Constraint {
|
||||
verticesLength -= 4;
|
||||
this._world.length = verticesLength;
|
||||
world = this._world;
|
||||
path.computeWorldVertices2(target, 2, verticesLength, world, 0);
|
||||
path.computeWorldVertices(target, 2, verticesLength, world, 0, 2);
|
||||
}
|
||||
|
||||
// Curve lengths.
|
||||
|
||||
@ -29,6 +29,8 @@
|
||||
*****************************************************************************/
|
||||
|
||||
package spine {
|
||||
import spine.attachments.MeshAttachment;
|
||||
import spine.attachments.RegionAttachment;
|
||||
import flash.utils.Dictionary;
|
||||
import spine.attachments.PathAttachment;
|
||||
import spine.attachments.Attachment;
|
||||
@ -44,7 +46,7 @@ public class Skeleton {
|
||||
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 color:Color = new Color(1, 1, 1, 1);
|
||||
public var time:Number = 0;
|
||||
public var flipX:Boolean, flipY:Boolean;
|
||||
public var x:Number = 0, y:Number = 0;
|
||||
@ -167,25 +169,25 @@ public class Skeleton {
|
||||
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 i:Number = 0;
|
||||
var n:Number = 0;
|
||||
for (i = 0, n = data.skins.length; i < n; i++)
|
||||
sortPathConstraintAttachment(data.skins[i], 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]);
|
||||
for (i = 0; i < boneCount; i++)
|
||||
sortBone(constrained[i]);
|
||||
|
||||
_updateCache.push(constraint);
|
||||
|
||||
for (ii = 0; ii < boneCount; ii++)
|
||||
sortReset(constrained[ii].children);
|
||||
for (ii = 0; ii < boneCount; ii++)
|
||||
constrained[ii]._sorted = true;
|
||||
for (i = 0; i < boneCount; i++)
|
||||
sortReset(constrained[i].children);
|
||||
for (i = 0; i < boneCount; i++)
|
||||
constrained[i]._sorted = true;
|
||||
}
|
||||
|
||||
private function sortTransformConstraint (constraint:TransformConstraint): void {
|
||||
@ -193,16 +195,24 @@ public class Skeleton {
|
||||
|
||||
var constrained:Vector.<Bone> = constraint.bones;
|
||||
var boneCount:Number = constrained.length;
|
||||
var ii:Number = 0;
|
||||
for (ii = 0; ii < boneCount; ii++)
|
||||
sortBone(constrained[ii]);
|
||||
var i:Number = 0;
|
||||
if (constraint.data.local) {
|
||||
for (i = 0; i < boneCount; i++) {
|
||||
var child:Bone = constrained[constrained.length - 1];
|
||||
sortBone(child.parent);
|
||||
if (!(_updateCache.indexOf(child) > -1)) _updateCacheReset.push(child);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < boneCount; i++)
|
||||
sortBone(constrained[i]);
|
||||
}
|
||||
|
||||
_updateCache.push(constraint);
|
||||
|
||||
for (ii = 0; ii < boneCount; ii++)
|
||||
sortReset(constrained[ii].children);
|
||||
for (ii = 0; ii < boneCount; ii++)
|
||||
constrained[ii]._sorted = true;
|
||||
for (i = 0; i < boneCount; i++)
|
||||
sortReset(constrained[i].children);
|
||||
for (i = 0; i < boneCount; i++)
|
||||
constrained[i]._sorted = true;
|
||||
}
|
||||
|
||||
private function sortPathConstraintAttachment (skin:Skin, slotIndex:int, slotBone:Bone) : void {
|
||||
@ -464,6 +474,44 @@ public class Skeleton {
|
||||
public function toString () : String {
|
||||
return _data.name != null ? _data.name : super.toString();
|
||||
}
|
||||
|
||||
public function getBounds (offset: Vector.<Number>, size: Vector.<Number>, temp: Vector.<Number>) : void {
|
||||
if (offset == null) throw new ArgumentError("offset cannot be null.");
|
||||
if (size == null) throw new ArgumentError("size cannot be null.");
|
||||
var drawOrder:Vector.<Slot> = this.drawOrder;
|
||||
var minX:Number = Number.POSITIVE_INFINITY, minY:Number = Number.POSITIVE_INFINITY, maxX:Number = Number.NEGATIVE_INFINITY, maxY:Number = Number.NEGATIVE_INFINITY;
|
||||
for (var i:int = 0, n:int = drawOrder.length; i < n; i++) {
|
||||
var slot:Slot = drawOrder[i];
|
||||
var verticesLength:int = 0;
|
||||
var vertices: Vector.<Number> = null;
|
||||
var attachment:Attachment = slot.attachment;
|
||||
if (attachment is RegionAttachment) {
|
||||
verticesLength = 8;
|
||||
temp.length = verticesLength;
|
||||
vertices = temp;
|
||||
(attachment as RegionAttachment).computeWorldVertices(slot.bone, vertices, 0, 2);
|
||||
} else if (attachment is MeshAttachment) {
|
||||
var mesh:MeshAttachment = attachment as MeshAttachment;
|
||||
verticesLength = mesh.worldVerticesLength;
|
||||
temp.length = verticesLength;
|
||||
vertices = temp;
|
||||
mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2);
|
||||
}
|
||||
if (vertices != null) {
|
||||
for (var ii:int = 0, nn:int = vertices.length; ii < nn; ii += 8) {
|
||||
var x:Number = vertices[ii], y:Number = vertices[ii + 1];
|
||||
minX = Math.min(minX, x);
|
||||
minY = Math.min(minY, y);
|
||||
maxX = Math.max(maxX, x);
|
||||
maxY = Math.max(maxY, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
offset[0] = minX;
|
||||
offset[1] = minY;
|
||||
size[0] = maxX - minX;
|
||||
size[1] = maxY - minY;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ public class SkeletonBounds {
|
||||
polygons[polygons.length] = polygon;
|
||||
|
||||
polygon.vertices.length = boundingBox.worldVerticesLength;
|
||||
boundingBox.computeWorldVertices(slot, polygon.vertices);
|
||||
boundingBox.computeWorldVertices(slot, 0, boundingBox.worldVerticesLength, polygon.vertices, 0, 2);
|
||||
}
|
||||
|
||||
if (updateAabb)
|
||||
|
||||
@ -29,6 +29,8 @@
|
||||
*****************************************************************************/
|
||||
|
||||
package spine {
|
||||
import spine.animation.TwoColorTimeline;
|
||||
import spine.attachments.PointAttachment;
|
||||
import spine.animation.PathConstraintMixTimeline;
|
||||
import spine.animation.PathConstraintSpacingTimeline;
|
||||
import spine.animation.PathConstraintPositionTimeline;
|
||||
@ -126,10 +128,12 @@ public class SkeletonJson {
|
||||
|
||||
var color:String = slotMap["color"];
|
||||
if (color) {
|
||||
slotData.r = toColor(color, 0);
|
||||
slotData.g = toColor(color, 1);
|
||||
slotData.b = toColor(color, 2);
|
||||
slotData.a = toColor(color, 3);
|
||||
slotData.color.setFrom(toColor(color, 0), toColor(color, 1), toColor(color, 2), toColor(color, 3));
|
||||
}
|
||||
|
||||
var dark:String = slotMap["dark"];
|
||||
if (dark) {
|
||||
slotData.darkColor.setFrom(toColor(dark, 0), toColor(dark, 1), toColor(dark, 2), toColor(dark, 3));
|
||||
}
|
||||
|
||||
slotData.attachmentName = slotMap["attachment"];
|
||||
@ -288,10 +292,7 @@ public class SkeletonJson {
|
||||
region.height = Number(map["height"] || 0) * scale;
|
||||
color = map["color"];
|
||||
if (color) {
|
||||
region.r = toColor(color, 0);
|
||||
region.g = toColor(color, 1);
|
||||
region.b = toColor(color, 2);
|
||||
region.a = toColor(color, 3);
|
||||
region.color.setFrom(toColor(color, 0), toColor(color, 1), toColor(color, 2), toColor(color, 3));
|
||||
}
|
||||
region.updateOffset();
|
||||
return region;
|
||||
@ -303,10 +304,7 @@ public class SkeletonJson {
|
||||
|
||||
color = map["color"];
|
||||
if (color) {
|
||||
mesh.r = toColor(color, 0);
|
||||
mesh.g = toColor(color, 1);
|
||||
mesh.b = toColor(color, 2);
|
||||
mesh.a = toColor(color, 3);
|
||||
mesh.color.setFrom(toColor(color, 0), toColor(color, 1), toColor(color, 2), toColor(color, 3));
|
||||
}
|
||||
|
||||
mesh.width = Number(map["width"] || 0) * scale;
|
||||
@ -347,6 +345,18 @@ public class SkeletonJson {
|
||||
}
|
||||
path.lengths = lengths;
|
||||
return path;
|
||||
case AttachmentType.point:
|
||||
var point:PointAttachment = attachmentLoader.newPointAttachment(skin, name);
|
||||
if (!point) return null;
|
||||
point.x = map.hasOwnProperty("x") ? Number(map["x"]) * scale : 0;
|
||||
point.y = map.hasOwnProperty("y") ? Number(map["y"]) * scale : 0;
|
||||
point.rotation = map.hasOwnProperty("rotation") ? Number(map["rotation"]) : 0;
|
||||
|
||||
color = map["color"];
|
||||
if (color) {
|
||||
point.color.setFrom(toColor(color, 0), toColor(color, 1), toColor(color, 2), toColor(color, 3));
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -400,7 +410,16 @@ public class SkeletonJson {
|
||||
|
||||
for (timelineName in slotMap) {
|
||||
values = slotMap[timelineName];
|
||||
if (timelineName == "color") {
|
||||
if (timelineName == "attachment") {
|
||||
var attachmentTimeline:AttachmentTimeline = new AttachmentTimeline(values.length);
|
||||
attachmentTimeline.slotIndex = slotIndex;
|
||||
|
||||
frameIndex = 0;
|
||||
for each (valueMap in values)
|
||||
attachmentTimeline.setFrame(frameIndex++, valueMap["time"], valueMap["name"]);
|
||||
timelines[timelines.length] = attachmentTimeline;
|
||||
duration = Math.max(duration, attachmentTimeline.frames[attachmentTimeline.frameCount - 1]);
|
||||
} else if (timelineName == "color") {
|
||||
var colorTimeline:ColorTimeline = new ColorTimeline(values.length);
|
||||
colorTimeline.slotIndex = slotIndex;
|
||||
|
||||
@ -417,15 +436,24 @@ public class SkeletonJson {
|
||||
}
|
||||
timelines[timelines.length] = colorTimeline;
|
||||
duration = Math.max(duration, colorTimeline.frames[(colorTimeline.frameCount - 1) * ColorTimeline.ENTRIES]);
|
||||
} else if (timelineName == "attachment") {
|
||||
var attachmentTimeline:AttachmentTimeline = new AttachmentTimeline(values.length);
|
||||
attachmentTimeline.slotIndex = slotIndex;
|
||||
} else if (timelineName == "twoColor") {
|
||||
var twoColorTimeline:TwoColorTimeline = new TwoColorTimeline(values.length);
|
||||
twoColorTimeline.slotIndex = slotIndex;
|
||||
|
||||
frameIndex = 0;
|
||||
for each (valueMap in values)
|
||||
attachmentTimeline.setFrame(frameIndex++, valueMap["time"], valueMap["name"]);
|
||||
timelines[timelines.length] = attachmentTimeline;
|
||||
duration = Math.max(duration, attachmentTimeline.frames[attachmentTimeline.frameCount - 1]);
|
||||
for each (valueMap in values) {
|
||||
color = valueMap["color"];
|
||||
var darkColor:String = valueMap["dark"];
|
||||
var light:Color = new Color(0, 0, 0, 0);
|
||||
var dark:Color = new Color(0, 0, 0, 0);
|
||||
light.setFrom(toColor(color, 0), toColor(color, 1), toColor(color, 2), toColor(color, 3));
|
||||
dark.setFrom(toColor(darkColor, 0), toColor(darkColor, 1), toColor(darkColor, 2), toColor(darkColor, 3));
|
||||
twoColorTimeline.setFrame(frameIndex, valueMap["time"], light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b);
|
||||
readCurve(valueMap, twoColorTimeline, frameIndex);
|
||||
frameIndex++;
|
||||
}
|
||||
timelines[timelines.length] = twoColorTimeline;
|
||||
duration = Math.max(duration, twoColorTimeline.frames[(twoColorTimeline.frameCount - 1) * TwoColorTimeline.ENTRIES]);
|
||||
} else
|
||||
throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
|
||||
}
|
||||
|
||||
@ -34,10 +34,8 @@ import spine.attachments.Attachment;
|
||||
public class Slot {
|
||||
internal var _data:SlotData;
|
||||
internal var _bone:Bone;
|
||||
public var r:Number;
|
||||
public var g:Number;
|
||||
public var b:Number;
|
||||
public var a:Number;
|
||||
public var color:Color;
|
||||
public var darkColor:Color;
|
||||
internal var _attachment:Attachment;
|
||||
private var _attachmentTime:Number;
|
||||
public var attachmentVertices:Vector.<Number> = new Vector.<Number>();
|
||||
@ -47,6 +45,8 @@ public class Slot {
|
||||
if (bone == null) throw new ArgumentError("bone cannot be null.");
|
||||
_data = data;
|
||||
_bone = bone;
|
||||
this.color = new Color(1, 1, 1, 1);
|
||||
this.darkColor = data.darkColor == null ? null : new Color(1, 1, 1, 1);
|
||||
setToSetupPose();
|
||||
}
|
||||
|
||||
@ -86,10 +86,8 @@ public class Slot {
|
||||
}
|
||||
|
||||
public function setToSetupPose () : void {
|
||||
r = _data.r;
|
||||
g = _data.g;
|
||||
b = _data.b;
|
||||
a = _data.a;
|
||||
color.setFromColor(data.color);
|
||||
if (darkColor != null) darkColor.setFromColor(this.data.darkColor);
|
||||
if (_data.attachmentName == null)
|
||||
attachment = null;
|
||||
else {
|
||||
|
||||
@ -34,10 +34,8 @@ public class SlotData {
|
||||
internal var _index:int;
|
||||
internal var _name:String;
|
||||
internal var _boneData:BoneData;
|
||||
public var r:Number = 1;
|
||||
public var g:Number = 1;
|
||||
public var b:Number = 1;
|
||||
public var a:Number = 1;
|
||||
public var color: Color = new Color(1, 1, 1, 1);
|
||||
public var darkColor: Color;
|
||||
public var attachmentName:String;
|
||||
public var blendMode:BlendMode;
|
||||
|
||||
|
||||
@ -57,8 +57,23 @@ public class TransformConstraint implements Constraint {
|
||||
public function apply () : void {
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
public function update () : void {
|
||||
if (data.local) {
|
||||
if (data.relative)
|
||||
applyRelativeLocal();
|
||||
else
|
||||
applyAbsoluteLocal();
|
||||
|
||||
} else {
|
||||
if (data.relative)
|
||||
applyRelativeWorld();
|
||||
else
|
||||
applyAbsoluteWorld();
|
||||
}
|
||||
}
|
||||
|
||||
internal function applyAbsoluteWorld () : void {
|
||||
var rotateMix:Number = this.rotateMix, translateMix:Number = this.translateMix, scaleMix:Number = this.scaleMix, shearMix:Number = this.shearMix;
|
||||
var target:Bone = this.target;
|
||||
var ta:Number = target.a, tb:Number = target.b, tc:Number = target.c, td:Number = target.d;
|
||||
@ -78,10 +93,10 @@ public class TransformConstraint implements Constraint {
|
||||
else if (r < -Math.PI) r += Math.PI * 2;
|
||||
r *= rotateMix;
|
||||
var cos:Number = Math.cos(r), sin:Number = Math.sin(r);
|
||||
bone._a = cos * a - sin * c;
|
||||
bone._b = cos * b - sin * d;
|
||||
bone._c = sin * a + cos * c;
|
||||
bone._d = sin * b + cos * d;
|
||||
bone.a = cos * a - sin * c;
|
||||
bone.b = cos * b - sin * d;
|
||||
bone.c = sin * a + cos * c;
|
||||
bone.d = sin * b + cos * d;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
@ -89,8 +104,8 @@ public class TransformConstraint implements Constraint {
|
||||
_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;
|
||||
bone.worldX += (_temp[0] - bone.worldX) * translateMix;
|
||||
bone.worldY += (_temp[1] - bone.worldY) * translateMix;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
@ -98,13 +113,13 @@ public class TransformConstraint implements Constraint {
|
||||
var s:Number = Math.sqrt(bone.a * bone.a + bone.c * bone.c);
|
||||
var ts:Number = Math.sqrt(ta * ta + tc * tc);
|
||||
if (s > 0.00001) s = (s + (ts - s + data.offsetScaleX) * scaleMix) / s;
|
||||
bone._a *= s;
|
||||
bone._c *= s;
|
||||
bone.a *= s;
|
||||
bone.c *= s;
|
||||
s = Math.sqrt(bone.b * bone.b + bone.d * bone.d);
|
||||
ts = Math.sqrt(tb * tb + td * td);
|
||||
if (s > 0.00001) s = (s + (ts - s + data.offsetScaleY) * scaleMix) / s;
|
||||
bone._b *= s;
|
||||
bone._d *= s;
|
||||
bone.b *= s;
|
||||
bone.d *= s;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
@ -117,8 +132,8 @@ public class TransformConstraint implements Constraint {
|
||||
else if (r < -Math.PI) r += Math.PI * 2;
|
||||
r = by + (r + offsetShearY) * shearMix;
|
||||
s = Math.sqrt(b * b + d * d);
|
||||
bone._b = Math.cos(r) * s;
|
||||
bone._d = Math.sin(r) * s;
|
||||
bone.b = Math.cos(r) * s;
|
||||
bone.d = Math.sin(r) * s;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
@ -126,6 +141,141 @@ public class TransformConstraint implements Constraint {
|
||||
}
|
||||
}
|
||||
|
||||
public function applyRelativeWorld () : void {
|
||||
var rotateMix:Number = this.rotateMix, translateMix:Number = this.translateMix, scaleMix:Number = this.scaleMix, shearMix:Number = this.shearMix;
|
||||
var target:Bone = this.target;
|
||||
var ta:Number = target.a, tb:Number = target.b, tc:Number = target.c, td:Number = target.d;
|
||||
var degRadReflect:Number = ta * td - tb * tc > 0 ? MathUtils.degRad : -MathUtils.degRad;
|
||||
var offsetRotation:Number = this.data.offsetRotation * degRadReflect, offsetShearY:Number = this.data.offsetShearY * degRadReflect;
|
||||
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) {
|
||||
var a:Number = bone.a, b:Number = bone.b, c:Number = bone.c, d:Number = bone.d;
|
||||
var r:Number = Math.atan2(tc, ta) + offsetRotation;
|
||||
if (r > MathUtils.PI)
|
||||
r -= MathUtils.PI2;
|
||||
else if (r < -MathUtils.PI) r += MathUtils.PI2;
|
||||
r *= rotateMix;
|
||||
var cos:Number = Math.cos(r), sin:Number = Math.sin(r);
|
||||
bone.a = cos * a - sin * c;
|
||||
bone.b = cos * b - sin * d;
|
||||
bone.c = sin * a + cos * c;
|
||||
bone.d = sin * b + cos * d;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (translateMix != 0) {
|
||||
var temp:Vector.<Number> = this._temp;
|
||||
temp[0] = this._data.offsetX;
|
||||
temp[1] = this._data.offsetY;
|
||||
target.localToWorld(temp);
|
||||
bone.worldX += temp[0] * translateMix;
|
||||
bone.worldY += temp[1] * translateMix;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (scaleMix > 0) {
|
||||
var s:Number = (Math.sqrt(ta * ta + tc * tc) - 1 + this.data.offsetScaleX) * scaleMix + 1;
|
||||
bone.a *= s;
|
||||
bone.c *= s;
|
||||
s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * scaleMix + 1;
|
||||
bone.b *= s;
|
||||
bone.d *= s;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (shearMix > 0) {
|
||||
r = Math.atan2(td, tb) - Math.atan2(tc, ta);
|
||||
if (r > MathUtils.PI)
|
||||
r -= MathUtils.PI2;
|
||||
else if (r < -MathUtils.PI) r += MathUtils.PI2;
|
||||
b = bone.b; d = bone.d;
|
||||
r = Math.atan2(d, b) + (r - MathUtils.PI / 2 + offsetShearY) * shearMix;
|
||||
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 applyAbsoluteLocal () : void {
|
||||
var rotateMix:Number = this.rotateMix, translateMix:Number = this.translateMix, scaleMix:Number = this.scaleMix, shearMix:Number = this.shearMix;
|
||||
var target:Bone = this.target;
|
||||
if (!target.appliedValid) target.updateAppliedTransform();
|
||||
var bones:Vector.<Bone> = this.bones;
|
||||
for (var i:int = 0, n:int = bones.length; i < n; i++) {
|
||||
var bone:Bone = bones[i];
|
||||
if (!bone.appliedValid) bone.updateAppliedTransform();
|
||||
|
||||
var rotation:Number = bone.arotation;
|
||||
if (rotateMix != 0) {
|
||||
var r:Number = target.arotation - rotation + this.data.offsetRotation;
|
||||
r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360;
|
||||
rotation += r * rotateMix;
|
||||
}
|
||||
|
||||
var x:Number = bone.ax, y:Number = bone.ay;
|
||||
if (translateMix != 0) {
|
||||
x += (target.ax - x + this.data.offsetX) * translateMix;
|
||||
y += (target.ay - y + this.data.offsetY) * translateMix;
|
||||
}
|
||||
|
||||
var scaleX:Number = bone.ascaleX, scaleY:Number = bone.ascaleY;
|
||||
if (scaleMix > 0) {
|
||||
if (scaleX > 0.00001) scaleX = (scaleX + (target.ascaleX - scaleX + this.data.offsetScaleX) * scaleMix) / scaleX;
|
||||
if (scaleY > 0.00001) scaleY = (scaleY + (target.ascaleY - scaleY + this.data.offsetScaleY) * scaleMix) / scaleY;
|
||||
}
|
||||
|
||||
var shearY:Number = bone.ashearY;
|
||||
if (shearMix > 0) {
|
||||
r = target.ashearY - shearY + this.data.offsetShearY;
|
||||
r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360;
|
||||
bone.shearY += r * shearMix;
|
||||
}
|
||||
|
||||
bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
|
||||
}
|
||||
}
|
||||
|
||||
public function applyRelativeLocal () : void {
|
||||
var rotateMix:Number = this.rotateMix, translateMix:Number = this.translateMix, scaleMix:Number = this.scaleMix, shearMix:Number = this.shearMix;
|
||||
var target:Bone = this.target;
|
||||
if (!target.appliedValid) target.updateAppliedTransform();
|
||||
var bones:Vector.<Bone> = this.bones;
|
||||
for (var i:int = 0, n:int = bones.length; i < n; i++) {
|
||||
var bone:Bone = bones[i];
|
||||
if (!bone.appliedValid) bone.updateAppliedTransform();
|
||||
|
||||
var rotation:Number = bone.arotation;
|
||||
if (rotateMix != 0) rotation += (target.arotation + this.data.offsetRotation) * rotateMix;
|
||||
|
||||
var x:Number = bone.ax, y:Number = bone.ay;
|
||||
if (translateMix != 0) {
|
||||
x += (target.ax + this.data.offsetX) * translateMix;
|
||||
y += (target.ay + this.data.offsetY) * translateMix;
|
||||
}
|
||||
|
||||
var scaleX:Number = bone.ascaleX, scaleY:Number = bone.ascaleY;
|
||||
if (scaleMix > 0) {
|
||||
if (scaleX > 0.00001) scaleX *= ((target.ascaleX - 1 + this.data.offsetScaleX) * scaleMix) + 1;
|
||||
if (scaleY > 0.00001) scaleY *= ((target.ascaleY - 1 + this.data.offsetScaleY) * scaleMix) + 1;
|
||||
}
|
||||
|
||||
var shearY:Number = bone.ashearY;
|
||||
if (shearMix > 0) shearY += (target.ashearY + this.data.offsetShearY) * shearMix;
|
||||
|
||||
bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getOrder () : Number {
|
||||
return _data.order;
|
||||
}
|
||||
|
||||
@ -45,6 +45,8 @@ public class TransformConstraintData {
|
||||
public var offsetScaleX:Number;
|
||||
public var offsetScaleY:Number;
|
||||
public var offsetShearY:Number;
|
||||
public var relative:Boolean = false;
|
||||
public var local:Boolean = false;
|
||||
|
||||
public function TransformConstraintData (name:String) {
|
||||
if (name == null) throw new ArgumentError("name cannot be null.");
|
||||
|
||||
@ -66,10 +66,7 @@ public class ColorTimeline extends CurveTimeline {
|
||||
|
||||
if (time < frames[0]) {
|
||||
if (setupPose) {
|
||||
slot.r = slot.data.r;
|
||||
slot.g = slot.data.g;
|
||||
slot.b = slot.data.b;
|
||||
slot.a = slot.data.a;
|
||||
slot.color.setFromColor(slot.data.color);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -98,21 +95,15 @@ public class ColorTimeline extends CurveTimeline {
|
||||
a += (frames[frame + A] - a) * percent;
|
||||
}
|
||||
if (alpha == 1) {
|
||||
slot.r = r;
|
||||
slot.g = g;
|
||||
slot.b = b;
|
||||
slot.a = a;
|
||||
slot.color.setFrom(r, g, b, a);
|
||||
} else {
|
||||
if (setupPose) {
|
||||
slot.r = slot.data.r;
|
||||
slot.g = slot.data.g;
|
||||
slot.b = slot.data.b;
|
||||
slot.a = slot.data.a;
|
||||
slot.color.setFromColor(slot.data.color);
|
||||
}
|
||||
slot.r += (r - slot.r) * alpha;
|
||||
slot.g += (g - slot.g) * alpha;
|
||||
slot.b += (b - slot.b) * alpha;
|
||||
slot.a += (a - slot.a) * alpha;
|
||||
slot.color.r += (r - slot.color.r) * alpha;
|
||||
slot.color.g += (g - slot.color.g) * alpha;
|
||||
slot.color.b += (b - slot.color.b) * alpha;
|
||||
slot.color.a += (a - slot.color.a) * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,6 +51,7 @@ public class TimelineType {
|
||||
public static const pathConstraintPosition:TimelineType = new TimelineType(11);
|
||||
public static const pathConstraintSpacing:TimelineType = new TimelineType(12);
|
||||
public static const pathConstraintMix:TimelineType = new TimelineType(13);
|
||||
public static const twoColor:TimelineType = new TimelineType(14);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
128
spine-as3/spine-as3/src/spine/animation/TwoColorTimeline.as
Normal file
128
spine-as3/spine-as3/src/spine/animation/TwoColorTimeline.as
Normal file
@ -0,0 +1,128 @@
|
||||
/******************************************************************************
|
||||
* 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.animation {
|
||||
import spine.Color;
|
||||
import spine.Event;
|
||||
import spine.Skeleton;
|
||||
import spine.Slot;
|
||||
|
||||
public class TwoColorTimeline extends CurveTimeline {
|
||||
static public const ENTRIES:int = 8;
|
||||
static internal const PREV_TIME:int = -8, PREV_R:int = -7, PREV_G:int = -6, PREV_B:int = -5, PREV_A:int = -4;
|
||||
static internal const PREV_R2:int = -3, PREV_G2:int = -2, PREV_B2:int = -1;
|
||||
static internal const R:int = 1, G:int = 2, B:int = 3, A:int = 4, R2:int = 5, G2:int = 6, B2:int = 7;
|
||||
|
||||
public var slotIndex:int;
|
||||
public var frames:Vector.<Number>; // time, r, g, b, a, ...
|
||||
|
||||
public function TwoColorTimeline (frameCount:int) {
|
||||
super(frameCount);
|
||||
frames = new Vector.<Number>(frameCount * ENTRIES, true);
|
||||
}
|
||||
|
||||
override public function getPropertyId () : int {
|
||||
return (TimelineType.twoColor.ordinal << 24) + slotIndex;
|
||||
}
|
||||
|
||||
/** Sets the time and value of the specified keyframe. */
|
||||
public function setFrame (frameIndex:int, time:Number, r:Number, g:Number, b:Number, a:Number, r2:Number, g2:Number, b2:Number) : void {
|
||||
frameIndex *= TwoColorTimeline.ENTRIES;
|
||||
this.frames[frameIndex] = time;
|
||||
this.frames[frameIndex + TwoColorTimeline.R] = r;
|
||||
this.frames[frameIndex + TwoColorTimeline.G] = g;
|
||||
this.frames[frameIndex + TwoColorTimeline.B] = b;
|
||||
this.frames[frameIndex + TwoColorTimeline.A] = a;
|
||||
this.frames[frameIndex + TwoColorTimeline.R2] = r2;
|
||||
this.frames[frameIndex + TwoColorTimeline.G2] = g2;
|
||||
this.frames[frameIndex + TwoColorTimeline.B2] = b2;
|
||||
}
|
||||
|
||||
override public function apply (skeleton:Skeleton, lastTime:Number, time:Number, firedEvents:Vector.<Event>, alpha:Number, setupPose:Boolean, mixingOut:Boolean) : void {
|
||||
var frames:Vector.<Number> = this.frames;
|
||||
var slot:Slot = skeleton.slots[slotIndex];
|
||||
|
||||
if (time < frames[0]) {
|
||||
if (setupPose) {
|
||||
slot.color.setFromColor(slot.data.color);
|
||||
slot.darkColor.setFromColor(slot.data.darkColor);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var r:Number, g:Number, b:Number, a:Number, r2:Number, g2:Number, b2:Number;
|
||||
if (time >= frames[frames.length - ENTRIES]) { // Time is after last frame.
|
||||
var i:int = frames.length;
|
||||
r = frames[i + PREV_R];
|
||||
g = frames[i + PREV_G];
|
||||
b = frames[i + PREV_B];
|
||||
a = frames[i + PREV_A];
|
||||
r2 = frames[i + PREV_R2];
|
||||
g2 = frames[i + PREV_G2];
|
||||
b2 = frames[i + PREV_B2];
|
||||
} else {
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
var frame:int = Animation.binarySearch(frames, time, ENTRIES);
|
||||
r = frames[frame + PREV_R];
|
||||
g = frames[frame + PREV_G];
|
||||
b = frames[frame + PREV_B];
|
||||
a = frames[frame + PREV_A];
|
||||
r2 = frames[frame + PREV_R2];
|
||||
g2 = frames[frame + PREV_G2];
|
||||
b2 = frames[frame + PREV_B2];
|
||||
var frameTime:Number = frames[frame];
|
||||
var percent:Number = getCurvePercent(frame / ENTRIES - 1,
|
||||
1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
||||
|
||||
r += (frames[frame + R] - r) * percent;
|
||||
g += (frames[frame + G] - g) * percent;
|
||||
b += (frames[frame + B] - b) * percent;
|
||||
a += (frames[frame + A] - a) * percent;
|
||||
r2 += (frames[frame + R2] - a) * percent;
|
||||
g2 += (frames[frame + G2] - a) * percent;
|
||||
b2 += (frames[frame + B2] - a) * percent;
|
||||
}
|
||||
if (alpha == 1) {
|
||||
slot.color.setFrom(r, g, b, a);
|
||||
slot.darkColor.setFrom(r2, g2, b2, 1);
|
||||
} else {
|
||||
var light:Color = slot.color;
|
||||
var dark:Color = slot.darkColor;
|
||||
if (setupPose) {
|
||||
light.setFromColor(slot.data.color);
|
||||
dark.setFromColor(slot.data.darkColor);
|
||||
}
|
||||
light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha);
|
||||
dark.add((r2 - dark.r) * alpha, (g2 - dark.g) * alpha, (b2 - dark.b) * alpha, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -89,6 +89,10 @@ public class AtlasAttachmentLoader implements AttachmentLoader {
|
||||
public function newPathAttachment(skin:Skin, name:String) : PathAttachment {
|
||||
return new PathAttachment(name);
|
||||
}
|
||||
|
||||
public function newPointAttachment(skin:Skin, name:String) : PointAttachment {
|
||||
return new PointAttachment(name);
|
||||
}
|
||||
|
||||
static public function nextPOT (value:int) : int {
|
||||
value--;
|
||||
|
||||
@ -43,6 +43,9 @@ public interface AttachmentLoader {
|
||||
|
||||
/** @return May be null to not load an attachment */
|
||||
function newPathAttachment(skin:Skin, name:String): PathAttachment;
|
||||
|
||||
/** @return May be null to not load an attachment */
|
||||
function newPointAttachment(skin:Skin, name:String): PointAttachment;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -37,6 +37,7 @@ public class AttachmentType {
|
||||
public static const mesh:AttachmentType = new AttachmentType(3, "mesh");
|
||||
public static const linkedmesh:AttachmentType = new AttachmentType(3, "linkedmesh");
|
||||
public static const path:AttachmentType = new AttachmentType(4, "path");
|
||||
public static const point:AttachmentType = new AttachmentType(5, "point");
|
||||
|
||||
public var ordinal:int;
|
||||
public var name:String;
|
||||
|
||||
@ -29,16 +29,13 @@
|
||||
*****************************************************************************/
|
||||
|
||||
package spine.attachments {
|
||||
import spine.Color;
|
||||
|
||||
public dynamic class MeshAttachment extends VertexAttachment {
|
||||
public var worldVertices:Vector.<Number>;
|
||||
public dynamic class MeshAttachment extends VertexAttachment {
|
||||
public var uvs:Vector.<Number>;
|
||||
public var regionUVs:Vector.<Number>;
|
||||
public var triangles:Vector.<uint>;
|
||||
public var r:Number = 1;
|
||||
public var g:Number = 1;
|
||||
public var b:Number = 1;
|
||||
public var a:Number = 1;
|
||||
public var color:Color = new Color(1, 1, 1, 1);
|
||||
public var hullLength:int;
|
||||
private var _parentMesh:MeshAttachment;
|
||||
public var inheritDeform:Boolean;
|
||||
|
||||
57
spine-as3/spine-as3/src/spine/attachments/PointAttachment.as
Normal file
57
spine-as3/spine-as3/src/spine/attachments/PointAttachment.as
Normal file
@ -0,0 +1,57 @@
|
||||
/******************************************************************************
|
||||
* 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.attachments {
|
||||
import spine.Color;
|
||||
import spine.MathUtils;
|
||||
import spine.Bone;
|
||||
|
||||
public dynamic class PointAttachment extends VertexAttachment {
|
||||
public var x: Number, y: Number, rotation: Number;
|
||||
public var color:Color = new Color(0.38, 0.94, 0, 1);
|
||||
|
||||
public function PointAttachment (name:String) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public function computeWorldPosition (bone: Bone, point: Vector.<Number>): Vector.<Number> {
|
||||
point[0] = this.x * bone.a + this.y * bone.b + bone.worldX;
|
||||
point[1] = this.x * bone.c + this.y * bone.d + bone.worldY;
|
||||
return point;
|
||||
}
|
||||
|
||||
public function computeWorldRotation (bone: Bone): Number {
|
||||
var cos:Number = MathUtils.cosDeg(this.rotation), sin: Number = MathUtils.sinDeg(this.rotation);
|
||||
var x:Number = cos * bone.a + sin * bone.b;
|
||||
var y:Number = cos * bone.c + sin * bone.d;
|
||||
return Math.atan2(y, x) * MathUtils.radDeg;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -29,6 +29,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
package spine.attachments {
|
||||
import spine.Color;
|
||||
import spine.Bone;
|
||||
|
||||
public dynamic class RegionAttachment extends Attachment {
|
||||
@ -48,10 +49,7 @@ public dynamic class RegionAttachment extends Attachment {
|
||||
public var rotation:Number;
|
||||
public var width:Number;
|
||||
public var height:Number;
|
||||
public var r:Number = 1;
|
||||
public var g:Number = 1;
|
||||
public var b:Number = 1;
|
||||
public var a:Number = 1;
|
||||
public var color:Color = new Color(1, 1, 1, 1);
|
||||
|
||||
public var path:String;
|
||||
public var rendererObject:Object;
|
||||
@ -71,28 +69,6 @@ public dynamic class RegionAttachment extends Attachment {
|
||||
uvs.length = 8;
|
||||
}
|
||||
|
||||
public function setUVs (u:Number, v:Number, u2:Number, v2:Number, rotate:Boolean) : void {
|
||||
if (rotate) {
|
||||
uvs[X2] = u;
|
||||
uvs[Y2] = v2;
|
||||
uvs[X3] = u;
|
||||
uvs[Y3] = v;
|
||||
uvs[X4] = u2;
|
||||
uvs[Y4] = v;
|
||||
uvs[X1] = u2;
|
||||
uvs[Y1] = v2;
|
||||
} else {
|
||||
uvs[X1] = u;
|
||||
uvs[Y1] = v2;
|
||||
uvs[X2] = u;
|
||||
uvs[Y2] = v;
|
||||
uvs[X3] = u2;
|
||||
uvs[Y3] = v;
|
||||
uvs[X4] = u2;
|
||||
uvs[Y4] = v2;
|
||||
}
|
||||
}
|
||||
|
||||
public function updateOffset () : void {
|
||||
var regionScaleX:Number = width / regionOriginalWidth * scaleX;
|
||||
var regionScaleY:Number = height / regionOriginalHeight * scaleY;
|
||||
@ -120,30 +96,58 @@ public dynamic class RegionAttachment extends Attachment {
|
||||
offset[X4] = localX2Cos - localYSin;
|
||||
offset[Y4] = localYCos + localX2Sin;
|
||||
}
|
||||
|
||||
public function setUVs (u:Number, v:Number, u2:Number, v2:Number, rotate:Boolean) : void {
|
||||
var uvs:Vector.<Number> = this.uvs;
|
||||
if (rotate) {
|
||||
uvs[X2] = u;
|
||||
uvs[Y2] = v2;
|
||||
uvs[X3] = u;
|
||||
uvs[Y3] = v;
|
||||
uvs[X4] = u2;
|
||||
uvs[Y4] = v;
|
||||
uvs[X1] = u2;
|
||||
uvs[Y1] = v2;
|
||||
} else {
|
||||
uvs[X1] = u;
|
||||
uvs[Y1] = v2;
|
||||
uvs[X2] = u;
|
||||
uvs[Y2] = v;
|
||||
uvs[X3] = u2;
|
||||
uvs[Y3] = v;
|
||||
uvs[X4] = u2;
|
||||
uvs[Y4] = v2;
|
||||
}
|
||||
}
|
||||
|
||||
public function computeWorldVertices (x:Number, y:Number, bone:Bone, worldVertices:Vector.<Number>) : void {
|
||||
x += bone.worldX;
|
||||
y += bone.worldY;
|
||||
var m00:Number = bone.a;
|
||||
var m01:Number = bone.b;
|
||||
var m10:Number = bone.c;
|
||||
var m11:Number = bone.d;
|
||||
var x1:Number = offset[X1];
|
||||
var y1:Number = offset[Y1];
|
||||
var x2:Number = offset[X2];
|
||||
var y2:Number = offset[Y2];
|
||||
var x3:Number = offset[X3];
|
||||
var y3:Number = offset[Y3];
|
||||
var x4:Number = offset[X4];
|
||||
var y4:Number = offset[Y4];
|
||||
worldVertices[X1] = x1 * m00 + y1 * m01 + x;
|
||||
worldVertices[Y1] = x1 * m10 + y1 * m11 + y;
|
||||
worldVertices[X2] = x2 * m00 + y2 * m01 + x;
|
||||
worldVertices[Y2] = x2 * m10 + y2 * m11 + y;
|
||||
worldVertices[X3] = x3 * m00 + y3 * m01 + x;
|
||||
worldVertices[Y3] = x3 * m10 + y3 * m11 + y;
|
||||
worldVertices[X4] = x4 * m00 + y4 * m01 + x;
|
||||
worldVertices[Y4] = x4 * m10 + y4 * m11 + y;
|
||||
public function computeWorldVertices (bone:Bone, worldVertices:Vector.<Number>, offset:int, stride:int) : void {
|
||||
var vertexOffset:Vector.<Number> = this.offset;
|
||||
var x:Number = bone.worldX, y:Number = bone.worldY;
|
||||
var a:Number = bone.a, b:Number = bone.b, c:Number = bone.c, d:Number = bone.d;
|
||||
var offsetX:Number = 0, offsetY:Number = 0;
|
||||
|
||||
offsetX = vertexOffset[X1];
|
||||
offsetY = vertexOffset[Y1];
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + x; // br
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y;
|
||||
offset += stride;
|
||||
|
||||
offsetX = vertexOffset[X2];
|
||||
offsetY = vertexOffset[Y2];
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + x; // bl
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y;
|
||||
offset += stride;
|
||||
|
||||
offsetX = vertexOffset[X3];
|
||||
offsetY = vertexOffset[Y3];
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + x; // ul
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y;
|
||||
offset += stride;
|
||||
|
||||
offsetX = vertexOffset[X4];
|
||||
offsetY = vertexOffset[Y4];
|
||||
worldVertices[offset] = offsetX * a + offsetY * b + x; // ur
|
||||
worldVertices[offset + 1] = offsetX * c + offsetY * d + y;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -42,17 +42,13 @@ public dynamic class VertexAttachment extends Attachment {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public function computeWorldVertices (slot:Slot, worldVertices:Vector.<Number>): void {
|
||||
computeWorldVertices2(slot, 0, worldVerticesLength, worldVertices, 0);
|
||||
}
|
||||
|
||||
/** Transforms local vertices to world coordinates.
|
||||
* @param start The index of the first local vertex value to transform. Each vertex has 2 values, x and y.
|
||||
* @param count The number of world vertex values to output. Must be <= {@link #getWorldVerticesLength()} - start.
|
||||
* @param worldVertices The output world vertices. Must have a length >= offset + count.
|
||||
* @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;
|
||||
public function computeWorldVertices (slot:Slot, start:int, count:int, worldVertices:Vector.<Number>, offset:int, stride:int): void {
|
||||
count = offset + (count >> 1) * stride;
|
||||
var skeleton:Skeleton = slot.skeleton;
|
||||
var deformArray:Vector.<Number> = slot.attachmentVertices;
|
||||
var vertices:Vector.<Number> = this.vertices;
|
||||
@ -70,7 +66,7 @@ public dynamic class VertexAttachment extends Attachment {
|
||||
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) {
|
||||
for (v = start, w = offset; w < count; v += 2, w += stride) {
|
||||
vx = vertices[v], vy = vertices[v + 1];
|
||||
worldVertices[w] = vx * a + vy * bb + x;
|
||||
worldVertices[w + 1] = vx * c + vy * d + y;
|
||||
@ -85,7 +81,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) {
|
||||
for (w = offset, b = skip * 3; w < count; w += stride) {
|
||||
wx = 0, wy = 0;
|
||||
n = bones[v++];
|
||||
n += v;
|
||||
@ -100,7 +96,7 @@ public dynamic class VertexAttachment extends Attachment {
|
||||
}
|
||||
} else {
|
||||
deform = deformArray;
|
||||
for (w = offset, b = skip * 3, f = skip << 1; w < count; w += 2) {
|
||||
for (w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) {
|
||||
wx = 0; wy = 0;
|
||||
n = bones[v++];
|
||||
n += v;
|
||||
|
||||
@ -125,10 +125,10 @@ public class SkeletonSprite extends Sprite {
|
||||
wrapper.blendMode = blendModes[slot.data.blendMode.ordinal];
|
||||
|
||||
var colorTransform:ColorTransform = wrapper.transform.colorTransform;
|
||||
colorTransform.redMultiplier = skeleton.r * slot.r * regionAttachment.r;
|
||||
colorTransform.greenMultiplier = skeleton.g * slot.g * regionAttachment.g;
|
||||
colorTransform.blueMultiplier = skeleton.b * slot.b * regionAttachment.b;
|
||||
colorTransform.alphaMultiplier = skeleton.a * slot.a * regionAttachment.a;
|
||||
colorTransform.redMultiplier = skeleton.color.r * slot.color.r * regionAttachment.color.r;
|
||||
colorTransform.greenMultiplier = skeleton.color.g * slot.color.g * regionAttachment.color.g;
|
||||
colorTransform.blueMultiplier = skeleton.color.b * slot.color.b * regionAttachment.color.b;
|
||||
colorTransform.alphaMultiplier = skeleton.color.a * slot.color.a * regionAttachment.color.a;
|
||||
wrapper.transform.colorTransform = colorTransform;
|
||||
|
||||
var bone:Bone = slot.bone;
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -40,12 +40,12 @@ public class Main extends Sprite {
|
||||
|
||||
public function Main () {
|
||||
var example:Class;
|
||||
example = SpineboyExample;
|
||||
// example = SpineboyExample;
|
||||
// example = GoblinsExample;
|
||||
example = RaptorExample;
|
||||
// example = RaptorExample;
|
||||
// example = TankExample;
|
||||
// example = VineExample;
|
||||
// example = StretchymanExample;
|
||||
example = StretchymanExample;
|
||||
|
||||
_starling = new Starling(example, stage);
|
||||
_starling.enableErrorChecking = true;
|
||||
|
||||
Binary file not shown.
@ -69,13 +69,11 @@ public class SkeletonSprite extends DisplayObject {
|
||||
}
|
||||
|
||||
override public function render (painter:Painter) : void {
|
||||
alpha *= this.alpha * skeleton.a;
|
||||
alpha *= this.alpha * skeleton.color.a;
|
||||
var originalBlendMode:String = painter.state.blendMode;
|
||||
var r:Number = skeleton.r * 255;
|
||||
var g:Number = skeleton.g * 255;
|
||||
var b:Number = skeleton.b * 255;
|
||||
var x:Number = skeleton.x;
|
||||
var y:Number = skeleton.y;
|
||||
var r:Number = skeleton.color.r * 255;
|
||||
var g:Number = skeleton.color.g * 255;
|
||||
var b:Number = skeleton.color.b * 255;
|
||||
var drawOrder:Vector.<Slot> = skeleton.drawOrder;
|
||||
var worldVertices:Vector.<Number> = _tempVertices;
|
||||
var ii:int, iii:int;
|
||||
@ -89,13 +87,12 @@ public class SkeletonSprite extends DisplayObject {
|
||||
var slot:Slot = drawOrder[i];
|
||||
if (slot.attachment is RegionAttachment) {
|
||||
var region:RegionAttachment = slot.attachment as RegionAttachment;
|
||||
region.computeWorldVertices(x, y, slot.bone, worldVertices);
|
||||
// FIXME pre-multiplied alpha?
|
||||
a = slot.a * region.a;
|
||||
region.computeWorldVertices(slot.bone, worldVertices, 0, 2);
|
||||
a = slot.color.a * region.color.a;
|
||||
rgb = Color.rgb(
|
||||
r * slot.r * region.r,
|
||||
g * slot.g * region.g,
|
||||
b * slot.b * region.b);
|
||||
r * slot.color.r * region.color.r,
|
||||
g * slot.color.g * region.color.g,
|
||||
b * slot.color.b * region.color.b);
|
||||
|
||||
var image:Image = region.rendererObject as Image;
|
||||
if (image == null) {
|
||||
@ -132,7 +129,7 @@ public class SkeletonSprite extends DisplayObject {
|
||||
verticesLength = meshAttachment.worldVerticesLength;
|
||||
verticesCount = verticesLength >> 1;
|
||||
if (worldVertices.length < verticesLength) worldVertices.length = verticesLength;
|
||||
meshAttachment.computeWorldVertices(slot, worldVertices);
|
||||
meshAttachment.computeWorldVertices(slot, 0, meshAttachment.worldVerticesLength, worldVertices, 0, 2);
|
||||
mesh = meshAttachment.rendererObject as SkeletonMesh;
|
||||
if (mesh == null) {
|
||||
if (meshAttachment.rendererObject is Image)
|
||||
@ -153,11 +150,11 @@ public class SkeletonSprite extends DisplayObject {
|
||||
}
|
||||
|
||||
// FIXME pre-multiplied alpha?
|
||||
a = slot.a * meshAttachment.a;
|
||||
a = slot.color.a * meshAttachment.color.a;
|
||||
rgb = Color.rgb(
|
||||
r * slot.r * meshAttachment.r,
|
||||
g * slot.g * meshAttachment.g,
|
||||
b * slot.b * meshAttachment.b);
|
||||
r * slot.color.r * meshAttachment.color.r,
|
||||
g * slot.color.g * meshAttachment.color.g,
|
||||
b * slot.color.b * meshAttachment.color.b);
|
||||
|
||||
vertexData = mesh.getVertexData();
|
||||
uvs = meshAttachment.uvs;
|
||||
@ -191,12 +188,12 @@ public class SkeletonSprite extends DisplayObject {
|
||||
if (attachment is RegionAttachment) {
|
||||
var region:RegionAttachment = RegionAttachment(slot.attachment);
|
||||
verticesLength = 8;
|
||||
region.computeWorldVertices(0, 0, slot.bone, worldVertices);
|
||||
region.computeWorldVertices(slot.bone, worldVertices, 0, 2);
|
||||
} else if (attachment is MeshAttachment) {
|
||||
var mesh:MeshAttachment = MeshAttachment(attachment);
|
||||
verticesLength = mesh.worldVerticesLength;
|
||||
if (worldVertices.length < verticesLength) worldVertices.length = verticesLength;
|
||||
mesh.computeWorldVertices(slot, worldVertices);
|
||||
mesh.computeWorldVertices(slot, 0, verticesLength, worldVertices, 0, 2);
|
||||
} else
|
||||
continue;
|
||||
for (var ii:int = 0; ii < verticesLength; ii += 2) {
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
package spine.starling {
|
||||
import spine.attachments.PointAttachment;
|
||||
import spine.attachments.PathAttachment;
|
||||
import starling.display.Image;
|
||||
import spine.Bone;
|
||||
@ -123,6 +124,10 @@ public class StarlingAtlasAttachmentLoader implements AttachmentLoader {
|
||||
public function newPathAttachment (skin:Skin, name:String) : PathAttachment {
|
||||
return new PathAttachment(name);
|
||||
}
|
||||
|
||||
public function newPointAttachment (skin:Skin, name:String) : PointAttachment {
|
||||
return new PointAttachment(name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -489,8 +489,8 @@ module spine {
|
||||
mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2);
|
||||
}
|
||||
if (vertices != null) {
|
||||
for (let i = 0, nn = vertices.length; i < nn; i += 8) {
|
||||
let x = vertices[i], y = vertices[i + 1];
|
||||
for (let ii = 0, nn = vertices.length; ii < nn; ii += 8) {
|
||||
let x = vertices[ii], y = vertices[ii + 1];
|
||||
minX = Math.min(minX, x);
|
||||
minY = Math.min(minY, y);
|
||||
maxX = Math.max(maxX, x);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user