mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-09 16:48:43 +08:00
[as3] Ported addition of uniform/compressed IK and rotation fix. See #1163.
This commit is contained in:
parent
23c4f3501f
commit
057d81799b
Binary file not shown.
@ -34,6 +34,7 @@ package spine {
|
||||
public var bones : Vector.<Bone>;
|
||||
public var target : Bone;
|
||||
public var bendDirection : int;
|
||||
public var compress: Boolean;
|
||||
public var stretch: Boolean;
|
||||
public var mix : Number;
|
||||
|
||||
@ -43,6 +44,7 @@ package spine {
|
||||
_data = data;
|
||||
mix = data.mix;
|
||||
bendDirection = data.bendDirection;
|
||||
compress = data.compress;
|
||||
stretch = data.stretch;
|
||||
|
||||
bones = new Vector.<Bone>();
|
||||
@ -58,7 +60,7 @@ package spine {
|
||||
public function update() : void {
|
||||
switch (bones.length) {
|
||||
case 1:
|
||||
apply1(bones[0], target.worldX, target.worldY, stretch, mix);
|
||||
apply1(bones[0], target.worldX, target.worldY, compress, stretch, _data.uniform, mix);
|
||||
break;
|
||||
case 2:
|
||||
apply2(bones[0], bones[1], target.worldX, target.worldY, bendDirection, stretch, mix);
|
||||
@ -80,7 +82,7 @@ package 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. */
|
||||
static public function apply1(bone : Bone, targetX : Number, targetY : Number, stretch : Boolean, alpha : Number) : void {
|
||||
static public function apply1(bone : Bone, targetX : Number, targetY : Number, compress: Boolean, stretch : Boolean, uniform: Boolean, alpha : Number) : void {
|
||||
if (!bone.appliedValid) bone.updateAppliedTransform();
|
||||
var p : Bone = bone.parent;
|
||||
var id : Number = 1 / (p.a * p.d - p.b * p.c);
|
||||
@ -92,11 +94,16 @@ package spine {
|
||||
rotationIK -= 360;
|
||||
else if (rotationIK < -180) rotationIK += 360;
|
||||
var sx : Number = bone.ascaleX;
|
||||
var sy : Number = bone.ascaleY;
|
||||
if (stretch) {
|
||||
var b : Number = bone.data.length * sx, dd : Number = 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) {
|
||||
var s : Number = (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.ashearY);
|
||||
bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY);
|
||||
}
|
||||
|
||||
/** Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as possible. The
|
||||
|
||||
@ -36,7 +36,9 @@ package spine {
|
||||
public var target : BoneData;
|
||||
public var mix : Number = 1;
|
||||
public var bendDirection : int = 1;
|
||||
public var compress : Boolean = false;
|
||||
public var stretch : Boolean = false;
|
||||
public var uniform : Boolean = false;
|
||||
|
||||
public function IkConstraintData(name : String) {
|
||||
if (name == null) throw new ArgumentError("name cannot be null.");
|
||||
|
||||
@ -290,9 +290,10 @@ package spine {
|
||||
bone.setToSetupPose();
|
||||
|
||||
for each (var ikConstraint : IkConstraint in ikConstraints) {
|
||||
ikConstraint.bendDirection = ikConstraint._data.bendDirection;
|
||||
ikConstraint.stretch = ikConstraint._data.stretch;
|
||||
ikConstraint.mix = ikConstraint._data.mix;
|
||||
ikConstraint.bendDirection = ikConstraint._data.bendDirection;
|
||||
ikConstraint.compress = ikConstraint._data.compress;
|
||||
ikConstraint.stretch = ikConstraint._data.stretch;
|
||||
}
|
||||
|
||||
for each (var transformConstraint : TransformConstraint in transformConstraints) {
|
||||
|
||||
@ -158,7 +158,9 @@ package spine {
|
||||
if (!ikConstraintData.target) throw new Error("Target bone not found: " + constraintMap["target"]);
|
||||
|
||||
ikConstraintData.bendDirection = (!constraintMap.hasOwnProperty("bendPositive") || constraintMap["bendPositive"]) ? 1 : -1;
|
||||
ikConstraintData.stretch = (!constraintMap.hasOwnProperty("stretch") || constraintMap["stretch"]);
|
||||
ikConstraintData.compress = (constraintMap.hasOwnProperty("compress") && constraintMap["compress"]);
|
||||
ikConstraintData.stretch = (constraintMap.hasOwnProperty("stretch") && constraintMap["stretch"]);
|
||||
ikConstraintData.uniform = (constraintMap.hasOwnProperty("uniform") && constraintMap["uniform"]);
|
||||
ikConstraintData.mix = constraintMap.hasOwnProperty("mix") ? constraintMap["mix"] : 1;
|
||||
|
||||
skeletonData.ikConstraints.push(ikConstraintData);
|
||||
@ -532,8 +534,9 @@ package spine {
|
||||
for each (valueMap in values) {
|
||||
var mix : Number = valueMap.hasOwnProperty("mix") ? valueMap["mix"] : 1;
|
||||
var bendDirection : int = (!valueMap.hasOwnProperty("bendPositive") || valueMap["bendPositive"]) ? 1 : -1;
|
||||
var stretch : Boolean = (!valueMap.hasOwnProperty("stretch") || valueMap["stretch"]);
|
||||
ikTimeline.setFrame(frameIndex, valueMap["time"], mix, bendDirection, stretch);
|
||||
var compress : Boolean = (valueMap.hasOwnProperty("compress") && valueMap["compress"]);
|
||||
var stretch : Boolean = (valueMap.hasOwnProperty("stretch") && valueMap["stretch"]);
|
||||
ikTimeline.setFrame(frameIndex, valueMap["time"], mix, bendDirection, compress, stretch);
|
||||
readCurve(valueMap, ikTimeline, frameIndex);
|
||||
frameIndex++;
|
||||
}
|
||||
|
||||
@ -314,10 +314,10 @@ package spine.animation {
|
||||
// Mix between rotations using the direction of the shortest route on the first frame while detecting crosses.
|
||||
var r1 : Number = blend == MixBlend.setup ? bone.data.rotation : bone.rotation;
|
||||
var total : Number, diff : Number = r2 - r1;
|
||||
diff -= (16384 - int((16384.499999999996 - diff / 360))) * 360;
|
||||
if (diff == 0) {
|
||||
total = timelinesRotation[i];
|
||||
} else {
|
||||
diff -= (16384 - int((16384.499999999996 - diff / 360))) * 360;
|
||||
} else {
|
||||
var lastTotal : Number, lastDiff : Number;
|
||||
if (firstFrame) {
|
||||
lastTotal = 0;
|
||||
|
||||
@ -34,11 +34,11 @@ package spine.animation {
|
||||
import spine.Skeleton;
|
||||
|
||||
public class IkConstraintTimeline extends CurveTimeline {
|
||||
static public const ENTRIES : int = 4;
|
||||
static internal const PREV_TIME : int = -4, PREV_MIX : int = -3, PREV_BEND_DIRECTION : int = -2, PREV_STRETCH : int = -1;
|
||||
static internal const MIX : int = 1, BEND_DIRECTION : int = 2, STRETCH : int = 3;
|
||||
static public const ENTRIES : int = 5;
|
||||
static internal const PREV_TIME : int = -5, PREV_MIX : int = -4, PREV_BEND_DIRECTION : int = -3, PREV_COMPRESS : int = -2, PREV_STRETCH : int = -1;
|
||||
static internal const MIX : int = 1, BEND_DIRECTION : int = 2, COMPRESS : int = 3, STRETCH : int = 4;
|
||||
public var ikConstraintIndex : int;
|
||||
public var frames : Vector.<Number>; // time, mix, bendDirection, ...
|
||||
public var frames : Vector.<Number>; // time, mix, bendDirection, compress, stretch, ...
|
||||
|
||||
public function IkConstraintTimeline(frameCount : int) {
|
||||
super(frameCount);
|
||||
@ -50,11 +50,12 @@ package spine.animation {
|
||||
}
|
||||
|
||||
/** Sets the time, mix and bend direction of the specified keyframe. */
|
||||
public function setFrame(frameIndex : int, time : Number, mix : Number, bendDirection : int, stretch: Boolean) : void {
|
||||
public function setFrame(frameIndex : int, time : Number, mix : Number, bendDirection : int, compress: Boolean, stretch: Boolean) : void {
|
||||
frameIndex *= ENTRIES;
|
||||
frames[frameIndex] = time;
|
||||
frames[int(frameIndex + MIX)] = mix;
|
||||
frames[int(frameIndex + BEND_DIRECTION)] = bendDirection;
|
||||
frames[int(frameIndex + COMPRESS)] = compress ? 1 : 0;
|
||||
frames[int(frameIndex + STRETCH)] = stretch ? 1 : 0;
|
||||
}
|
||||
|
||||
@ -65,11 +66,13 @@ package spine.animation {
|
||||
case MixBlend.setup:
|
||||
constraint.mix = constraint.data.mix;
|
||||
constraint.bendDirection = constraint.data.bendDirection;
|
||||
constraint.compress = constraint.data.compress;
|
||||
constraint.stretch = constraint.data.stretch;
|
||||
return;
|
||||
case MixBlend.first:
|
||||
constraint.mix += (constraint.data.mix - constraint.mix) * alpha;
|
||||
constraint.bendDirection = constraint.data.bendDirection;
|
||||
constraint.compress = constraint.data.compress;
|
||||
constraint.stretch = constraint.data.stretch;
|
||||
}
|
||||
return;
|
||||
@ -81,15 +84,18 @@ package spine.animation {
|
||||
|
||||
if (direction == MixDirection.Out) {
|
||||
constraint.bendDirection = constraint.data.bendDirection;
|
||||
constraint.compress = constraint.data.compress;
|
||||
constraint.stretch = constraint.data.stretch;
|
||||
} else {
|
||||
constraint.bendDirection = int(frames[frames.length + PREV_BEND_DIRECTION]);
|
||||
constraint.compress = int(frames[frames.length + PREV_COMPRESS]) != 0;
|
||||
constraint.stretch = int(frames[frames.length + PREV_STRETCH]) != 0;
|
||||
}
|
||||
} else {
|
||||
constraint.mix += (frames[frames.length + PREV_MIX] - constraint.mix) * alpha;
|
||||
if (direction == MixDirection.In) {
|
||||
constraint.bendDirection = int(frames[frames.length + PREV_BEND_DIRECTION]);
|
||||
constraint.compress = int(frames[frames.length + PREV_COMPRESS]) != 0;
|
||||
constraint.stretch = int(frames[frames.length + PREV_STRETCH]) != 0;
|
||||
}
|
||||
}
|
||||
@ -106,15 +112,18 @@ package spine.animation {
|
||||
constraint.mix = constraint.data.mix + (mix + (frames[frame + MIX] - mix) * percent - constraint.data.mix) * alpha;
|
||||
if (direction == MixDirection.Out) {
|
||||
constraint.bendDirection = constraint.data.bendDirection;
|
||||
constraint.compress = constraint.data.compress;
|
||||
constraint.stretch = constraint.data.stretch;
|
||||
} else {
|
||||
constraint.bendDirection = int(frames[frame + PREV_BEND_DIRECTION]);
|
||||
constraint.compress = int(frames[frame + PREV_COMPRESS]) != 0;
|
||||
constraint.stretch = int(frames[frame + PREV_STRETCH]) != 0;
|
||||
}
|
||||
} else {
|
||||
constraint.mix += (mix + (frames[frame + MIX] - mix) * percent - constraint.mix) * alpha;
|
||||
if (direction == MixDirection.In) {
|
||||
constraint.bendDirection = int(frames[frame + PREV_BEND_DIRECTION]);
|
||||
constraint.compress = int(frames[frame + PREV_COMPRESS]) != 0;
|
||||
constraint.stretch = int(frames[frame + PREV_STRETCH]) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user