[haxe] 4.3 porting WIP - latest updates.

This commit is contained in:
Davide Tantillo 2025-06-20 10:04:40 +02:00
parent 09b12f8934
commit f468cd0fd9
9 changed files with 80 additions and 59 deletions

View File

@ -36,6 +36,10 @@ package spine;
* constraint or application code modifies the world transform after it was computed from the local transform. */
class Bone extends PosedActive<BoneData, BoneLocal, BonePose> {
static public var yDown:Bool = false;
static public var yDir(get, never):Int;
static private function get_yDir(): Int {
return Bone.yDown ? -1 : 1;
}
/** The parent bone, or null if this is the root bone. */
public final parent:Bone = null;

View File

@ -211,7 +211,7 @@ class PhysicsConstraint extends Constraint<PhysicsConstraint, PhysicsConstraintD
d = Math.pow(p.damping, 60 * t);
m = t * p.massInverse;
e = p.strength;
var w = f * p.wind, g = f * (Bone.yDown ? -p.gravity : p.gravity);
var w = f * p.wind, g = f * p.gravity * Bone.yDir;
ax = (w * skeleton.windX + g * skeleton.gravityX) * skeleton.scaleX;
ay = (w * skeleton.windY + g * skeleton.gravityY) * skeleton.scaleY;
}

View File

