[ts] Port of commit 48355c2, abb4362: PhysicsConstraint fixes.

This commit is contained in:
Davide Tantillo 2025-09-15 11:32:57 +02:00
parent c01994c803
commit f8a125aa8a

View File

@ -27,10 +27,10 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/ *****************************************************************************/
import { BonePose } from "./BonePose.js"; import type { BonePose } from "./BonePose.js";
import { Constraint } from "./Constraint.js"; import { Constraint } from "./Constraint.js";
import { Physics } from "./Physics.js"; import { Physics } from "./Physics.js";
import { PhysicsConstraintData } from "./PhysicsConstraintData.js"; import type { PhysicsConstraintData } from "./PhysicsConstraintData.js";
import { PhysicsConstraintPose } from "./PhysicsConstraintPose.js"; import { PhysicsConstraintPose } from "./PhysicsConstraintPose.js";
import { Skeleton } from "./Skeleton.js"; import { Skeleton } from "./Skeleton.js";
import { MathUtils } from "./Utils.js"; import { MathUtils } from "./Utils.js";
@ -125,10 +125,10 @@ export class PhysicsConstraint extends Constraint<PhysicsConstraint, PhysicsCons
switch (physics) { switch (physics) {
case Physics.none: case Physics.none:
return; return;
// biome-ignore lint/suspicious/noFallthroughSwitchClause: fall through expected
case Physics.reset: case Physics.reset:
this.reset(skeleton); this.reset(skeleton); // Fall through.
// Fall through. case Physics.update: {
case Physics.update:
const delta = Math.max(skeleton.time - this.lastTime, 0), aa = this.remaining; const delta = Math.max(skeleton.time - this.lastTime, 0), aa = this.remaining;
this.remaining += delta; this.remaining += delta;
this.lastTime = skeleton.time; this.lastTime = skeleton.time;
@ -139,8 +139,8 @@ export class PhysicsConstraint extends Constraint<PhysicsConstraint, PhysicsCons
this.ux = bx; this.ux = bx;
this.uy = by; this.uy = by;
} else { } else {
let a = this.remaining, i = p.inertia, f = skeleton.data.referenceScale, d = -1, m = 0, e = 0, ax = 0, ay = 0, let a = this.remaining, i = p.inertia, f = skeleton.data.referenceScale, d = -1, m = 0, e = 0, qx = this.data.limit * delta,
qx = this.data.limit * delta, qy = qx * Math.abs(skeleton.scaleY); qy = qx * Math.abs(skeleton.scaleY);
qx *= Math.abs(skeleton.scaleX); qx *= Math.abs(skeleton.scaleX);
if (x || y) { if (x || y) {
if (x) { if (x) {
@ -154,13 +154,13 @@ export class PhysicsConstraint extends Constraint<PhysicsConstraint, PhysicsCons
this.uy = by; this.uy = by;
} }
if (a >= t) { if (a >= t) {
let xs = this.xOffset, ys = this.yOffset; const xs = this.xOffset, ys = this.yOffset;
d = Math.pow(p.damping, 60 * t); d = p.damping ** (60 * t);
m = t * p.massInverse; m = t * p.massInverse;
e = p.strength; e = p.strength;
let w = f * p.wind, g = f * p.gravity; const w = f * p.wind, g = f * p.gravity;
ax = (w * skeleton.windX + g * skeleton.gravityX) * skeleton.scaleX; const ax = (w * skeleton.windX + g * skeleton.gravityX) * skeleton.scaleX;
ay = (w * skeleton.windY + g * skeleton.gravityY) * skeleton.scaleY; const ay = (w * skeleton.windY + g * skeleton.gravityY) * skeleton.scaleY;
do { do {
if (x) { if (x) {
this.xVelocity += (ax - this.xOffset * e) * m; this.xVelocity += (ax - this.xOffset * e) * m;
@ -182,7 +182,7 @@ export class PhysicsConstraint extends Constraint<PhysicsConstraint, PhysicsCons
if (y) bone.worldY += (this.yOffset - this.yLag * z) * mix * this.data.y; if (y) bone.worldY += (this.yOffset - this.yLag * z) * mix * this.data.y;
} }
if (rotateOrShearX || scaleX) { if (rotateOrShearX || scaleX) {
let ca = Math.atan2(bone.c, bone.a), c, s, mr = 0, dx = this.cx - bone.worldX, dy = this.cy - bone.worldY; let ca = Math.atan2(bone.c, bone.a), c = 0, s = 0, mr = 0, dx = this.cx - bone.worldX, dy = this.cy - bone.worldY;
if (dx > qx) if (dx > qx)
dx = qx; dx = qx;
else if (dx < -qx) // else if (dx < -qx) //
@ -207,19 +207,18 @@ export class PhysicsConstraint extends Constraint<PhysicsConstraint, PhysicsCons
} else { } else {
c = Math.cos(ca); c = Math.cos(ca);
s = Math.sin(ca); s = Math.sin(ca);
let r = l * bone.getWorldScaleX() - this.scaleLag * Math.max(0, 1 - aa / t); const r = l * bone.getWorldScaleX() - this.scaleLag * Math.max(0, 1 - aa / t);
if (r > 0) this.scaleOffset += (dx * c + dy * s) * i / r; if (r > 0) this.scaleOffset += (dx * c + dy * s) * i / r;
} }
if (a >= t) { if (a >= t) {
if (d == -1) { if (d === -1) {
d = Math.pow(p.damping, 60 * t); d = p.damping ** (60 * t);
m = t * p.massInverse; m = t * p.massInverse;
e = p.strength; e = p.strength;
const w = f * p.wind, g = f * p.gravity * Skeleton.yDir;
ax = (w * skeleton.windX + g * skeleton.gravityX) * skeleton.scaleX;
ay = (w * skeleton.windY + g * skeleton.gravityY) * skeleton.scaleY;
} }
let rs = this.rotateOffset, ss = this.scaleOffset, h = l / f const ax = p.wind * skeleton.windX + p.gravity * skeleton.gravityX;
const ay = (p.wind * skeleton.windY + p.gravity * skeleton.gravityY) * Skeleton.yDir;
const rs = this.rotateOffset, ss = this.scaleOffset, h = l / f;
while (true) { while (true) {
a -= t; a -= t;
if (scaleX) { if (scaleX) {
@ -248,6 +247,7 @@ export class PhysicsConstraint extends Constraint<PhysicsConstraint, PhysicsCons
this.cx = bone.worldX; this.cx = bone.worldX;
this.cy = bone.worldY; this.cy = bone.worldY;
break; break;
}
case Physics.pose: case Physics.pose:
z = Math.max(0, 1 - this.remaining / t); z = Math.max(0, 1 - this.remaining / t);
if (x) bone.worldX += (this.xOffset - this.xLag * z) * mix * this.data.x; if (x) bone.worldX += (this.xOffset - this.xLag * z) * mix * this.data.x;
@ -289,7 +289,7 @@ export class PhysicsConstraint extends Constraint<PhysicsConstraint, PhysicsCons
bone.a *= s; bone.a *= s;
bone.c *= s; bone.c *= s;
} }
if (physics != Physics.pose) { if (physics !== Physics.pose) {
this.tx = l * bone.a; this.tx = l * bone.a;
this.ty = l * bone.c; this.ty = l * bone.c;
} }