[ts] Ported stretchy IK. See #1142.

This commit is contained in:
Mario Zechner 2018-08-06 15:09:08 +02:00
parent ac7fe7ca80
commit cdc2d5bc88
37 changed files with 532 additions and 210 deletions

View File

@ -106,6 +106,8 @@ cp -f ../stretchyman/export/stretchyman-pro.json ../../spine-corona/data
cp -f ../stretchyman/export/stretchyman.atlas ../../spine-corona/data cp -f ../stretchyman/export/stretchyman.atlas ../../spine-corona/data
cp -f ../stretchyman/export/stretchyman.png ../../spine-corona/data cp -f ../stretchyman/export/stretchyman.png ../../spine-corona/data
cp -f ../stretchyman-stretchy-ik/export/stretchyman-stretchy-ik.json ../../spine-corona/data
cp -f ../owl/export/owl-pro.json ../../spine-corona/data cp -f ../owl/export/owl-pro.json ../../spine-corona/data
cp -f ../owl/export/owl.atlas ../../spine-corona/data cp -f ../owl/export/owl.atlas ../../spine-corona/data
cp -f ../owl/export/owl.png ../../spine-corona/data cp -f ../owl/export/owl.png ../../spine-corona/data
@ -140,6 +142,8 @@ cp -f ../stretchyman/export/stretchyman-pro.json ../../spine-love/data
cp -f ../stretchyman/export/stretchyman.atlas ../../spine-love/data cp -f ../stretchyman/export/stretchyman.atlas ../../spine-love/data
cp -f ../stretchyman/export/stretchyman.png ../../spine-love/data cp -f ../stretchyman/export/stretchyman.png ../../spine-love/data
cp -f ../stretchyman-stretchy-ik/export/stretchyman-stretchy-ik.json ../../spine-love/data
echo "spine-sfml-c" echo "spine-sfml-c"
rm -f ../../spine-sfml/data/* rm -f ../../spine-sfml/data/*
cp -f ../coin/export/coin-pro.json ../../spine-sfml/c/data/ cp -f ../coin/export/coin-pro.json ../../spine-sfml/c/data/
@ -177,6 +181,9 @@ cp -f ../stretchyman/export/stretchyman-pro.skel ../../spine-sfml/c/data/
cp -f ../stretchyman/export/stretchyman.atlas ../../spine-sfml/c/data/ cp -f ../stretchyman/export/stretchyman.atlas ../../spine-sfml/c/data/
cp -f ../stretchyman/export/stretchyman.png ../../spine-sfml/c/data/ cp -f ../stretchyman/export/stretchyman.png ../../spine-sfml/c/data/
cp -f ../stretchyman-stretchy-ik/export/stretchyman-stretchy-ik.json ../../spine-sfml/c/data
cp -f ../stretchyman-stretchy-ik/export/stretchyman-stretchy-ik.skel ../../spine-sfml/c/data
cp -f ../owl/export/owl-pro.json ../../spine-sfml/c/data/ cp -f ../owl/export/owl-pro.json ../../spine-sfml/c/data/
cp -f ../owl/export/owl-pro.skel ../../spine-sfml/c/data/ cp -f ../owl/export/owl-pro.skel ../../spine-sfml/c/data/
cp -f ../owl/export/owl.atlas ../../spine-sfml/c/data/ cp -f ../owl/export/owl.atlas ../../spine-sfml/c/data/
@ -219,6 +226,9 @@ cp -f ../stretchyman/export/stretchyman-pro.skel ../../spine-sfml/cpp/data/
cp -f ../stretchyman/export/stretchyman.atlas ../../spine-sfml/cpp/data/ cp -f ../stretchyman/export/stretchyman.atlas ../../spine-sfml/cpp/data/
cp -f ../stretchyman/export/stretchyman.png ../../spine-sfml/cpp/data/ cp -f ../stretchyman/export/stretchyman.png ../../spine-sfml/cpp/data/
cp -f ../stretchyman-stretchy-ik/export/stretchyman-stretchy-ik.json ../../spine-sfml/cpp/data
cp -f ../stretchyman-stretchy-ik/export/stretchyman-stretchy-ik.skel ../../spine-sfml/cpp/data
cp -f ../owl/export/owl-pro.json ../../spine-sfml/cpp/data/ cp -f ../owl/export/owl-pro.json ../../spine-sfml/cpp/data/
cp -f ../owl/export/owl-pro.skel ../../spine-sfml/cpp/data/ cp -f ../owl/export/owl-pro.skel ../../spine-sfml/cpp/data/
cp -f ../owl/export/owl.atlas ../../spine-sfml/cpp/data/ cp -f ../owl/export/owl.atlas ../../spine-sfml/cpp/data/
@ -254,6 +264,8 @@ cp -f ../stretchyman/export/stretchyman-pro.json ../../spine-starling/spine-star
cp -f ../stretchyman/export/stretchyman.atlas ../../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/ cp -f ../stretchyman/export/stretchyman.png ../../spine-starling/spine-starling-example/src/
cp -f ../stretchyman-stretchy-ik/export/stretchyman-stretchy-ik.json ../../spine-starling/spine-starling-example/src/
cp -f ../owl/export/owl-pro.json ../../spine-starling/spine-starling-example/src/ cp -f ../owl/export/owl-pro.json ../../spine-starling/spine-starling-example/src/
cp -f ../owl/export/owl.atlas ../../spine-starling/spine-starling-example/src/ cp -f ../owl/export/owl.atlas ../../spine-starling/spine-starling-example/src/
cp -f ../owl/export/owl.png ../../spine-starling/spine-starling-example/src/ cp -f ../owl/export/owl.png ../../spine-starling/spine-starling-example/src/
@ -293,6 +305,8 @@ cp -f ../stretchyman/export/stretchyman-pro.json ../../spine-ts/webgl/example/as
cp -f ../stretchyman/export/stretchyman.atlas ../../spine-ts/webgl/example/assets/ cp -f ../stretchyman/export/stretchyman.atlas ../../spine-ts/webgl/example/assets/
cp -f ../stretchyman/export/stretchyman.png ../../spine-ts/webgl/example/assets/ cp -f ../stretchyman/export/stretchyman.png ../../spine-ts/webgl/example/assets/
cp -f ../stretchyman-stretchy-ik/export/stretchyman-stretchy-ik.json ../../spine-ts/webgl/example/assets/
rm -f ../../spine-ts/canvas/example/assets/* rm -f ../../spine-ts/canvas/example/assets/*
cp -f ../spineboy/export/spineboy-ess.json ../../spine-ts/canvas/example/assets/ cp -f ../spineboy/export/spineboy-ess.json ../../spine-ts/canvas/example/assets/
cp -f ../spineboy/export/spineboy.atlas ../../spine-ts/canvas/example/assets/ cp -f ../spineboy/export/spineboy.atlas ../../spine-ts/canvas/example/assets/

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,8 @@
Copyright (c) 2016, Esoteric Software
The images in this project may be redistributed as long as they are accompanied
by this license file. The images may not be used for commercial use of any
kind.
The project file is released into the public domain. It may be used as the basis
for derivative work.

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<AS3Classpath> <AS3Classpath>
<AS3Classpath generateProblems="true" sdkBased="false" type="source" useAsSharedCode="false">src</AS3Classpath> <AS3Classpath generateProblems="true" sdkBased="false" type="source" useAsSharedCode="false">src</AS3Classpath>
<AS3Classpath generateProblems="true" sdkBased="true" type="lib" useAsSharedCode="false">frameworks/libs/player/{playerVersion}/playerglobal.swc</AS3Classpath> <AS3Classpath generateProblems="true" sdkBased="true" type="lib" useAsSharedCode="false">frameworks/libs/player/30.0/playerglobal.swc</AS3Classpath>
</AS3Classpath> </AS3Classpath>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -176,13 +176,15 @@ declare module spine {
static PREV_TIME: number; static PREV_TIME: number;
static PREV_MIX: number; static PREV_MIX: number;
static PREV_BEND_DIRECTION: number; static PREV_BEND_DIRECTION: number;
static PREV_STRETCH: number;
static MIX: number; static MIX: number;
static BEND_DIRECTION: number; static BEND_DIRECTION: number;
static STRETCH: number;
ikConstraintIndex: number; ikConstraintIndex: number;
frames: ArrayLike<number>; frames: ArrayLike<number>;
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void; setFrame(frameIndex: number, time: number, mix: number, bendDirection: number, stretch: boolean): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class TransformConstraintTimeline extends CurveTimeline { class TransformConstraintTimeline extends CurveTimeline {
@ -510,14 +512,15 @@ declare module spine {
data: IkConstraintData; data: IkConstraintData;
bones: Array<Bone>; bones: Array<Bone>;
target: Bone; target: Bone;
mix: number;
bendDirection: number; bendDirection: number;
stretch: boolean;
mix: number;
constructor(data: IkConstraintData, skeleton: Skeleton); constructor(data: IkConstraintData, skeleton: Skeleton);
getOrder(): number; getOrder(): number;
apply(): void; apply(): void;
update(): void; update(): void;
apply1(bone: Bone, targetX: number, targetY: number, alpha: number): void; apply1(bone: Bone, targetX: number, targetY: number, stretch: boolean, alpha: number): void;
apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, alpha: number): void; apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, stretch: boolean, alpha: number): void;
} }
} }
declare module spine { declare module spine {
@ -527,6 +530,7 @@ declare module spine {
bones: BoneData[]; bones: BoneData[];
target: BoneData; target: BoneData;
bendDirection: number; bendDirection: number;
stretch: boolean;
mix: number; mix: number;
constructor(name: string); constructor(name: string);
} }

View File

@ -1,7 +1,10 @@
var __extends = (this && this.__extends) || (function () { var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf || var extendStatics = function (d, b) {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || extendStatics = Object.setPrototypeOf ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }
@ -965,11 +968,12 @@ var spine;
IkConstraintTimeline.prototype.getPropertyId = function () { IkConstraintTimeline.prototype.getPropertyId = function () {
return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex; return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex;
}; };
IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, bendDirection) { IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, bendDirection, stretch) {
frameIndex *= IkConstraintTimeline.ENTRIES; frameIndex *= IkConstraintTimeline.ENTRIES;
this.frames[frameIndex] = time; this.frames[frameIndex] = time;
this.frames[frameIndex + IkConstraintTimeline.MIX] = mix; this.frames[frameIndex + IkConstraintTimeline.MIX] = mix;
this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection; this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection;
this.frames[frameIndex + IkConstraintTimeline.STRETCH] = stretch ? 1 : 0;
}; };
IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
var frames = this.frames; var frames = this.frames;
@ -979,23 +983,33 @@ var spine;
case MixBlend.setup: case MixBlend.setup:
constraint.mix = constraint.data.mix; constraint.mix = constraint.data.mix;
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
return; return;
case MixBlend.first: case MixBlend.first:
constraint.mix += (constraint.data.mix - constraint.mix) * alpha; constraint.mix += (constraint.data.mix - constraint.mix) * alpha;
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
} }
return; return;
} }
if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) {
if (blend == MixBlend.setup) { if (blend == MixBlend.setup) {
constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha; constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha;
constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection if (direction == MixDirection.out) {
: frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
}
else {
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
else { else {
constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha; constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha;
if (direction == MixDirection["in"]) if (direction == MixDirection["in"]) {
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
return; return;
} }
@ -1005,20 +1019,31 @@ var spine;
var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime)); var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime));
if (blend == MixBlend.setup) { if (blend == MixBlend.setup) {
constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha; constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha;
constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection : frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; if (direction == MixDirection.out) {
constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
}
else {
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
else { else {
constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha; constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha;
if (direction == MixDirection["in"]) if (direction == MixDirection["in"]) {
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
}; };
IkConstraintTimeline.ENTRIES = 3; IkConstraintTimeline.ENTRIES = 4;
IkConstraintTimeline.PREV_TIME = -3; IkConstraintTimeline.PREV_TIME = -4;
IkConstraintTimeline.PREV_MIX = -2; IkConstraintTimeline.PREV_MIX = -3;
IkConstraintTimeline.PREV_BEND_DIRECTION = -1; IkConstraintTimeline.PREV_BEND_DIRECTION = -2;
IkConstraintTimeline.PREV_STRETCH = -1;
IkConstraintTimeline.MIX = 1; IkConstraintTimeline.MIX = 1;
IkConstraintTimeline.BEND_DIRECTION = 2; IkConstraintTimeline.BEND_DIRECTION = 2;
IkConstraintTimeline.STRETCH = 3;
return IkConstraintTimeline; return IkConstraintTimeline;
}(CurveTimeline)); }(CurveTimeline));
spine.IkConstraintTimeline = IkConstraintTimeline; spine.IkConstraintTimeline = IkConstraintTimeline;
@ -2608,8 +2633,9 @@ var spine;
(function (spine) { (function (spine) {
var IkConstraint = (function () { var IkConstraint = (function () {
function IkConstraint(data, skeleton) { function IkConstraint(data, skeleton) {
this.mix = 1;
this.bendDirection = 0; this.bendDirection = 0;
this.stretch = false;
this.mix = 1;
if (data == null) if (data == null)
throw new Error("data cannot be null."); throw new Error("data cannot be null.");
if (skeleton == null) if (skeleton == null)
@ -2617,6 +2643,7 @@ var spine;
this.data = data; this.data = data;
this.mix = data.mix; this.mix = data.mix;
this.bendDirection = data.bendDirection; this.bendDirection = data.bendDirection;
this.stretch = data.stretch;
this.bones = new Array(); this.bones = new Array();
for (var i = 0; i < data.bones.length; i++) for (var i = 0; i < data.bones.length; i++)
this.bones.push(skeleton.findBone(data.bones[i].name)); this.bones.push(skeleton.findBone(data.bones[i].name));
@ -2633,14 +2660,14 @@ var spine;
var bones = this.bones; var bones = this.bones;
switch (bones.length) { switch (bones.length) {
case 1: case 1:
this.apply1(bones[0], target.worldX, target.worldY, this.mix); this.apply1(bones[0], target.worldX, target.worldY, this.stretch, this.mix);
break; break;
case 2: case 2:
this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.mix); this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.mix);
break; break;
} }
}; };
IkConstraint.prototype.apply1 = function (bone, targetX, targetY, alpha) { IkConstraint.prototype.apply1 = function (bone, targetX, targetY, stretch, alpha) {
if (!bone.appliedValid) if (!bone.appliedValid)
bone.updateAppliedTransform(); bone.updateAppliedTransform();
var p = bone.parent; var p = bone.parent;
@ -2654,9 +2681,15 @@ var spine;
rotationIK -= 360; rotationIK -= 360;
else if (rotationIK < -180) else if (rotationIK < -180)
rotationIK += 360; rotationIK += 360;
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, bone.ascaleX, bone.ascaleY, bone.ashearX, bone.ashearY); var sx = bone.ascaleX;
if (stretch) {
var b = bone.data.length * sx, dd = Math.sqrt(tx * tx + ty * ty);
if (dd > b && b > 0.0001)
sx *= (dd / b - 1) * alpha + 1;
}
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, bone.ascaleY, bone.ashearX, bone.ashearY);
}; };
IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, alpha) { IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, stretch, alpha) {
if (alpha == 0) { if (alpha == 0) {
child.updateWorldTransform(); child.updateWorldTransform();
return; return;
@ -2665,7 +2698,7 @@ var spine;
parent.updateAppliedTransform(); parent.updateAppliedTransform();
if (!child.appliedValid) if (!child.appliedValid)
child.updateAppliedTransform(); child.updateAppliedTransform();
var px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, csx = child.ascaleX; var px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX;
var os1 = 0, os2 = 0, s2 = 0; var os1 = 0, os2 = 0, s2 = 0;
if (psx < 0) { if (psx < 0) {
psx = -psx; psx = -psx;
@ -2704,18 +2737,21 @@ var spine;
c = pp.c; c = pp.c;
d = pp.d; d = pp.d;
var id = 1 / (a * d - b * c), x = targetX - pp.worldX, y = targetY - pp.worldY; var id = 1 / (a * d - b * c), x = targetX - pp.worldX, y = targetY - pp.worldY;
var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py; var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py, dd = tx * tx + ty * ty;
x = cwx - pp.worldX; x = cwx - pp.worldX;
y = cwy - pp.worldY; y = cwy - pp.worldY;
var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py;
var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1 = 0, a2 = 0; var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1 = 0, a2 = 0;
outer: if (u) { outer: if (u) {
l2 *= psx; l2 *= psx;
var cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2); var cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);
if (cos < -1) if (cos < -1)
cos = -1; cos = -1;
else if (cos > 1) else if (cos > 1) {
cos = 1; cos = 1;
if (stretch && l1 + l2 > 0.0001)
sx *= (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1;
}
a2 = Math.acos(cos) * bendDir; a2 = Math.acos(cos) * bendDir;
a = l1 + l2 * cos; a = l1 + l2 * cos;
b = l2 * Math.sin(a2); b = l2 * Math.sin(a2);
@ -2724,7 +2760,7 @@ var spine;
else { else {
a = psx * l2; a = psx * l2;
b = psy * l2; b = psy * l2;
var aa = a * a, bb = b * b, dd = tx * tx + ty * ty, ta = Math.atan2(ty, tx); var aa = a * a, bb = b * b, ta = Math.atan2(ty, tx);
c = bb * l1 * l1 + aa * dd - aa * bb; c = bb * l1 * l1 + aa * dd - aa * bb;
var c1 = -2 * bb * l1, c2 = bb - aa; var c1 = -2 * bb * l1, c2 = bb - aa;
d = c1 * c1 - 4 * c2 * c; d = c1 * c1 - 4 * c2 * c;
@ -2779,7 +2815,7 @@ var spine;
a1 -= 360; a1 -= 360;
else if (a1 < -180) else if (a1 < -180)
a1 += 360; a1 += 360;
parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, parent.ascaleX, parent.ascaleY, 0, 0); parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, parent.ascaleY, 0, 0);
rotation = child.arotation; rotation = child.arotation;
a2 = ((a2 + os) * spine.MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation; a2 = ((a2 + os) * spine.MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation;
if (a2 > 180) if (a2 > 180)
@ -2799,6 +2835,7 @@ var spine;
this.order = 0; this.order = 0;
this.bones = new Array(); this.bones = new Array();
this.bendDirection = 1; this.bendDirection = 1;
this.stretch = false;
this.mix = 1; this.mix = 1;
this.name = name; this.name = name;
} }
@ -3584,6 +3621,7 @@ var spine;
for (var i = 0, n = ikConstraints.length; i < n; i++) { for (var i = 0, n = ikConstraints.length; i < n; i++) {
var constraint = ikConstraints[i]; var constraint = ikConstraints[i];
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
constraint.mix = constraint.data.mix; constraint.mix = constraint.data.mix;
} }
var transformConstraints = this.transformConstraints; var transformConstraints = this.transformConstraints;
@ -4453,6 +4491,7 @@ var spine;
if (data.target == null) if (data.target == null)
throw new Error("IK target bone not found: " + targetName); throw new Error("IK target bone not found: " + targetName);
data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1; data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1;
data.stretch = this.getValue(constraintMap, "stretch", false);
data.mix = this.getValue(constraintMap, "mix", 1); data.mix = this.getValue(constraintMap, "mix", 1);
skeletonData.ikConstraints.push(data); skeletonData.ikConstraints.push(data);
} }
@ -4823,7 +4862,7 @@ var spine;
var frameIndex = 0; var frameIndex = 0;
for (var i = 0; i < constraintMap.length; i++) { for (var i = 0; i < constraintMap.length; i++) {
var valueMap = constraintMap[i]; var valueMap = constraintMap[i];
timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1); timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "stretch", false));
this.readCurve(valueMap, timeline, frameIndex); this.readCurve(valueMap, timeline, frameIndex);
frameIndex++; frameIndex++;
} }

File diff suppressed because one or more lines are too long

View File

@ -176,13 +176,15 @@ declare module spine {
static PREV_TIME: number; static PREV_TIME: number;
static PREV_MIX: number; static PREV_MIX: number;
static PREV_BEND_DIRECTION: number; static PREV_BEND_DIRECTION: number;
static PREV_STRETCH: number;
static MIX: number; static MIX: number;
static BEND_DIRECTION: number; static BEND_DIRECTION: number;
static STRETCH: number;
ikConstraintIndex: number; ikConstraintIndex: number;
frames: ArrayLike<number>; frames: ArrayLike<number>;
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void; setFrame(frameIndex: number, time: number, mix: number, bendDirection: number, stretch: boolean): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class TransformConstraintTimeline extends CurveTimeline { class TransformConstraintTimeline extends CurveTimeline {
@ -510,14 +512,15 @@ declare module spine {
data: IkConstraintData; data: IkConstraintData;
bones: Array<Bone>; bones: Array<Bone>;
target: Bone; target: Bone;
mix: number;
bendDirection: number; bendDirection: number;
stretch: boolean;
mix: number;
constructor(data: IkConstraintData, skeleton: Skeleton); constructor(data: IkConstraintData, skeleton: Skeleton);
getOrder(): number; getOrder(): number;
apply(): void; apply(): void;
update(): void; update(): void;
apply1(bone: Bone, targetX: number, targetY: number, alpha: number): void; apply1(bone: Bone, targetX: number, targetY: number, stretch: boolean, alpha: number): void;
apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, alpha: number): void; apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, stretch: boolean, alpha: number): void;
} }
} }
declare module spine { declare module spine {
@ -527,6 +530,7 @@ declare module spine {
bones: BoneData[]; bones: BoneData[];
target: BoneData; target: BoneData;
bendDirection: number; bendDirection: number;
stretch: boolean;
mix: number; mix: number;
constructor(name: string); constructor(name: string);
} }

View File

@ -1,7 +1,10 @@
var __extends = (this && this.__extends) || (function () { var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf || var extendStatics = function (d, b) {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || extendStatics = Object.setPrototypeOf ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }
@ -965,11 +968,12 @@ var spine;
IkConstraintTimeline.prototype.getPropertyId = function () { IkConstraintTimeline.prototype.getPropertyId = function () {
return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex; return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex;
}; };
IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, bendDirection) { IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, bendDirection, stretch) {
frameIndex *= IkConstraintTimeline.ENTRIES; frameIndex *= IkConstraintTimeline.ENTRIES;
this.frames[frameIndex] = time; this.frames[frameIndex] = time;
this.frames[frameIndex + IkConstraintTimeline.MIX] = mix; this.frames[frameIndex + IkConstraintTimeline.MIX] = mix;
this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection; this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection;
this.frames[frameIndex + IkConstraintTimeline.STRETCH] = stretch ? 1 : 0;
}; };
IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
var frames = this.frames; var frames = this.frames;
@ -979,23 +983,33 @@ var spine;
case MixBlend.setup: case MixBlend.setup:
constraint.mix = constraint.data.mix; constraint.mix = constraint.data.mix;
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
return; return;
case MixBlend.first: case MixBlend.first:
constraint.mix += (constraint.data.mix - constraint.mix) * alpha; constraint.mix += (constraint.data.mix - constraint.mix) * alpha;
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
} }
return; return;
} }
if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) {
if (blend == MixBlend.setup) { if (blend == MixBlend.setup) {
constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha; constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha;
constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection if (direction == MixDirection.out) {
: frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
}
else {
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
else { else {
constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha; constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha;
if (direction == MixDirection["in"]) if (direction == MixDirection["in"]) {
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
return; return;
} }
@ -1005,20 +1019,31 @@ var spine;
var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime)); var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime));
if (blend == MixBlend.setup) { if (blend == MixBlend.setup) {
constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha; constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha;
constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection : frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; if (direction == MixDirection.out) {
constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
}
else {
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
else { else {
constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha; constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha;
if (direction == MixDirection["in"]) if (direction == MixDirection["in"]) {
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
}; };
IkConstraintTimeline.ENTRIES = 3; IkConstraintTimeline.ENTRIES = 4;
IkConstraintTimeline.PREV_TIME = -3; IkConstraintTimeline.PREV_TIME = -4;
IkConstraintTimeline.PREV_MIX = -2; IkConstraintTimeline.PREV_MIX = -3;
IkConstraintTimeline.PREV_BEND_DIRECTION = -1; IkConstraintTimeline.PREV_BEND_DIRECTION = -2;
IkConstraintTimeline.PREV_STRETCH = -1;
IkConstraintTimeline.MIX = 1; IkConstraintTimeline.MIX = 1;
IkConstraintTimeline.BEND_DIRECTION = 2; IkConstraintTimeline.BEND_DIRECTION = 2;
IkConstraintTimeline.STRETCH = 3;
return IkConstraintTimeline; return IkConstraintTimeline;
}(CurveTimeline)); }(CurveTimeline));
spine.IkConstraintTimeline = IkConstraintTimeline; spine.IkConstraintTimeline = IkConstraintTimeline;
@ -2608,8 +2633,9 @@ var spine;
(function (spine) { (function (spine) {
var IkConstraint = (function () { var IkConstraint = (function () {
function IkConstraint(data, skeleton) { function IkConstraint(data, skeleton) {
this.mix = 1;
this.bendDirection = 0; this.bendDirection = 0;
this.stretch = false;
this.mix = 1;
if (data == null) if (data == null)
throw new Error("data cannot be null."); throw new Error("data cannot be null.");
if (skeleton == null) if (skeleton == null)
@ -2617,6 +2643,7 @@ var spine;
this.data = data; this.data = data;
this.mix = data.mix; this.mix = data.mix;
this.bendDirection = data.bendDirection; this.bendDirection = data.bendDirection;
this.stretch = data.stretch;
this.bones = new Array(); this.bones = new Array();
for (var i = 0; i < data.bones.length; i++) for (var i = 0; i < data.bones.length; i++)
this.bones.push(skeleton.findBone(data.bones[i].name)); this.bones.push(skeleton.findBone(data.bones[i].name));
@ -2633,14 +2660,14 @@ var spine;
var bones = this.bones; var bones = this.bones;
switch (bones.length) { switch (bones.length) {
case 1: case 1:
this.apply1(bones[0], target.worldX, target.worldY, this.mix); this.apply1(bones[0], target.worldX, target.worldY, this.stretch, this.mix);
break; break;
case 2: case 2:
this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.mix); this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.mix);
break; break;
} }
}; };
IkConstraint.prototype.apply1 = function (bone, targetX, targetY, alpha) { IkConstraint.prototype.apply1 = function (bone, targetX, targetY, stretch, alpha) {
if (!bone.appliedValid) if (!bone.appliedValid)
bone.updateAppliedTransform(); bone.updateAppliedTransform();
var p = bone.parent; var p = bone.parent;
@ -2654,9 +2681,15 @@ var spine;
rotationIK -= 360; rotationIK -= 360;
else if (rotationIK < -180) else if (rotationIK < -180)
rotationIK += 360; rotationIK += 360;
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, bone.ascaleX, bone.ascaleY, bone.ashearX, bone.ashearY); var sx = bone.ascaleX;
if (stretch) {
var b = bone.data.length * sx, dd = Math.sqrt(tx * tx + ty * ty);
if (dd > b && b > 0.0001)
sx *= (dd / b - 1) * alpha + 1;
}
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, bone.ascaleY, bone.ashearX, bone.ashearY);
}; };
IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, alpha) { IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, stretch, alpha) {
if (alpha == 0) { if (alpha == 0) {
child.updateWorldTransform(); child.updateWorldTransform();
return; return;
@ -2665,7 +2698,7 @@ var spine;
parent.updateAppliedTransform(); parent.updateAppliedTransform();
if (!child.appliedValid) if (!child.appliedValid)
child.updateAppliedTransform(); child.updateAppliedTransform();
var px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, csx = child.ascaleX; var px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX;
var os1 = 0, os2 = 0, s2 = 0; var os1 = 0, os2 = 0, s2 = 0;
if (psx < 0) { if (psx < 0) {
psx = -psx; psx = -psx;
@ -2704,18 +2737,21 @@ var spine;
c = pp.c; c = pp.c;
d = pp.d; d = pp.d;
var id = 1 / (a * d - b * c), x = targetX - pp.worldX, y = targetY - pp.worldY; var id = 1 / (a * d - b * c), x = targetX - pp.worldX, y = targetY - pp.worldY;
var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py; var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py, dd = tx * tx + ty * ty;
x = cwx - pp.worldX; x = cwx - pp.worldX;
y = cwy - pp.worldY; y = cwy - pp.worldY;
var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py;
var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1 = 0, a2 = 0; var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1 = 0, a2 = 0;
outer: if (u) { outer: if (u) {
l2 *= psx; l2 *= psx;
var cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2); var cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);
if (cos < -1) if (cos < -1)
cos = -1; cos = -1;
else if (cos > 1) else if (cos > 1) {
cos = 1; cos = 1;
if (stretch && l1 + l2 > 0.0001)
sx *= (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1;
}
a2 = Math.acos(cos) * bendDir; a2 = Math.acos(cos) * bendDir;
a = l1 + l2 * cos; a = l1 + l2 * cos;
b = l2 * Math.sin(a2); b = l2 * Math.sin(a2);
@ -2724,7 +2760,7 @@ var spine;
else { else {
a = psx * l2; a = psx * l2;
b = psy * l2; b = psy * l2;
var aa = a * a, bb = b * b, dd = tx * tx + ty * ty, ta = Math.atan2(ty, tx); var aa = a * a, bb = b * b, ta = Math.atan2(ty, tx);
c = bb * l1 * l1 + aa * dd - aa * bb; c = bb * l1 * l1 + aa * dd - aa * bb;
var c1 = -2 * bb * l1, c2 = bb - aa; var c1 = -2 * bb * l1, c2 = bb - aa;
d = c1 * c1 - 4 * c2 * c; d = c1 * c1 - 4 * c2 * c;
@ -2779,7 +2815,7 @@ var spine;
a1 -= 360; a1 -= 360;
else if (a1 < -180) else if (a1 < -180)
a1 += 360; a1 += 360;
parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, parent.ascaleX, parent.ascaleY, 0, 0); parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, parent.ascaleY, 0, 0);
rotation = child.arotation; rotation = child.arotation;
a2 = ((a2 + os) * spine.MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation; a2 = ((a2 + os) * spine.MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation;
if (a2 > 180) if (a2 > 180)
@ -2799,6 +2835,7 @@ var spine;
this.order = 0; this.order = 0;
this.bones = new Array(); this.bones = new Array();
this.bendDirection = 1; this.bendDirection = 1;
this.stretch = false;
this.mix = 1; this.mix = 1;
this.name = name; this.name = name;
} }
@ -3584,6 +3621,7 @@ var spine;
for (var i = 0, n = ikConstraints.length; i < n; i++) { for (var i = 0, n = ikConstraints.length; i < n; i++) {
var constraint = ikConstraints[i]; var constraint = ikConstraints[i];
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
constraint.mix = constraint.data.mix; constraint.mix = constraint.data.mix;
} }
var transformConstraints = this.transformConstraints; var transformConstraints = this.transformConstraints;
@ -4453,6 +4491,7 @@ var spine;
if (data.target == null) if (data.target == null)
throw new Error("IK target bone not found: " + targetName); throw new Error("IK target bone not found: " + targetName);
data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1; data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1;
data.stretch = this.getValue(constraintMap, "stretch", false);
data.mix = this.getValue(constraintMap, "mix", 1); data.mix = this.getValue(constraintMap, "mix", 1);
skeletonData.ikConstraints.push(data); skeletonData.ikConstraints.push(data);
} }
@ -4823,7 +4862,7 @@ var spine;
var frameIndex = 0; var frameIndex = 0;
for (var i = 0; i < constraintMap.length; i++) { for (var i = 0; i < constraintMap.length; i++) {
var valueMap = constraintMap[i]; var valueMap = constraintMap[i];
timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1); timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "stretch", false));
this.readCurve(valueMap, timeline, frameIndex); this.readCurve(valueMap, timeline, frameIndex);
frameIndex++; frameIndex++;
} }

File diff suppressed because one or more lines are too long

View File

@ -176,13 +176,15 @@ declare module spine {
static PREV_TIME: number; static PREV_TIME: number;
static PREV_MIX: number; static PREV_MIX: number;
static PREV_BEND_DIRECTION: number; static PREV_BEND_DIRECTION: number;
static PREV_STRETCH: number;
static MIX: number; static MIX: number;
static BEND_DIRECTION: number; static BEND_DIRECTION: number;
static STRETCH: number;
ikConstraintIndex: number; ikConstraintIndex: number;
frames: ArrayLike<number>; frames: ArrayLike<number>;
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void; setFrame(frameIndex: number, time: number, mix: number, bendDirection: number, stretch: boolean): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class TransformConstraintTimeline extends CurveTimeline { class TransformConstraintTimeline extends CurveTimeline {
@ -510,14 +512,15 @@ declare module spine {
data: IkConstraintData; data: IkConstraintData;
bones: Array<Bone>; bones: Array<Bone>;
target: Bone; target: Bone;
mix: number;
bendDirection: number; bendDirection: number;
stretch: boolean;
mix: number;
constructor(data: IkConstraintData, skeleton: Skeleton); constructor(data: IkConstraintData, skeleton: Skeleton);
getOrder(): number; getOrder(): number;
apply(): void; apply(): void;
update(): void; update(): void;
apply1(bone: Bone, targetX: number, targetY: number, alpha: number): void; apply1(bone: Bone, targetX: number, targetY: number, stretch: boolean, alpha: number): void;
apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, alpha: number): void; apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, stretch: boolean, alpha: number): void;
} }
} }
declare module spine { declare module spine {
@ -527,6 +530,7 @@ declare module spine {
bones: BoneData[]; bones: BoneData[];
target: BoneData; target: BoneData;
bendDirection: number; bendDirection: number;
stretch: boolean;
mix: number; mix: number;
constructor(name: string); constructor(name: string);
} }

View File

@ -1,7 +1,10 @@
var __extends = (this && this.__extends) || (function () { var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf || var extendStatics = function (d, b) {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || extendStatics = Object.setPrototypeOf ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }
@ -965,11 +968,12 @@ var spine;
IkConstraintTimeline.prototype.getPropertyId = function () { IkConstraintTimeline.prototype.getPropertyId = function () {
return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex; return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex;
}; };
IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, bendDirection) { IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, bendDirection, stretch) {
frameIndex *= IkConstraintTimeline.ENTRIES; frameIndex *= IkConstraintTimeline.ENTRIES;
this.frames[frameIndex] = time; this.frames[frameIndex] = time;
this.frames[frameIndex + IkConstraintTimeline.MIX] = mix; this.frames[frameIndex + IkConstraintTimeline.MIX] = mix;
this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection; this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection;
this.frames[frameIndex + IkConstraintTimeline.STRETCH] = stretch ? 1 : 0;
}; };
IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
var frames = this.frames; var frames = this.frames;
@ -979,23 +983,33 @@ var spine;
case MixBlend.setup: case MixBlend.setup:
constraint.mix = constraint.data.mix; constraint.mix = constraint.data.mix;
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
return; return;
case MixBlend.first: case MixBlend.first:
constraint.mix += (constraint.data.mix - constraint.mix) * alpha; constraint.mix += (constraint.data.mix - constraint.mix) * alpha;
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
} }
return; return;
} }
if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) {
if (blend == MixBlend.setup) { if (blend == MixBlend.setup) {
constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha; constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha;
constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection if (direction == MixDirection.out) {
: frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
}
else {
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
else { else {
constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha; constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha;
if (direction == MixDirection["in"]) if (direction == MixDirection["in"]) {
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
return; return;
} }
@ -1005,20 +1019,31 @@ var spine;
var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime)); var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime));
if (blend == MixBlend.setup) { if (blend == MixBlend.setup) {
constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha; constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha;
constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection : frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; if (direction == MixDirection.out) {
constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
}
else {
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
else { else {
constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha; constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha;
if (direction == MixDirection["in"]) if (direction == MixDirection["in"]) {
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
}; };
IkConstraintTimeline.ENTRIES = 3; IkConstraintTimeline.ENTRIES = 4;
IkConstraintTimeline.PREV_TIME = -3; IkConstraintTimeline.PREV_TIME = -4;
IkConstraintTimeline.PREV_MIX = -2; IkConstraintTimeline.PREV_MIX = -3;
IkConstraintTimeline.PREV_BEND_DIRECTION = -1; IkConstraintTimeline.PREV_BEND_DIRECTION = -2;
IkConstraintTimeline.PREV_STRETCH = -1;
IkConstraintTimeline.MIX = 1; IkConstraintTimeline.MIX = 1;
IkConstraintTimeline.BEND_DIRECTION = 2; IkConstraintTimeline.BEND_DIRECTION = 2;
IkConstraintTimeline.STRETCH = 3;
return IkConstraintTimeline; return IkConstraintTimeline;
}(CurveTimeline)); }(CurveTimeline));
spine.IkConstraintTimeline = IkConstraintTimeline; spine.IkConstraintTimeline = IkConstraintTimeline;
@ -2608,8 +2633,9 @@ var spine;
(function (spine) { (function (spine) {
var IkConstraint = (function () { var IkConstraint = (function () {
function IkConstraint(data, skeleton) { function IkConstraint(data, skeleton) {
this.mix = 1;
this.bendDirection = 0; this.bendDirection = 0;
this.stretch = false;
this.mix = 1;
if (data == null) if (data == null)
throw new Error("data cannot be null."); throw new Error("data cannot be null.");
if (skeleton == null) if (skeleton == null)
@ -2617,6 +2643,7 @@ var spine;
this.data = data; this.data = data;
this.mix = data.mix; this.mix = data.mix;
this.bendDirection = data.bendDirection; this.bendDirection = data.bendDirection;
this.stretch = data.stretch;
this.bones = new Array(); this.bones = new Array();
for (var i = 0; i < data.bones.length; i++) for (var i = 0; i < data.bones.length; i++)
this.bones.push(skeleton.findBone(data.bones[i].name)); this.bones.push(skeleton.findBone(data.bones[i].name));
@ -2633,14 +2660,14 @@ var spine;
var bones = this.bones; var bones = this.bones;
switch (bones.length) { switch (bones.length) {
case 1: case 1:
this.apply1(bones[0], target.worldX, target.worldY, this.mix); this.apply1(bones[0], target.worldX, target.worldY, this.stretch, this.mix);
break; break;
case 2: case 2:
this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.mix); this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.mix);
break; break;
} }
}; };
IkConstraint.prototype.apply1 = function (bone, targetX, targetY, alpha) { IkConstraint.prototype.apply1 = function (bone, targetX, targetY, stretch, alpha) {
if (!bone.appliedValid) if (!bone.appliedValid)
bone.updateAppliedTransform(); bone.updateAppliedTransform();
var p = bone.parent; var p = bone.parent;
@ -2654,9 +2681,15 @@ var spine;
rotationIK -= 360; rotationIK -= 360;
else if (rotationIK < -180) else if (rotationIK < -180)
rotationIK += 360; rotationIK += 360;
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, bone.ascaleX, bone.ascaleY, bone.ashearX, bone.ashearY); var sx = bone.ascaleX;
if (stretch) {
var b = bone.data.length * sx, dd = Math.sqrt(tx * tx + ty * ty);
if (dd > b && b > 0.0001)
sx *= (dd / b - 1) * alpha + 1;
}
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, bone.ascaleY, bone.ashearX, bone.ashearY);
}; };
IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, alpha) { IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, stretch, alpha) {
if (alpha == 0) { if (alpha == 0) {
child.updateWorldTransform(); child.updateWorldTransform();
return; return;
@ -2665,7 +2698,7 @@ var spine;
parent.updateAppliedTransform(); parent.updateAppliedTransform();
if (!child.appliedValid) if (!child.appliedValid)
child.updateAppliedTransform(); child.updateAppliedTransform();
var px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, csx = child.ascaleX; var px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX;
var os1 = 0, os2 = 0, s2 = 0; var os1 = 0, os2 = 0, s2 = 0;
if (psx < 0) { if (psx < 0) {
psx = -psx; psx = -psx;
@ -2704,18 +2737,21 @@ var spine;
c = pp.c; c = pp.c;
d = pp.d; d = pp.d;
var id = 1 / (a * d - b * c), x = targetX - pp.worldX, y = targetY - pp.worldY; var id = 1 / (a * d - b * c), x = targetX - pp.worldX, y = targetY - pp.worldY;
var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py; var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py, dd = tx * tx + ty * ty;
x = cwx - pp.worldX; x = cwx - pp.worldX;
y = cwy - pp.worldY; y = cwy - pp.worldY;
var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py;
var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1 = 0, a2 = 0; var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1 = 0, a2 = 0;
outer: if (u) { outer: if (u) {
l2 *= psx; l2 *= psx;
var cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2); var cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);
if (cos < -1) if (cos < -1)
cos = -1; cos = -1;
else if (cos > 1) else if (cos > 1) {
cos = 1; cos = 1;
if (stretch && l1 + l2 > 0.0001)
sx *= (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1;
}
a2 = Math.acos(cos) * bendDir; a2 = Math.acos(cos) * bendDir;
a = l1 + l2 * cos; a = l1 + l2 * cos;
b = l2 * Math.sin(a2); b = l2 * Math.sin(a2);
@ -2724,7 +2760,7 @@ var spine;
else { else {
a = psx * l2; a = psx * l2;
b = psy * l2; b = psy * l2;
var aa = a * a, bb = b * b, dd = tx * tx + ty * ty, ta = Math.atan2(ty, tx); var aa = a * a, bb = b * b, ta = Math.atan2(ty, tx);
c = bb * l1 * l1 + aa * dd - aa * bb; c = bb * l1 * l1 + aa * dd - aa * bb;
var c1 = -2 * bb * l1, c2 = bb - aa; var c1 = -2 * bb * l1, c2 = bb - aa;
d = c1 * c1 - 4 * c2 * c; d = c1 * c1 - 4 * c2 * c;
@ -2779,7 +2815,7 @@ var spine;
a1 -= 360; a1 -= 360;
else if (a1 < -180) else if (a1 < -180)
a1 += 360; a1 += 360;
parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, parent.ascaleX, parent.ascaleY, 0, 0); parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, parent.ascaleY, 0, 0);
rotation = child.arotation; rotation = child.arotation;
a2 = ((a2 + os) * spine.MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation; a2 = ((a2 + os) * spine.MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation;
if (a2 > 180) if (a2 > 180)
@ -2799,6 +2835,7 @@ var spine;
this.order = 0; this.order = 0;
this.bones = new Array(); this.bones = new Array();
this.bendDirection = 1; this.bendDirection = 1;
this.stretch = false;
this.mix = 1; this.mix = 1;
this.name = name; this.name = name;
} }
@ -3584,6 +3621,7 @@ var spine;
for (var i = 0, n = ikConstraints.length; i < n; i++) { for (var i = 0, n = ikConstraints.length; i < n; i++) {
var constraint = ikConstraints[i]; var constraint = ikConstraints[i];
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
constraint.mix = constraint.data.mix; constraint.mix = constraint.data.mix;
} }
var transformConstraints = this.transformConstraints; var transformConstraints = this.transformConstraints;
@ -4453,6 +4491,7 @@ var spine;
if (data.target == null) if (data.target == null)
throw new Error("IK target bone not found: " + targetName); throw new Error("IK target bone not found: " + targetName);
data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1; data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1;
data.stretch = this.getValue(constraintMap, "stretch", false);
data.mix = this.getValue(constraintMap, "mix", 1); data.mix = this.getValue(constraintMap, "mix", 1);
skeletonData.ikConstraints.push(data); skeletonData.ikConstraints.push(data);
} }
@ -4823,7 +4862,7 @@ var spine;
var frameIndex = 0; var frameIndex = 0;
for (var i = 0; i < constraintMap.length; i++) { for (var i = 0; i < constraintMap.length; i++) {
var valueMap = constraintMap[i]; var valueMap = constraintMap[i];
timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1); timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "stretch", false));
this.readCurve(valueMap, timeline, frameIndex); this.readCurve(valueMap, timeline, frameIndex);
frameIndex++; frameIndex++;
} }

File diff suppressed because one or more lines are too long

View File

@ -176,13 +176,15 @@ declare module spine {
static PREV_TIME: number; static PREV_TIME: number;
static PREV_MIX: number; static PREV_MIX: number;
static PREV_BEND_DIRECTION: number; static PREV_BEND_DIRECTION: number;
static PREV_STRETCH: number;
static MIX: number; static MIX: number;
static BEND_DIRECTION: number; static BEND_DIRECTION: number;
static STRETCH: number;
ikConstraintIndex: number; ikConstraintIndex: number;
frames: ArrayLike<number>; frames: ArrayLike<number>;
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void; setFrame(frameIndex: number, time: number, mix: number, bendDirection: number, stretch: boolean): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class TransformConstraintTimeline extends CurveTimeline { class TransformConstraintTimeline extends CurveTimeline {
@ -510,14 +512,15 @@ declare module spine {
data: IkConstraintData; data: IkConstraintData;
bones: Array<Bone>; bones: Array<Bone>;
target: Bone; target: Bone;
mix: number;
bendDirection: number; bendDirection: number;
stretch: boolean;
mix: number;
constructor(data: IkConstraintData, skeleton: Skeleton); constructor(data: IkConstraintData, skeleton: Skeleton);
getOrder(): number; getOrder(): number;
apply(): void; apply(): void;
update(): void; update(): void;
apply1(bone: Bone, targetX: number, targetY: number, alpha: number): void; apply1(bone: Bone, targetX: number, targetY: number, stretch: boolean, alpha: number): void;
apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, alpha: number): void; apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, stretch: boolean, alpha: number): void;
} }
} }
declare module spine { declare module spine {
@ -527,6 +530,7 @@ declare module spine {
bones: BoneData[]; bones: BoneData[];
target: BoneData; target: BoneData;
bendDirection: number; bendDirection: number;
stretch: boolean;
mix: number; mix: number;
constructor(name: string); constructor(name: string);
} }

View File

@ -1,7 +1,10 @@
var __extends = (this && this.__extends) || (function () { var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf || var extendStatics = function (d, b) {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || extendStatics = Object.setPrototypeOf ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }
@ -965,11 +968,12 @@ var spine;
IkConstraintTimeline.prototype.getPropertyId = function () { IkConstraintTimeline.prototype.getPropertyId = function () {
return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex; return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex;
}; };
IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, bendDirection) { IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, bendDirection, stretch) {
frameIndex *= IkConstraintTimeline.ENTRIES; frameIndex *= IkConstraintTimeline.ENTRIES;
this.frames[frameIndex] = time; this.frames[frameIndex] = time;
this.frames[frameIndex + IkConstraintTimeline.MIX] = mix; this.frames[frameIndex + IkConstraintTimeline.MIX] = mix;
this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection; this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection;
this.frames[frameIndex + IkConstraintTimeline.STRETCH] = stretch ? 1 : 0;
}; };
IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
var frames = this.frames; var frames = this.frames;
@ -979,23 +983,33 @@ var spine;
case MixBlend.setup: case MixBlend.setup:
constraint.mix = constraint.data.mix; constraint.mix = constraint.data.mix;
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
return; return;
case MixBlend.first: case MixBlend.first:
constraint.mix += (constraint.data.mix - constraint.mix) * alpha; constraint.mix += (constraint.data.mix - constraint.mix) * alpha;
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
} }
return; return;
} }
if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) {
if (blend == MixBlend.setup) { if (blend == MixBlend.setup) {
constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha; constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha;
constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection if (direction == MixDirection.out) {
: frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
}
else {
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
else { else {
constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha; constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha;
if (direction == MixDirection["in"]) if (direction == MixDirection["in"]) {
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
return; return;
} }
@ -1005,20 +1019,31 @@ var spine;
var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime)); var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime));
if (blend == MixBlend.setup) { if (blend == MixBlend.setup) {
constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha; constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha;
constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection : frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; if (direction == MixDirection.out) {
constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
}
else {
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
else { else {
constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha; constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha;
if (direction == MixDirection["in"]) if (direction == MixDirection["in"]) {
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
}; };
IkConstraintTimeline.ENTRIES = 3; IkConstraintTimeline.ENTRIES = 4;
IkConstraintTimeline.PREV_TIME = -3; IkConstraintTimeline.PREV_TIME = -4;
IkConstraintTimeline.PREV_MIX = -2; IkConstraintTimeline.PREV_MIX = -3;
IkConstraintTimeline.PREV_BEND_DIRECTION = -1; IkConstraintTimeline.PREV_BEND_DIRECTION = -2;
IkConstraintTimeline.PREV_STRETCH = -1;
IkConstraintTimeline.MIX = 1; IkConstraintTimeline.MIX = 1;
IkConstraintTimeline.BEND_DIRECTION = 2; IkConstraintTimeline.BEND_DIRECTION = 2;
IkConstraintTimeline.STRETCH = 3;
return IkConstraintTimeline; return IkConstraintTimeline;
}(CurveTimeline)); }(CurveTimeline));
spine.IkConstraintTimeline = IkConstraintTimeline; spine.IkConstraintTimeline = IkConstraintTimeline;
@ -2608,8 +2633,9 @@ var spine;
(function (spine) { (function (spine) {
var IkConstraint = (function () { var IkConstraint = (function () {
function IkConstraint(data, skeleton) { function IkConstraint(data, skeleton) {
this.mix = 1;
this.bendDirection = 0; this.bendDirection = 0;
this.stretch = false;
this.mix = 1;
if (data == null) if (data == null)
throw new Error("data cannot be null."); throw new Error("data cannot be null.");
if (skeleton == null) if (skeleton == null)
@ -2617,6 +2643,7 @@ var spine;
this.data = data; this.data = data;
this.mix = data.mix; this.mix = data.mix;
this.bendDirection = data.bendDirection; this.bendDirection = data.bendDirection;
this.stretch = data.stretch;
this.bones = new Array(); this.bones = new Array();
for (var i = 0; i < data.bones.length; i++) for (var i = 0; i < data.bones.length; i++)
this.bones.push(skeleton.findBone(data.bones[i].name)); this.bones.push(skeleton.findBone(data.bones[i].name));
@ -2633,14 +2660,14 @@ var spine;
var bones = this.bones; var bones = this.bones;
switch (bones.length) { switch (bones.length) {
case 1: case 1:
this.apply1(bones[0], target.worldX, target.worldY, this.mix); this.apply1(bones[0], target.worldX, target.worldY, this.stretch, this.mix);
break; break;
case 2: case 2:
this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.mix); this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.mix);
break; break;
} }
}; };
IkConstraint.prototype.apply1 = function (bone, targetX, targetY, alpha) { IkConstraint.prototype.apply1 = function (bone, targetX, targetY, stretch, alpha) {
if (!bone.appliedValid) if (!bone.appliedValid)
bone.updateAppliedTransform(); bone.updateAppliedTransform();
var p = bone.parent; var p = bone.parent;
@ -2654,9 +2681,15 @@ var spine;
rotationIK -= 360; rotationIK -= 360;
else if (rotationIK < -180) else if (rotationIK < -180)
rotationIK += 360; rotationIK += 360;
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, bone.ascaleX, bone.ascaleY, bone.ashearX, bone.ashearY); var sx = bone.ascaleX;
if (stretch) {
var b = bone.data.length * sx, dd = Math.sqrt(tx * tx + ty * ty);
if (dd > b && b > 0.0001)
sx *= (dd / b - 1) * alpha + 1;
}
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, bone.ascaleY, bone.ashearX, bone.ashearY);
}; };
IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, alpha) { IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, stretch, alpha) {
if (alpha == 0) { if (alpha == 0) {
child.updateWorldTransform(); child.updateWorldTransform();
return; return;
@ -2665,7 +2698,7 @@ var spine;
parent.updateAppliedTransform(); parent.updateAppliedTransform();
if (!child.appliedValid) if (!child.appliedValid)
child.updateAppliedTransform(); child.updateAppliedTransform();
var px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, csx = child.ascaleX; var px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX;
var os1 = 0, os2 = 0, s2 = 0; var os1 = 0, os2 = 0, s2 = 0;
if (psx < 0) { if (psx < 0) {
psx = -psx; psx = -psx;
@ -2704,18 +2737,21 @@ var spine;
c = pp.c; c = pp.c;
d = pp.d; d = pp.d;
var id = 1 / (a * d - b * c), x = targetX - pp.worldX, y = targetY - pp.worldY; var id = 1 / (a * d - b * c), x = targetX - pp.worldX, y = targetY - pp.worldY;
var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py; var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py, dd = tx * tx + ty * ty;
x = cwx - pp.worldX; x = cwx - pp.worldX;
y = cwy - pp.worldY; y = cwy - pp.worldY;
var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py;
var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1 = 0, a2 = 0; var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1 = 0, a2 = 0;
outer: if (u) { outer: if (u) {
l2 *= psx; l2 *= psx;
var cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2); var cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);
if (cos < -1) if (cos < -1)
cos = -1; cos = -1;
else if (cos > 1) else if (cos > 1) {
cos = 1; cos = 1;
if (stretch && l1 + l2 > 0.0001)
sx *= (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1;
}
a2 = Math.acos(cos) * bendDir; a2 = Math.acos(cos) * bendDir;
a = l1 + l2 * cos; a = l1 + l2 * cos;
b = l2 * Math.sin(a2); b = l2 * Math.sin(a2);
@ -2724,7 +2760,7 @@ var spine;
else { else {
a = psx * l2; a = psx * l2;
b = psy * l2; b = psy * l2;
var aa = a * a, bb = b * b, dd = tx * tx + ty * ty, ta = Math.atan2(ty, tx); var aa = a * a, bb = b * b, ta = Math.atan2(ty, tx);
c = bb * l1 * l1 + aa * dd - aa * bb; c = bb * l1 * l1 + aa * dd - aa * bb;
var c1 = -2 * bb * l1, c2 = bb - aa; var c1 = -2 * bb * l1, c2 = bb - aa;
d = c1 * c1 - 4 * c2 * c; d = c1 * c1 - 4 * c2 * c;
@ -2779,7 +2815,7 @@ var spine;
a1 -= 360; a1 -= 360;
else if (a1 < -180) else if (a1 < -180)
a1 += 360; a1 += 360;
parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, parent.ascaleX, parent.ascaleY, 0, 0); parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, parent.ascaleY, 0, 0);
rotation = child.arotation; rotation = child.arotation;
a2 = ((a2 + os) * spine.MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation; a2 = ((a2 + os) * spine.MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation;
if (a2 > 180) if (a2 > 180)
@ -2799,6 +2835,7 @@ var spine;
this.order = 0; this.order = 0;
this.bones = new Array(); this.bones = new Array();
this.bendDirection = 1; this.bendDirection = 1;
this.stretch = false;
this.mix = 1; this.mix = 1;
this.name = name; this.name = name;
} }
@ -3584,6 +3621,7 @@ var spine;
for (var i = 0, n = ikConstraints.length; i < n; i++) { for (var i = 0, n = ikConstraints.length; i < n; i++) {
var constraint = ikConstraints[i]; var constraint = ikConstraints[i];
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
constraint.mix = constraint.data.mix; constraint.mix = constraint.data.mix;
} }
var transformConstraints = this.transformConstraints; var transformConstraints = this.transformConstraints;
@ -4453,6 +4491,7 @@ var spine;
if (data.target == null) if (data.target == null)
throw new Error("IK target bone not found: " + targetName); throw new Error("IK target bone not found: " + targetName);
data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1; data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1;
data.stretch = this.getValue(constraintMap, "stretch", false);
data.mix = this.getValue(constraintMap, "mix", 1); data.mix = this.getValue(constraintMap, "mix", 1);
skeletonData.ikConstraints.push(data); skeletonData.ikConstraints.push(data);
} }
@ -4823,7 +4862,7 @@ var spine;
var frameIndex = 0; var frameIndex = 0;
for (var i = 0; i < constraintMap.length; i++) { for (var i = 0; i < constraintMap.length; i++) {
var valueMap = constraintMap[i]; var valueMap = constraintMap[i];
timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1); timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "stretch", false));
this.readCurve(valueMap, timeline, frameIndex); this.readCurve(valueMap, timeline, frameIndex);
frameIndex++; frameIndex++;
} }

File diff suppressed because one or more lines are too long

View File

@ -176,13 +176,15 @@ declare module spine {
static PREV_TIME: number; static PREV_TIME: number;
static PREV_MIX: number; static PREV_MIX: number;
static PREV_BEND_DIRECTION: number; static PREV_BEND_DIRECTION: number;
static PREV_STRETCH: number;
static MIX: number; static MIX: number;
static BEND_DIRECTION: number; static BEND_DIRECTION: number;
static STRETCH: number;
ikConstraintIndex: number; ikConstraintIndex: number;
frames: ArrayLike<number>; frames: ArrayLike<number>;
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void; setFrame(frameIndex: number, time: number, mix: number, bendDirection: number, stretch: boolean): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class TransformConstraintTimeline extends CurveTimeline { class TransformConstraintTimeline extends CurveTimeline {
@ -510,14 +512,15 @@ declare module spine {
data: IkConstraintData; data: IkConstraintData;
bones: Array<Bone>; bones: Array<Bone>;
target: Bone; target: Bone;
mix: number;
bendDirection: number; bendDirection: number;
stretch: boolean;
mix: number;
constructor(data: IkConstraintData, skeleton: Skeleton); constructor(data: IkConstraintData, skeleton: Skeleton);
getOrder(): number; getOrder(): number;
apply(): void; apply(): void;
update(): void; update(): void;
apply1(bone: Bone, targetX: number, targetY: number, alpha: number): void; apply1(bone: Bone, targetX: number, targetY: number, stretch: boolean, alpha: number): void;
apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, alpha: number): void; apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, stretch: boolean, alpha: number): void;
} }
} }
declare module spine { declare module spine {
@ -527,6 +530,7 @@ declare module spine {
bones: BoneData[]; bones: BoneData[];
target: BoneData; target: BoneData;
bendDirection: number; bendDirection: number;
stretch: boolean;
mix: number; mix: number;
constructor(name: string); constructor(name: string);
} }

View File

@ -1,7 +1,10 @@
var __extends = (this && this.__extends) || (function () { var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf || var extendStatics = function (d, b) {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || extendStatics = Object.setPrototypeOf ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }
@ -965,11 +968,12 @@ var spine;
IkConstraintTimeline.prototype.getPropertyId = function () { IkConstraintTimeline.prototype.getPropertyId = function () {
return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex; return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex;
}; };
IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, bendDirection) { IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, bendDirection, stretch) {
frameIndex *= IkConstraintTimeline.ENTRIES; frameIndex *= IkConstraintTimeline.ENTRIES;
this.frames[frameIndex] = time; this.frames[frameIndex] = time;
this.frames[frameIndex + IkConstraintTimeline.MIX] = mix; this.frames[frameIndex + IkConstraintTimeline.MIX] = mix;
this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection; this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection;
this.frames[frameIndex + IkConstraintTimeline.STRETCH] = stretch ? 1 : 0;
}; };
IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
var frames = this.frames; var frames = this.frames;
@ -979,23 +983,33 @@ var spine;
case MixBlend.setup: case MixBlend.setup:
constraint.mix = constraint.data.mix; constraint.mix = constraint.data.mix;
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
return; return;
case MixBlend.first: case MixBlend.first:
constraint.mix += (constraint.data.mix - constraint.mix) * alpha; constraint.mix += (constraint.data.mix - constraint.mix) * alpha;
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
} }
return; return;
} }
if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) {
if (blend == MixBlend.setup) { if (blend == MixBlend.setup) {
constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha; constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha;
constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection if (direction == MixDirection.out) {
: frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
}
else {
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
else { else {
constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha; constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha;
if (direction == MixDirection["in"]) if (direction == MixDirection["in"]) {
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
return; return;
} }
@ -1005,20 +1019,31 @@ var spine;
var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime)); var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime));
if (blend == MixBlend.setup) { if (blend == MixBlend.setup) {
constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha; constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha;
constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection : frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; if (direction == MixDirection.out) {
constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
}
else {
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
else { else {
constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha; constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha;
if (direction == MixDirection["in"]) if (direction == MixDirection["in"]) {
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
}; };
IkConstraintTimeline.ENTRIES = 3; IkConstraintTimeline.ENTRIES = 4;
IkConstraintTimeline.PREV_TIME = -3; IkConstraintTimeline.PREV_TIME = -4;
IkConstraintTimeline.PREV_MIX = -2; IkConstraintTimeline.PREV_MIX = -3;
IkConstraintTimeline.PREV_BEND_DIRECTION = -1; IkConstraintTimeline.PREV_BEND_DIRECTION = -2;
IkConstraintTimeline.PREV_STRETCH = -1;
IkConstraintTimeline.MIX = 1; IkConstraintTimeline.MIX = 1;
IkConstraintTimeline.BEND_DIRECTION = 2; IkConstraintTimeline.BEND_DIRECTION = 2;
IkConstraintTimeline.STRETCH = 3;
return IkConstraintTimeline; return IkConstraintTimeline;
}(CurveTimeline)); }(CurveTimeline));
spine.IkConstraintTimeline = IkConstraintTimeline; spine.IkConstraintTimeline = IkConstraintTimeline;
@ -2608,8 +2633,9 @@ var spine;
(function (spine) { (function (spine) {
var IkConstraint = (function () { var IkConstraint = (function () {
function IkConstraint(data, skeleton) { function IkConstraint(data, skeleton) {
this.mix = 1;
this.bendDirection = 0; this.bendDirection = 0;
this.stretch = false;
this.mix = 1;
if (data == null) if (data == null)
throw new Error("data cannot be null."); throw new Error("data cannot be null.");
if (skeleton == null) if (skeleton == null)
@ -2617,6 +2643,7 @@ var spine;
this.data = data; this.data = data;
this.mix = data.mix; this.mix = data.mix;
this.bendDirection = data.bendDirection; this.bendDirection = data.bendDirection;
this.stretch = data.stretch;
this.bones = new Array(); this.bones = new Array();
for (var i = 0; i < data.bones.length; i++) for (var i = 0; i < data.bones.length; i++)
this.bones.push(skeleton.findBone(data.bones[i].name)); this.bones.push(skeleton.findBone(data.bones[i].name));
@ -2633,14 +2660,14 @@ var spine;
var bones = this.bones; var bones = this.bones;
switch (bones.length) { switch (bones.length) {
case 1: case 1:
this.apply1(bones[0], target.worldX, target.worldY, this.mix); this.apply1(bones[0], target.worldX, target.worldY, this.stretch, this.mix);
break; break;
case 2: case 2:
this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.mix); this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.mix);
break; break;
} }
}; };
IkConstraint.prototype.apply1 = function (bone, targetX, targetY, alpha) { IkConstraint.prototype.apply1 = function (bone, targetX, targetY, stretch, alpha) {
if (!bone.appliedValid) if (!bone.appliedValid)
bone.updateAppliedTransform(); bone.updateAppliedTransform();
var p = bone.parent; var p = bone.parent;
@ -2654,9 +2681,15 @@ var spine;
rotationIK -= 360; rotationIK -= 360;
else if (rotationIK < -180) else if (rotationIK < -180)
rotationIK += 360; rotationIK += 360;
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, bone.ascaleX, bone.ascaleY, bone.ashearX, bone.ashearY); var sx = bone.ascaleX;
if (stretch) {
var b = bone.data.length * sx, dd = Math.sqrt(tx * tx + ty * ty);
if (dd > b && b > 0.0001)
sx *= (dd / b - 1) * alpha + 1;
}
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, bone.ascaleY, bone.ashearX, bone.ashearY);
}; };
IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, alpha) { IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, stretch, alpha) {
if (alpha == 0) { if (alpha == 0) {
child.updateWorldTransform(); child.updateWorldTransform();
return; return;
@ -2665,7 +2698,7 @@ var spine;
parent.updateAppliedTransform(); parent.updateAppliedTransform();
if (!child.appliedValid) if (!child.appliedValid)
child.updateAppliedTransform(); child.updateAppliedTransform();
var px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, csx = child.ascaleX; var px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX;
var os1 = 0, os2 = 0, s2 = 0; var os1 = 0, os2 = 0, s2 = 0;
if (psx < 0) { if (psx < 0) {
psx = -psx; psx = -psx;
@ -2704,18 +2737,21 @@ var spine;
c = pp.c; c = pp.c;
d = pp.d; d = pp.d;
var id = 1 / (a * d - b * c), x = targetX - pp.worldX, y = targetY - pp.worldY; var id = 1 / (a * d - b * c), x = targetX - pp.worldX, y = targetY - pp.worldY;
var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py; var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py, dd = tx * tx + ty * ty;
x = cwx - pp.worldX; x = cwx - pp.worldX;
y = cwy - pp.worldY; y = cwy - pp.worldY;
var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py;
var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1 = 0, a2 = 0; var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1 = 0, a2 = 0;
outer: if (u) { outer: if (u) {
l2 *= psx; l2 *= psx;
var cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2); var cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);
if (cos < -1) if (cos < -1)
cos = -1; cos = -1;
else if (cos > 1) else if (cos > 1) {
cos = 1; cos = 1;
if (stretch && l1 + l2 > 0.0001)
sx *= (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1;
}
a2 = Math.acos(cos) * bendDir; a2 = Math.acos(cos) * bendDir;
a = l1 + l2 * cos; a = l1 + l2 * cos;
b = l2 * Math.sin(a2); b = l2 * Math.sin(a2);
@ -2724,7 +2760,7 @@ var spine;
else { else {
a = psx * l2; a = psx * l2;
b = psy * l2; b = psy * l2;
var aa = a * a, bb = b * b, dd = tx * tx + ty * ty, ta = Math.atan2(ty, tx); var aa = a * a, bb = b * b, ta = Math.atan2(ty, tx);
c = bb * l1 * l1 + aa * dd - aa * bb; c = bb * l1 * l1 + aa * dd - aa * bb;
var c1 = -2 * bb * l1, c2 = bb - aa; var c1 = -2 * bb * l1, c2 = bb - aa;
d = c1 * c1 - 4 * c2 * c; d = c1 * c1 - 4 * c2 * c;
@ -2779,7 +2815,7 @@ var spine;
a1 -= 360; a1 -= 360;
else if (a1 < -180) else if (a1 < -180)
a1 += 360; a1 += 360;
parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, parent.ascaleX, parent.ascaleY, 0, 0); parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, parent.ascaleY, 0, 0);
rotation = child.arotation; rotation = child.arotation;
a2 = ((a2 + os) * spine.MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation; a2 = ((a2 + os) * spine.MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation;
if (a2 > 180) if (a2 > 180)
@ -2799,6 +2835,7 @@ var spine;
this.order = 0; this.order = 0;
this.bones = new Array(); this.bones = new Array();
this.bendDirection = 1; this.bendDirection = 1;
this.stretch = false;
this.mix = 1; this.mix = 1;
this.name = name; this.name = name;
} }
@ -3584,6 +3621,7 @@ var spine;
for (var i = 0, n = ikConstraints.length; i < n; i++) { for (var i = 0, n = ikConstraints.length; i < n; i++) {
var constraint = ikConstraints[i]; var constraint = ikConstraints[i];
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
constraint.mix = constraint.data.mix; constraint.mix = constraint.data.mix;
} }
var transformConstraints = this.transformConstraints; var transformConstraints = this.transformConstraints;
@ -4453,6 +4491,7 @@ var spine;
if (data.target == null) if (data.target == null)
throw new Error("IK target bone not found: " + targetName); throw new Error("IK target bone not found: " + targetName);
data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1; data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1;
data.stretch = this.getValue(constraintMap, "stretch", false);
data.mix = this.getValue(constraintMap, "mix", 1); data.mix = this.getValue(constraintMap, "mix", 1);
skeletonData.ikConstraints.push(data); skeletonData.ikConstraints.push(data);
} }
@ -4823,7 +4862,7 @@ var spine;
var frameIndex = 0; var frameIndex = 0;
for (var i = 0; i < constraintMap.length; i++) { for (var i = 0; i < constraintMap.length; i++) {
var valueMap = constraintMap[i]; var valueMap = constraintMap[i];
timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1); timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "stretch", false));
this.readCurve(valueMap, timeline, frameIndex); this.readCurve(valueMap, timeline, frameIndex);
frameIndex++; frameIndex++;
} }

File diff suppressed because one or more lines are too long

View File

@ -176,13 +176,15 @@ declare module spine {
static PREV_TIME: number; static PREV_TIME: number;
static PREV_MIX: number; static PREV_MIX: number;
static PREV_BEND_DIRECTION: number; static PREV_BEND_DIRECTION: number;
static PREV_STRETCH: number;
static MIX: number; static MIX: number;
static BEND_DIRECTION: number; static BEND_DIRECTION: number;
static STRETCH: number;
ikConstraintIndex: number; ikConstraintIndex: number;
frames: ArrayLike<number>; frames: ArrayLike<number>;
constructor(frameCount: number); constructor(frameCount: number);
getPropertyId(): number; getPropertyId(): number;
setFrame(frameIndex: number, time: number, mix: number, bendDirection: number): void; setFrame(frameIndex: number, time: number, mix: number, bendDirection: number, stretch: boolean): void;
apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void; apply(skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection): void;
} }
class TransformConstraintTimeline extends CurveTimeline { class TransformConstraintTimeline extends CurveTimeline {
@ -510,14 +512,15 @@ declare module spine {
data: IkConstraintData; data: IkConstraintData;
bones: Array<Bone>; bones: Array<Bone>;
target: Bone; target: Bone;
mix: number;
bendDirection: number; bendDirection: number;
stretch: boolean;
mix: number;
constructor(data: IkConstraintData, skeleton: Skeleton); constructor(data: IkConstraintData, skeleton: Skeleton);
getOrder(): number; getOrder(): number;
apply(): void; apply(): void;
update(): void; update(): void;
apply1(bone: Bone, targetX: number, targetY: number, alpha: number): void; apply1(bone: Bone, targetX: number, targetY: number, stretch: boolean, alpha: number): void;
apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, alpha: number): void; apply2(parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, stretch: boolean, alpha: number): void;
} }
} }
declare module spine { declare module spine {
@ -527,6 +530,7 @@ declare module spine {
bones: BoneData[]; bones: BoneData[];
target: BoneData; target: BoneData;
bendDirection: number; bendDirection: number;
stretch: boolean;
mix: number; mix: number;
constructor(name: string); constructor(name: string);
} }

View File

@ -1,7 +1,10 @@
var __extends = (this && this.__extends) || (function () { var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf || var extendStatics = function (d, b) {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || extendStatics = Object.setPrototypeOf ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }
@ -965,11 +968,12 @@ var spine;
IkConstraintTimeline.prototype.getPropertyId = function () { IkConstraintTimeline.prototype.getPropertyId = function () {
return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex; return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex;
}; };
IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, bendDirection) { IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, bendDirection, stretch) {
frameIndex *= IkConstraintTimeline.ENTRIES; frameIndex *= IkConstraintTimeline.ENTRIES;
this.frames[frameIndex] = time; this.frames[frameIndex] = time;
this.frames[frameIndex + IkConstraintTimeline.MIX] = mix; this.frames[frameIndex + IkConstraintTimeline.MIX] = mix;
this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection; this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection;
this.frames[frameIndex + IkConstraintTimeline.STRETCH] = stretch ? 1 : 0;
}; };
IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) { IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, blend, direction) {
var frames = this.frames; var frames = this.frames;
@ -979,23 +983,33 @@ var spine;
case MixBlend.setup: case MixBlend.setup:
constraint.mix = constraint.data.mix; constraint.mix = constraint.data.mix;
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
return; return;
case MixBlend.first: case MixBlend.first:
constraint.mix += (constraint.data.mix - constraint.mix) * alpha; constraint.mix += (constraint.data.mix - constraint.mix) * alpha;
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
} }
return; return;
} }
if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) {
if (blend == MixBlend.setup) { if (blend == MixBlend.setup) {
constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha; constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha;
constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection if (direction == MixDirection.out) {
: frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
}
else {
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
else { else {
constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha; constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha;
if (direction == MixDirection["in"]) if (direction == MixDirection["in"]) {
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
return; return;
} }
@ -1005,20 +1019,31 @@ var spine;
var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime)); var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime));
if (blend == MixBlend.setup) { if (blend == MixBlend.setup) {
constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha; constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha;
constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection : frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; if (direction == MixDirection.out) {
constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
}
else {
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
else { else {
constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha; constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha;
if (direction == MixDirection["in"]) if (direction == MixDirection["in"]) {
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
}; };
IkConstraintTimeline.ENTRIES = 3; IkConstraintTimeline.ENTRIES = 4;
IkConstraintTimeline.PREV_TIME = -3; IkConstraintTimeline.PREV_TIME = -4;
IkConstraintTimeline.PREV_MIX = -2; IkConstraintTimeline.PREV_MIX = -3;
IkConstraintTimeline.PREV_BEND_DIRECTION = -1; IkConstraintTimeline.PREV_BEND_DIRECTION = -2;
IkConstraintTimeline.PREV_STRETCH = -1;
IkConstraintTimeline.MIX = 1; IkConstraintTimeline.MIX = 1;
IkConstraintTimeline.BEND_DIRECTION = 2; IkConstraintTimeline.BEND_DIRECTION = 2;
IkConstraintTimeline.STRETCH = 3;
return IkConstraintTimeline; return IkConstraintTimeline;
}(CurveTimeline)); }(CurveTimeline));
spine.IkConstraintTimeline = IkConstraintTimeline; spine.IkConstraintTimeline = IkConstraintTimeline;
@ -2608,8 +2633,9 @@ var spine;
(function (spine) { (function (spine) {
var IkConstraint = (function () { var IkConstraint = (function () {
function IkConstraint(data, skeleton) { function IkConstraint(data, skeleton) {
this.mix = 1;
this.bendDirection = 0; this.bendDirection = 0;
this.stretch = false;
this.mix = 1;
if (data == null) if (data == null)
throw new Error("data cannot be null."); throw new Error("data cannot be null.");
if (skeleton == null) if (skeleton == null)
@ -2617,6 +2643,7 @@ var spine;
this.data = data; this.data = data;
this.mix = data.mix; this.mix = data.mix;
this.bendDirection = data.bendDirection; this.bendDirection = data.bendDirection;
this.stretch = data.stretch;
this.bones = new Array(); this.bones = new Array();
for (var i = 0; i < data.bones.length; i++) for (var i = 0; i < data.bones.length; i++)
this.bones.push(skeleton.findBone(data.bones[i].name)); this.bones.push(skeleton.findBone(data.bones[i].name));
@ -2633,14 +2660,14 @@ var spine;
var bones = this.bones; var bones = this.bones;
switch (bones.length) { switch (bones.length) {
case 1: case 1:
this.apply1(bones[0], target.worldX, target.worldY, this.mix); this.apply1(bones[0], target.worldX, target.worldY, this.stretch, this.mix);
break; break;
case 2: case 2:
this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.mix); this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.mix);
break; break;
} }
}; };
IkConstraint.prototype.apply1 = function (bone, targetX, targetY, alpha) { IkConstraint.prototype.apply1 = function (bone, targetX, targetY, stretch, alpha) {
if (!bone.appliedValid) if (!bone.appliedValid)
bone.updateAppliedTransform(); bone.updateAppliedTransform();
var p = bone.parent; var p = bone.parent;
@ -2654,9 +2681,15 @@ var spine;
rotationIK -= 360; rotationIK -= 360;
else if (rotationIK < -180) else if (rotationIK < -180)
rotationIK += 360; rotationIK += 360;
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, bone.ascaleX, bone.ascaleY, bone.ashearX, bone.ashearY); var sx = bone.ascaleX;
if (stretch) {
var b = bone.data.length * sx, dd = Math.sqrt(tx * tx + ty * ty);
if (dd > b && b > 0.0001)
sx *= (dd / b - 1) * alpha + 1;
}
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, bone.ascaleY, bone.ashearX, bone.ashearY);
}; };
IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, alpha) { IkConstraint.prototype.apply2 = function (parent, child, targetX, targetY, bendDir, stretch, alpha) {
if (alpha == 0) { if (alpha == 0) {
child.updateWorldTransform(); child.updateWorldTransform();
return; return;
@ -2665,7 +2698,7 @@ var spine;
parent.updateAppliedTransform(); parent.updateAppliedTransform();
if (!child.appliedValid) if (!child.appliedValid)
child.updateAppliedTransform(); child.updateAppliedTransform();
var px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, csx = child.ascaleX; var px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX;
var os1 = 0, os2 = 0, s2 = 0; var os1 = 0, os2 = 0, s2 = 0;
if (psx < 0) { if (psx < 0) {
psx = -psx; psx = -psx;
@ -2704,18 +2737,21 @@ var spine;
c = pp.c; c = pp.c;
d = pp.d; d = pp.d;
var id = 1 / (a * d - b * c), x = targetX - pp.worldX, y = targetY - pp.worldY; var id = 1 / (a * d - b * c), x = targetX - pp.worldX, y = targetY - pp.worldY;
var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py; var tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py, dd = tx * tx + ty * ty;
x = cwx - pp.worldX; x = cwx - pp.worldX;
y = cwy - pp.worldY; y = cwy - pp.worldY;
var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; var dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py;
var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1 = 0, a2 = 0; var l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1 = 0, a2 = 0;
outer: if (u) { outer: if (u) {
l2 *= psx; l2 *= psx;
var cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2); var cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);
if (cos < -1) if (cos < -1)
cos = -1; cos = -1;
else if (cos > 1) else if (cos > 1) {
cos = 1; cos = 1;
if (stretch && l1 + l2 > 0.0001)
sx *= (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1;
}
a2 = Math.acos(cos) * bendDir; a2 = Math.acos(cos) * bendDir;
a = l1 + l2 * cos; a = l1 + l2 * cos;
b = l2 * Math.sin(a2); b = l2 * Math.sin(a2);
@ -2724,7 +2760,7 @@ var spine;
else { else {
a = psx * l2; a = psx * l2;
b = psy * l2; b = psy * l2;
var aa = a * a, bb = b * b, dd = tx * tx + ty * ty, ta = Math.atan2(ty, tx); var aa = a * a, bb = b * b, ta = Math.atan2(ty, tx);
c = bb * l1 * l1 + aa * dd - aa * bb; c = bb * l1 * l1 + aa * dd - aa * bb;
var c1 = -2 * bb * l1, c2 = bb - aa; var c1 = -2 * bb * l1, c2 = bb - aa;
d = c1 * c1 - 4 * c2 * c; d = c1 * c1 - 4 * c2 * c;
@ -2779,7 +2815,7 @@ var spine;
a1 -= 360; a1 -= 360;
else if (a1 < -180) else if (a1 < -180)
a1 += 360; a1 += 360;
parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, parent.ascaleX, parent.ascaleY, 0, 0); parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, parent.ascaleY, 0, 0);
rotation = child.arotation; rotation = child.arotation;
a2 = ((a2 + os) * spine.MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation; a2 = ((a2 + os) * spine.MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation;
if (a2 > 180) if (a2 > 180)
@ -2799,6 +2835,7 @@ var spine;
this.order = 0; this.order = 0;
this.bones = new Array(); this.bones = new Array();
this.bendDirection = 1; this.bendDirection = 1;
this.stretch = false;
this.mix = 1; this.mix = 1;
this.name = name; this.name = name;
} }
@ -3584,6 +3621,7 @@ var spine;
for (var i = 0, n = ikConstraints.length; i < n; i++) { for (var i = 0, n = ikConstraints.length; i < n; i++) {
var constraint = ikConstraints[i]; var constraint = ikConstraints[i];
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
constraint.mix = constraint.data.mix; constraint.mix = constraint.data.mix;
} }
var transformConstraints = this.transformConstraints; var transformConstraints = this.transformConstraints;
@ -4453,6 +4491,7 @@ var spine;
if (data.target == null) if (data.target == null)
throw new Error("IK target bone not found: " + targetName); throw new Error("IK target bone not found: " + targetName);
data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1; data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1;
data.stretch = this.getValue(constraintMap, "stretch", false);
data.mix = this.getValue(constraintMap, "mix", 1); data.mix = this.getValue(constraintMap, "mix", 1);
skeletonData.ikConstraints.push(data); skeletonData.ikConstraints.push(data);
} }
@ -4823,7 +4862,7 @@ var spine;
var frameIndex = 0; var frameIndex = 0;
for (var i = 0; i < constraintMap.length; i++) { for (var i = 0; i < constraintMap.length; i++) {
var valueMap = constraintMap[i]; var valueMap = constraintMap[i];
timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1); timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "stretch", false));
this.readCurve(valueMap, timeline, frameIndex); this.readCurve(valueMap, timeline, frameIndex);
frameIndex++; frameIndex++;
} }

File diff suppressed because one or more lines are too long

View File

@ -1037,9 +1037,9 @@ module spine {
} }
export class IkConstraintTimeline extends CurveTimeline { export class IkConstraintTimeline extends CurveTimeline {
static ENTRIES = 3; static ENTRIES = 4;
static PREV_TIME = -3; static PREV_MIX = -2; static PREV_BEND_DIRECTION = -1; static PREV_TIME = -4; static PREV_MIX = -3; static PREV_BEND_DIRECTION = -2; static PREV_STRETCH = -1;
static MIX = 1; static BEND_DIRECTION = 2; static MIX = 1; static BEND_DIRECTION = 2; static STRETCH = 3;
ikConstraintIndex: number; ikConstraintIndex: number;
frames: ArrayLike<number>; // time, mix, bendDirection, ... frames: ArrayLike<number>; // time, mix, bendDirection, ...
@ -1054,11 +1054,12 @@ module spine {
} }
/** Sets the time, mix and bend direction of the specified keyframe. */ /** Sets the time, mix and bend direction of the specified keyframe. */
setFrame (frameIndex: number, time: number, mix: number, bendDirection: number) { setFrame (frameIndex: number, time: number, mix: number, bendDirection: number, stretch: boolean) {
frameIndex *= IkConstraintTimeline.ENTRIES; frameIndex *= IkConstraintTimeline.ENTRIES;
this.frames[frameIndex] = time; this.frames[frameIndex] = time;
this.frames[frameIndex + IkConstraintTimeline.MIX] = mix; this.frames[frameIndex + IkConstraintTimeline.MIX] = mix;
this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection; this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection;
this.frames[frameIndex + IkConstraintTimeline.STRETCH] = stretch ? 1 : 0;
} }
apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) { apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
@ -1069,10 +1070,12 @@ module spine {
case MixBlend.setup: case MixBlend.setup:
constraint.mix = constraint.data.mix; constraint.mix = constraint.data.mix;
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
return; return;
case MixBlend.first: case MixBlend.first:
constraint.mix += (constraint.data.mix - constraint.mix) * alpha; constraint.mix += (constraint.data.mix - constraint.mix) * alpha;
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
} }
return; return;
} }
@ -1080,11 +1083,19 @@ module spine {
if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { // Time is after last frame. if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { // Time is after last frame.
if (blend == MixBlend.setup) { if (blend == MixBlend.setup) {
constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha; constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha;
constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection if (direction == MixDirection.out) {
: frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
} else {
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]
constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} else { } else {
constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha; constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha;
if (direction == MixDirection.in) constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; if (direction == MixDirection.in) {
constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
return; return;
} }
@ -1098,10 +1109,19 @@ module spine {
if (blend == MixBlend.setup) { if (blend == MixBlend.setup) {
constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha; constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha;
constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection : frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; if (direction == MixDirection.out) {
constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
} else {
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} else { } else {
constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha; constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha;
if (direction == MixDirection.in) constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; if (direction == MixDirection.in) {
constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0;
}
} }
} }
} }

View File

@ -33,8 +33,9 @@ module spine {
data: IkConstraintData; data: IkConstraintData;
bones: Array<Bone>; bones: Array<Bone>;
target: Bone; target: Bone;
mix = 1;
bendDirection = 0; bendDirection = 0;
stretch = false;
mix = 1;
constructor (data: IkConstraintData, skeleton: Skeleton) { constructor (data: IkConstraintData, skeleton: Skeleton) {
if (data == null) throw new Error("data cannot be null."); if (data == null) throw new Error("data cannot be null.");
@ -42,6 +43,7 @@ module spine {
this.data = data; this.data = data;
this.mix = data.mix; this.mix = data.mix;
this.bendDirection = data.bendDirection; this.bendDirection = data.bendDirection;
this.stretch = data.stretch;
this.bones = new Array<Bone>(); this.bones = new Array<Bone>();
for (let i = 0; i < data.bones.length; i++) for (let i = 0; i < data.bones.length; i++)
@ -62,17 +64,17 @@ module spine {
let bones = this.bones; let bones = this.bones;
switch (bones.length) { switch (bones.length) {
case 1: case 1:
this.apply1(bones[0], target.worldX, target.worldY, this.mix); this.apply1(bones[0], target.worldX, target.worldY, this.stretch, this.mix);
break; break;
case 2: case 2:
this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.mix); this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.mix);
break; break;
} }
} }
/** Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified in the world /** 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. */ * coordinate system. */
apply1 (bone: Bone, targetX: number, targetY: number, alpha: number) { apply1 (bone: Bone, targetX: number, targetY: number, stretch: boolean, alpha: number) {
if (!bone.appliedValid) bone.updateAppliedTransform(); if (!bone.appliedValid) bone.updateAppliedTransform();
let p = bone.parent; let p = bone.parent;
let id = 1 / (p.a * p.d - p.b * p.c); let id = 1 / (p.a * p.d - p.b * p.c);
@ -83,21 +85,26 @@ module spine {
if (rotationIK > 180) if (rotationIK > 180)
rotationIK -= 360; rotationIK -= 360;
else if (rotationIK < -180) rotationIK += 360; else if (rotationIK < -180) rotationIK += 360;
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, bone.ascaleX, bone.ascaleY, bone.ashearX, let sx = bone.ascaleX;
if (stretch) {
let b = bone.data.length * sx, dd = Math.sqrt(tx * tx + ty * ty);
if (dd > b && b > 0.0001) sx *= (dd / b - 1) * alpha + 1;
}
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, bone.ascaleY, bone.ashearX,
bone.ashearY); 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 /** Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as possible. The
* target is specified in the world coordinate system. * target is specified in the world coordinate system.
* @param child A direct descendant of the parent bone. */ * @param child A direct descendant of the parent bone. */
apply2 (parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, alpha: number) { apply2 (parent: Bone, child: Bone, targetX: number, targetY: number, bendDir: number, stretch: boolean, alpha: number) {
if (alpha == 0) { if (alpha == 0) {
child.updateWorldTransform(); child.updateWorldTransform();
return; return;
} }
if (!parent.appliedValid) parent.updateAppliedTransform(); if (!parent.appliedValid) parent.updateAppliedTransform();
if (!child.appliedValid) child.updateAppliedTransform(); if (!child.appliedValid) child.updateAppliedTransform();
let px = parent.ax, py = parent.ay, psx = parent.ascaleX, psy = parent.ascaleY, csx = child.ascaleX; let px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX;
let os1 = 0, os2 = 0, s2 = 0; let os1 = 0, os2 = 0, s2 = 0;
if (psx < 0) { if (psx < 0) {
psx = -psx; psx = -psx;
@ -133,7 +140,7 @@ module spine {
c = pp.c; c = pp.c;
d = pp.d; d = pp.d;
let id = 1 / (a * d - b * c), x = targetX - pp.worldX, y = targetY - pp.worldY; let id = 1 / (a * d - b * c), x = targetX - pp.worldX, y = targetY - pp.worldY;
let tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py; let tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py, dd = tx * tx + ty * ty;
x = cwx - pp.worldX; x = cwx - pp.worldX;
y = cwy - pp.worldY; y = cwy - pp.worldY;
let dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; let dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py;
@ -141,10 +148,13 @@ module spine {
outer: outer:
if (u) { if (u) {
l2 *= psx; l2 *= psx;
let cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2); let cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2);
if (cos < -1) if (cos < -1)
cos = -1; cos = -1;
else if (cos > 1) cos = 1; else if (cos > 1) {
cos = 1;
if (stretch && l1 + l2 > 0.0001) sx *= (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1;
}
a2 = Math.acos(cos) * bendDir; a2 = Math.acos(cos) * bendDir;
a = l1 + l2 * cos; a = l1 + l2 * cos;
b = l2 * Math.sin(a2); b = l2 * Math.sin(a2);
@ -152,7 +162,7 @@ module spine {
} else { } else {
a = psx * l2; a = psx * l2;
b = psy * l2; b = psy * l2;
let aa = a * a, bb = b * b, dd = tx * tx + ty * ty, ta = Math.atan2(ty, tx); let aa = a * a, bb = b * b, ta = Math.atan2(ty, tx);
c = bb * l1 * l1 + aa * dd - aa * bb; c = bb * l1 * l1 + aa * dd - aa * bb;
let c1 = -2 * bb * l1, c2 = bb - aa; let c1 = -2 * bb * l1, c2 = bb - aa;
d = c1 * c1 - 4 * c2 * c; d = c1 * c1 - 4 * c2 * c;
@ -204,7 +214,7 @@ module spine {
if (a1 > 180) if (a1 > 180)
a1 -= 360; a1 -= 360;
else if (a1 < -180) a1 += 360; else if (a1 < -180) a1 += 360;
parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, parent.ascaleX, parent.ascaleY, 0, 0); parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, parent.ascaleY, 0, 0);
rotation = child.arotation; rotation = child.arotation;
a2 = ((a2 + os) * MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation; a2 = ((a2 + os) * MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation;
if (a2 > 180) if (a2 > 180)

View File

@ -35,6 +35,7 @@ module spine {
bones = new Array<BoneData>(); bones = new Array<BoneData>();
target: BoneData; target: BoneData;
bendDirection = 1; bendDirection = 1;
stretch = false;
mix = 1; mix = 1;
constructor (name: string) { constructor (name: string) {

View File

@ -287,6 +287,7 @@ module spine {
for (let i = 0, n = ikConstraints.length; i < n; i++) { for (let i = 0, n = ikConstraints.length; i < n; i++) {
let constraint = ikConstraints[i]; let constraint = ikConstraints[i];
constraint.bendDirection = constraint.data.bendDirection; constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
constraint.mix = constraint.data.mix; constraint.mix = constraint.data.mix;
} }

View File

@ -124,6 +124,7 @@ module spine {
if (data.target == null) throw new Error("IK target bone not found: " + targetName); if (data.target == null) throw new Error("IK target bone not found: " + targetName);
data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1; data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1;
data.stretch = this.getValue(constraintMap, "stretch", false);
data.mix = this.getValue(constraintMap, "mix", 1); data.mix = this.getValue(constraintMap, "mix", 1);
skeletonData.ikConstraints.push(data); skeletonData.ikConstraints.push(data);
@ -520,7 +521,7 @@ module spine {
for (let i = 0; i < constraintMap.length; i++) { for (let i = 0; i < constraintMap.length; i++) {
let valueMap = constraintMap[i]; let valueMap = constraintMap[i];
timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1),
this.getValue(valueMap, "bendPositive", true) ? 1 : -1); this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "stretch", false));
this.readCurve(valueMap, timeline, frameIndex); this.readCurve(valueMap, timeline, frameIndex);
frameIndex++; frameIndex++;
} }

File diff suppressed because one or more lines are too long

View File

@ -78,6 +78,7 @@ function init () {
assetManager.loadTextureAtlas("assets/vine.atlas"); assetManager.loadTextureAtlas("assets/vine.atlas");
assetManager.loadText("assets/stretchyman-pro.json"); assetManager.loadText("assets/stretchyman-pro.json");
assetManager.loadTextureAtlas("assets/stretchyman.atlas"); assetManager.loadTextureAtlas("assets/stretchyman.atlas");
assetManager.loadText("assets/stretchyman-stretchy-ik.json");
assetManager.loadText("assets/coin-pro.json"); assetManager.loadText("assets/coin-pro.json");
assetManager.loadTextureAtlas("assets/coin.atlas"); assetManager.loadTextureAtlas("assets/coin.atlas");
requestAnimationFrame(load); requestAnimationFrame(load);
@ -92,6 +93,7 @@ function load () {
skeletons["goblins"] = loadSkeleton("goblins-pro", "walk", false, "goblin"); skeletons["goblins"] = loadSkeleton("goblins-pro", "walk", false, "goblin");
skeletons["vine"] = loadSkeleton("vine-pro", "grow", false); skeletons["vine"] = loadSkeleton("vine-pro", "grow", false);
skeletons["stretchyman"] = loadSkeleton("stretchyman-pro", "sneak", false); skeletons["stretchyman"] = loadSkeleton("stretchyman-pro", "sneak", false);
skeletons["stretchyman-stretchy-ik"] = loadSkeleton("stretchyman-stretchy-ik", "sneak", false);
skeletons["coin"] = loadSkeleton("coin-pro", "rotate", false); skeletons["coin"] = loadSkeleton("coin-pro", "rotate", false);
setupUI(); setupUI();
requestAnimationFrame(render); requestAnimationFrame(render);
@ -104,7 +106,7 @@ function loadSkeleton (name, initialAnimation, premultipliedAlpha, skin) {
if (skin === undefined) skin = "default"; if (skin === undefined) skin = "default";
// Load the texture atlas using name.atlas from the AssetManager. // Load the texture atlas using name.atlas from the AssetManager.
atlas = assetManager.get("assets/" + name.replace("-ess", "").replace("-pro", "") + ".atlas"); atlas = assetManager.get("assets/" + name.replace("-ess", "").replace("-pro", "").replace("-stretchy-ik", "") + ".atlas");
// Create a AtlasAttachmentLoader that resolves region, mesh, boundingbox and path attachments // Create a AtlasAttachmentLoader that resolves region, mesh, boundingbox and path attachments
atlasLoader = new spine.AtlasAttachmentLoader(atlas); atlasLoader = new spine.AtlasAttachmentLoader(atlas);