@ -93,7 +93,7 @@ class Skeleton {
* Bones that do not inherit scale are still affected by this property. */
public var scaleY(get, default):Float = 1;
function get_scaleY() {
return Bone.yDown ? -scaleY : scaleY;
return scaleY * Bone.yDir;
}
/** Returns the skeleton's time. This is used for time-based manipulations, such as spine.PhysicsConstraint.

View File

@ -232,10 +232,11 @@ class SkeletonBinary {
var constraints = skeletonData.constraints;
for (i in 0...constraintCount) {
var name = input.readString();
var nn = input.readInt(true);
var nn;
switch (input.readByte()) {
case CONSTRAINT_IK:
var data = new IkConstraintData(name);
nn = input.readInt(true);
var constraintBones = data.bones;
for (ii in 0...nn)
constraintBones.push(bones[input.readInt(true)]);
@ -252,6 +253,7 @@ class SkeletonBinary {
constraints[i] = data;
case CONSTRAINT_TRANSFORM:
var data = new TransformConstraintData(name);
nn = input.readInt(true);
var constraintBones = data.bones;
for (ii in 0...nn)
constraintBones.push(bones[input.readInt(true)]);
@ -324,6 +326,7 @@ class SkeletonBinary {
constraints[i] = data;
case CONSTRAINT_PATH:
var data = new PathConstraintData(name);
nn = input.readInt(true);
var constraintBones = data.bones;
for (ii in 0...nn)
constraintBones[ii] = bones[input.readInt(true)];
@ -345,7 +348,7 @@ class SkeletonBinary {
constraints[i] = data;
case CONSTRAINT_PHYSICS:
var data = new PhysicsConstraintData(name);
data.bone = bones[nn];
data.bone = bones[input.readInt(true)];
var flags = input.readByte();
data.skinRequired = (flags & 1) != 0;
if ((flags & 2) != 0) data.x = input.readFloat();
@ -374,30 +377,33 @@ class SkeletonBinary {
constraints[i] = data;
case CONSTRAINT_SLIDER:
var data = new SliderData(name);
data.skinRequired = (nn & 1) != 0;
data.loop = (nn & 2) != 0;
data.additive = (nn & 4) != 0;
if ((nn & 8) != 0) data.setup.time = input.readFloat();
if ((nn & 16) != 0) data.setup.mix = (nn & 32) != 0 ? input.readFloat() : 1;
if ((nn & 64) != 0) {
data.local = (nn & 128) != 0;
var flags = input.readByte();
data.skinRequired = (flags & 1) != 0;
data.loop = (flags & 2) != 0;
data.additive = (flags & 4) != 0;
if ((flags & 8) != 0) data.setup.time = input.readFloat();
if ((flags & 16) != 0) data.setup.mix = (flags & 32) != 0 ? input.readFloat() : 1;
if ((flags & 64) != 0) {
data.local = (flags & 128) != 0;
data.bone = bones[input.readInt(true)];
var offset = input.readFloat();
var propertyScale = 1.;
switch (input.readByte()) {
case 0: data.property = new FromRotate();
case 1:
offset *= scale;
propertyScale = scale;
data.property = new FromX();
case 2:
offset *= scale;
propertyScale = scale;
data.property = new FromY();
case 3: data.property = new FromScaleX();
case 4: data.property = new FromScaleY();
case 5: data.property = new FromShearY();
default: data.property = null;
}
data.property.offset = offset;
data.scale = input.readFloat();
data.property.offset = offset * propertyScale;
data.offset = input.readFloat();
data.scale = input.readFloat() / propertyScale;
}
constraints[i] = data;
}

View File

@ -352,8 +352,10 @@ class SkeletonJson {
if (data.bone == null) throw new SpineException("Slider bone not found: " + boneName);
var property = getString(constraintMap, "property");
data.property = fromProperty(property);
data.property.offset = getFloat(constraintMap, "offset", 0) * propertyScale(property, scale);
data.scale = getFloat(constraintMap, "scale");
var propertyScale = propertyScale(property, scale);
data.property.offset = getFloat(constraintMap, "from", 0) * propertyScale;
data.offset = getFloat(constraintMap, "to", 0);
data.scale = getFloat(constraintMap, "scale", 1) / propertyScale;
data.local = getBoolean(constraintMap, "local", false);
}
@ -958,13 +960,11 @@ class SkeletonJson {
if (constraint == null) throw new SpineException("Transform constraint not found: " + transformName);
var timeline = new TransformConstraintTimeline(timelineMap.length, timelineMap.length * 6,
skeletonData.constraints.indexOf(constraint));
var time = getFloat(keyMap, "time");
var mixRotate = getFloat(keyMap, "mixRotate", 0);
var mixX = getFloat(keyMap, "mixX", 0);
var mixY = getFloat(keyMap, "mixY", mixX);
var mixScaleX:Float = getFloat(keyMap, "mixScaleX", 0);
var mixScaleY:Float = getFloat(keyMap, "mixScaleY", mixScaleX);
var mixShearY:Float = getFloat(keyMap, "mixShearY", 0);
var time = getFloat(keyMap, "time", 0);
var mixRotate = getFloat(keyMap, "mixRotate", 1);
var mixX = getFloat(keyMap, "mixX", 1), mixY = getFloat(keyMap, "mixY", mixX);
var mixScaleX:Float = getFloat(keyMap, "mixScaleX", 1), mixScaleY:Float = getFloat(keyMap, "mixScaleY", 1);
var mixShearY:Float = getFloat(keyMap, "mixShearY", 1);
frame = 0;
bezier = 0;
@ -976,13 +976,11 @@ class SkeletonJson {
break;
}
var time2 = getFloat(nextMap, "time");
var time2 = getFloat(nextMap, "time", 0);
var mixRotate2 = getFloat(nextMap, "mixRotate", 1);
var mixX2 = getFloat(nextMap, "mixX", 1), mixY2 = getFloat(nextMap, "mixY", mixX2);
var mixScaleX2:Float = getFloat(nextMap, "mixScaleX", 1), mixScaleY2:Float = getFloat(nextMap, "mixScaleY", 1);
var mixShearY2:Float = getFloat(nextMap, "mixShearY", 1);
var mixX2 = getFloat(nextMap, "mixX", 1);
var mixY2 = getFloat(nextMap, "mixY", mixX2);
var mixScaleX2:Float = getFloat(nextMap, "mixScaleX", 1);
var mixScaleY2:Float = getFloat(nextMap, "mixScaleY", mixScaleX2);
var curve = keyMap.curve;
if (curve != null) {
bezier = readCurve(curve, timeline, bezier, frame, 0, time, time2, mixRotate, mixRotate2, 1);

View File

@ -64,7 +64,8 @@ class Slider extends Constraint<Slider, SliderData, SliderPose> {
if (bone != null) {
if (!bone.active) return;
if (data.local) bone.applied.validateLocalTransform(skeleton);
p.time = (data.property.value(bone.applied, data.local, offsets) - data.property.offset) * data.scale;
p.time = data.offset
+ (data.property.value(skeleton, bone.applied, data.local, offsets) - data.property.offset) * data.scale;
if (data.loop)
p.time = animation.duration + (p.time % animation.duration);
else

View File

@ -43,7 +43,8 @@ class SliderData extends ConstraintData<Slider, SliderPose> {
public var loop = false;
public var bone:BoneData = null;
public var property:FromProperty = null;
public var scale = 1.;
public var scale = 0.;
public var offset = 0.;
public var local = false;
public function new (name:String) {

View File

@ -80,7 +80,7 @@ class TransformConstraint extends Constraint<TransformConstraint, TransformConst
var f = 0;
while (f < fn) {
var from = fromItems[f];
var value = from.value(source, localSource, offsets) - from.offset;
var value = from.value(skeleton, source, localSource, offsets) - from.offset;
var toItems = from.to;
var t = 0, tn = from.to.length;
while (t < tn) {
@ -93,7 +93,7 @@ class TransformConstraint extends Constraint<TransformConstraint, TransformConst
else
clamped = MathUtils.clamp(clamped, to.max, to.offset);
}
to.apply(p, bone, clamped, localTarget, additive);
to.apply(skeleton, p, bone, clamped, localTarget, additive);
}
t++;
}

View File

@ -169,7 +169,7 @@ abstract class FromProperty {
public final to = new Array<ToProperty>();
/** Reads this property from the specified bone. */
abstract public function value (source:BonePose, local:Bool, offsets:Array<Float>):Float;
abstract public function value (skeleton:Skeleton, source:BonePose, local:Bool, offsets:Array<Float>):Float;
}
/** Constrained property for a TransformConstraint. */
@ -190,13 +190,13 @@ abstract class ToProperty {
abstract public function mix (pose:TransformConstraintPose):Float;
/** Applies the value to this property. */
abstract public function apply (pose:TransformConstraintPose, bone:BonePose, value:Float, local:Bool, additive:Bool):Void;
abstract public function apply (skeleton:Skeleton, pose:TransformConstraintPose, bone:BonePose, value:Float, local:Bool, additive:Bool):Void;
}
class FromRotate extends FromProperty {
public function value (source:BonePose, local:Bool, offsets:Array<Float>):Float {
public function value (skeleton:Skeleton, source:BonePose, local:Bool, offsets:Array<Float>):Float {
if (local) return source.rotation + offsets[TransformConstraintData.ROTATION];
var value = Math.atan2(source.c, source.a) * MathUtils.radDeg
var value = Math.atan2(source.c / skeleton.scaleY, source.a / skeleton.scaleX) * MathUtils.radDeg
+ (source.a * source.d - source.b * source.c > 0 ? offsets[TransformConstraintData.ROTATION] : -offsets[TransformConstraintData.ROTATION]);
if (value < 0) value += 360;
return value;
@ -208,13 +208,13 @@ class ToRotate extends ToProperty {
return pose.mixRotate;
}
public function apply (pose:TransformConstraintPose, bone:BonePose, value:Float, local:Bool, additive:Bool):Void {
public function apply (skeleton:Skeleton, pose:TransformConstraintPose, bone:BonePose, value:Float, local:Bool, additive:Bool):Void {
if (local) {
if (!additive) value -= bone.rotation;
bone.rotation += value * pose.mixRotate;
} else {
var a = bone.a, b = bone.b, c = bone.c, d = bone.d;
value *= MathUtils.degRad;
value *= MathUtils.degRad * Bone.yDir;
if (!additive) value -= Math.atan2(c, a);
if (value > Math.PI)
value -= MathUtils.PI2;
@ -231,8 +231,10 @@ class ToRotate extends ToProperty {
}
class FromX extends FromProperty {
public function value (source:BonePose, local:Bool, offsets:Array<Float>):Float {
return local ? source.x + offsets[TransformConstraintData.X] : offsets[TransformConstraintData.X] * source.a + offsets[TransformConstraintData.Y] * source.b + source.worldX;
public function value (skeleton:Skeleton, source:BonePose, local:Bool, offsets:Array<Float>):Float {
return local
? source.x + offsets[TransformConstraintData.X]
: (offsets[TransformConstraintData.X] * source.a + offsets[TransformConstraintData.Y] * source.b + source.worldX) / skeleton.scaleX;
}
}
@ -241,7 +243,7 @@ class ToX extends ToProperty {
return pose.mixX;
}
public function apply (pose:TransformConstraintPose, bone:BonePose, value:Float, local:Bool, additive:Bool):Void {
public function apply (skeleton:Skeleton, pose:TransformConstraintPose, bone:BonePose, value:Float, local:Bool, additive:Bool):Void {
if (local) {
if (!additive) value -= bone.x;
bone.x += value * pose.mixX;
@ -253,8 +255,10 @@ class ToX extends ToProperty {
}
class FromY extends FromProperty {
public function value (source:BonePose, local:Bool, offsets:Array<Float>):Float {
return local ? source.y + offsets[TransformConstraintData.Y] : offsets[TransformConstraintData.X] * source.c + offsets[TransformConstraintData.Y] * source.d + source.worldY;
public function value (skeleton:Skeleton, source:BonePose, local:Bool, offsets:Array<Float>):Float {
return local
? source.y + offsets[TransformConstraintData.Y]
: (offsets[TransformConstraintData.X] * source.c + offsets[TransformConstraintData.Y] * source.d + source.worldY) / skeleton.scaleY;
}
}
@ -263,20 +267,22 @@ class ToY extends ToProperty {
return pose.mixY;
}
public function apply (pose:TransformConstraintPose, bone:BonePose, value:Float, local:Bool, additive:Bool):Void {
public function apply (skeleton:Skeleton, pose:TransformConstraintPose, bone:BonePose, value:Float, local:Bool, additive:Bool):Void {
if (local) {
if (!additive) value -= bone.y;
bone.y += value * pose.mixY;
} else {
if (!additive) value -= bone.worldY;
bone.worldY += value * pose.mixY;
if (!additive) value -= bone.worldY * Bone.yDir;
bone.worldY += value * pose.mixY * Bone.yDir;
}
}
}
class FromScaleX extends FromProperty {
public function value (source:BonePose, local:Bool, offsets:Array<Float>):Float {
return (local ? source.scaleX : Math.sqrt(source.a * source.a + source.c * source.c)) + offsets[TransformConstraintData.SCALEX];
public function value (skeleton:Skeleton, source:BonePose, local:Bool, offsets:Array<Float>):Float {
if (local) return source.scaleX + offsets[TransformConstraintData.SCALEX];
var a = source.a / skeleton.scaleX, c = source.c / skeleton.scaleY;
return Math.sqrt(a * a + c * c) + offsets[TransformConstraintData.SCALEX];
}
}
@ -285,7 +291,7 @@ class ToScaleX extends ToProperty {
return pose.mixScaleX;
}
public function apply (pose:TransformConstraintPose, bone:BonePose, value:Float, local:Bool, additive:Bool):Void {
public function apply (skeleton:Skeleton, pose:TransformConstraintPose, bone:BonePose, value:Float, local:Bool, additive:Bool):Void {
if (local) {
if (additive)
bone.scaleX *= 1 + ((value - 1) * pose.mixScaleX);
@ -296,7 +302,7 @@ class ToScaleX extends ToProperty {
if (additive)
s = 1 + (value - 1) * pose.mixScaleX;
else {
s = Math.sqrt(bone.a * bone.a + bone.c * bone.c);
s = Math.sqrt(bone.a * bone.a + bone.c * bone.c) / skeleton.scaleX;
if (s != 0) s = 1 + (value / s - 1) * pose.mixScaleX;
}
bone.a *= s;
@ -306,8 +312,10 @@ class ToScaleX extends ToProperty {
}
class FromScaleY extends FromProperty {
public function value (source:BonePose, local:Bool, offsets:Array<Float>):Float {
return (local ? source.scaleY : Math.sqrt(source.b * source.b + source.d * source.d)) + offsets[TransformConstraintData.SCALEY];
public function value (skeleton:Skeleton, source:BonePose, local:Bool, offsets:Array<Float>):Float {
if (local) return source.scaleY + offsets[TransformConstraintData.SCALEY];
var b = source.b / skeleton.scaleX, d = source.d / skeleton.scaleY;
return Math.sqrt(b * b + d * d) + offsets[TransformConstraintData.SCALEY];
}
}
@ -316,7 +324,7 @@ class ToScaleY extends ToProperty {
return pose.mixScaleY;
}
public function apply (pose:TransformConstraintPose, bone:BonePose, value:Float, local:Bool, additive:Bool):Void {
public function apply (skeleton:Skeleton, pose:TransformConstraintPose, bone:BonePose, value:Float, local:Bool, additive:Bool):Void {
if (local) {
if (additive)
bone.scaleY *= 1 + ((value - 1) * pose.mixScaleY);
@ -327,7 +335,7 @@ class ToScaleY extends ToProperty {
if (additive)
s = 1 + (value - 1) * pose.mixScaleY;
else {
s = Math.sqrt(bone.b * bone.b + bone.d * bone.d);
s = Math.sqrt(bone.b * bone.b + bone.d * bone.d) / skeleton.scaleY * Bone.yDir;
if (s != 0) s = 1 + (value / s - 1) * pose.mixScaleY;
}
bone.b *= s;
@ -337,8 +345,11 @@ class ToScaleY extends ToProperty {
}
class FromShearY extends FromProperty {
public function value (source:BonePose, local:Bool, offsets:Array<Float>):Float {
return (local ? source.shearY : (Math.atan2(source.d, source.b) - Math.atan2(source.c, source.a)) * MathUtils.radDeg - 90) + offsets[TransformConstraintData.SHEARY];
public function value (skeleton:Skeleton, source:BonePose, local:Bool, offsets:Array<Float>):Float {
if (local) return source.shearY + offsets[TransformConstraintData.SHEARY];
var sx = 1 / skeleton.scaleX, sy = 1 / skeleton.scaleY;
return (Math.atan2(source.d * sy, source.b * sx) - Math.atan2(source.c * sy, source.a * sx))
* MathUtils.radDeg - 90 + offsets[TransformConstraintData.SHEARY];
}
}
@ -347,13 +358,13 @@ class ToShearY extends ToProperty {
return pose.mixShearY;
}
public function apply (pose:TransformConstraintPose, bone:BonePose, value:Float, local:Bool, additive:Bool):Void {
public function apply (skeleton:Skeleton, pose:TransformConstraintPose, bone:BonePose, value:Float, local:Bool, additive:Bool):Void {
if (local) {
if (!additive) value -= bone.shearY;
bone.shearY += value * pose.mixShearY;
} else {
var b = bone.b, d = bone.d, by = Math.atan2(d, b);
value = (value + 90) * MathUtils.degRad;
value = (value + 90) * MathUtils.degRad * Bone.yDir;
if (additive)
value -= Math.PI / 2;
else {