[ts] Ported addition of uniform/compressed IK and rotation fix. See #1163.

This commit is contained in:
badlogic 2018-08-23 15:23:02 +02:00
parent 7df713b13f
commit 18f2ccf480
9 changed files with 10778 additions and 10750 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1037,12 +1037,12 @@ module spine {
}
export class IkConstraintTimeline extends CurveTimeline {
static ENTRIES = 4;
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 STRETCH = 3;
static ENTRIES = 5;
static PREV_TIME = -5; static PREV_MIX = -4; static PREV_BEND_DIRECTION = -3; static PREV_COMPRESS = -2; static PREV_STRETCH = -1;
static MIX = 1; static BEND_DIRECTION = 2; static COMPRESS = 3; static STRETCH = 4;
ikConstraintIndex: number;
frames: ArrayLike<number>; // time, mix, bendDirection, ...
frames: ArrayLike<number>; // time, mix, bendDirection, compress, stretch, ...
constructor (frameCount: number) {
super(frameCount);
@ -1054,11 +1054,12 @@ module spine {
}
/** Sets the time, mix and bend direction of the specified keyframe. */
setFrame (frameIndex: number, time: number, mix: number, bendDirection: number, stretch: boolean) {
setFrame (frameIndex: number, time: number, mix: number, bendDirection: number, compress: boolean, stretch: boolean) {
frameIndex *= IkConstraintTimeline.ENTRIES;
this.frames[frameIndex] = time;
this.frames[frameIndex + IkConstraintTimeline.MIX] = mix;
this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection;
this.frames[frameIndex + IkConstraintTimeline.COMPRESS] = compress ? 1 : 0;
this.frames[frameIndex + IkConstraintTimeline.STRETCH] = stretch ? 1 : 0;
}

View File

@ -304,10 +304,10 @@ module spine {
// Mix between rotations using the direction of the shortest route on the first frame while detecting crosses.
let r1 = blend == MixBlend.setup ? bone.data.rotation : bone.rotation;
let total = 0, diff = r2 - r1;
diff -= (16384 - ((16384.499999999996 - diff / 360) | 0)) * 360;
if (diff == 0) {
total = timelinesRotation[i];
} else {
diff -= (16384 - ((16384.499999999996 - diff / 360) | 0)) * 360;
let lastTotal = 0, lastDiff = 0;
if (firstFrame) {
lastTotal = 0;

View File

@ -34,6 +34,7 @@ module spine {
bones: Array<Bone>;
target: Bone;
bendDirection = 0;
compress = false;
stretch = false;
mix = 1;
@ -43,6 +44,7 @@ module spine {
this.data = data;
this.mix = data.mix;
this.bendDirection = data.bendDirection;
this.compress = data.compress;
this.stretch = data.stretch;
this.bones = new Array<Bone>();
@ -64,7 +66,7 @@ module spine {
let bones = this.bones;
switch (bones.length) {
case 1:
this.apply1(bones[0], target.worldX, target.worldY, this.stretch, this.mix);
this.apply1(bones[0], target.worldX, target.worldY, this.compress, this.stretch, this.data.uniform, this.mix);
break;
case 2:
this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.mix);
@ -74,7 +76,7 @@ module spine {
/** 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. */
apply1 (bone: Bone, targetX: number, targetY: number, stretch: boolean, alpha: number) {
apply1 (bone: Bone, targetX: number, targetY: number, compress: boolean, stretch: boolean, uniform: boolean, alpha: number) {
if (!bone.appliedValid) bone.updateAppliedTransform();
let p = bone.parent;
let id = 1 / (p.a * p.d - p.b * p.c);
@ -85,12 +87,16 @@ module spine {
if (rotationIK > 180)
rotationIK -= 360;
else if (rotationIK < -180) rotationIK += 360;
let sx = bone.ascaleX;
if (stretch) {
let sx = bone.ascaleX, sy = bone.ascaleY;
if (compress || 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;
if ((compress && dd < b) || (stretch && dd > b) && b > 0.0001) {
let s = (dd / b - 1) * alpha + 1;
sx *= s;
if (uniform) sy *= s;
}
}
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, bone.ascaleY, bone.ashearX,
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX,
bone.ashearY);
}

View File

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

View File

@ -286,9 +286,10 @@ module spine {
let ikConstraints = this.ikConstraints;
for (let i = 0, n = ikConstraints.length; i < n; i++) {
let constraint = ikConstraints[i];
constraint.bendDirection = constraint.data.bendDirection;
constraint.stretch = constraint.data.stretch;
constraint.mix = constraint.data.mix;
constraint.bendDirection = constraint.data.bendDirection;
constraint.compress = constraint.data.compress;
constraint.stretch = constraint.data.stretch;
}
let transformConstraints = this.transformConstraints;

View File

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