Mario Zechner 1 rok pred
rodič
commit
fd0c20a2c7

+ 1 - 1
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java

@@ -2278,7 +2278,7 @@ public class Animation {
 			PhysicsConstraint constraint;
 			if (constraintIndex == -1) {
 				float value = time >= frames[0] ? getCurveValue(time) : 0;
-			
+
 				Object[] constraints = skeleton.physicsConstraints.items;
 				for (int i = 0, n = skeleton.physicsConstraints.size; i < n; i++) {
 					constraint = (PhysicsConstraint)constraints[i];

+ 1 - 1
spine-libgdx/spine-skeletonviewer/src/com/esotericsoftware/spine/SkeletonViewerUI.java

@@ -113,7 +113,7 @@ class SkeletonViewerUI {
 	CheckBox debugPathsCheckbox = new CheckBox("Paths", skin);
 	CheckBox debugPointsCheckbox = new CheckBox("Points", skin);
 	CheckBox debugClippingCheckbox = new CheckBox("Clipping", skin);
-	
+
 	CheckBox pmaCheckbox = new CheckBox("Premultiplied", skin);
 
 	CheckBox linearCheckbox = new CheckBox("Linear", skin);

+ 194 - 194
spine-ts/spine-core/src/Animation.ts

@@ -350,20 +350,20 @@ export abstract class CurveTimeline1 extends CurveTimeline {
 	getRelativeValue (time: number, alpha: number, blend: MixBlend, current: number, setup: number) {
 		if (time < this.frames[0]) {
 			switch (blend) {
-			case MixBlend.setup:
-				return setup;
-			case MixBlend.first:
-				return current + (setup - current) * alpha;
+				case MixBlend.setup:
+					return setup;
+				case MixBlend.first:
+					return current + (setup - current) * alpha;
 			}
 			return current;
 		}
 		let value = this.getCurveValue(time);
 		switch (blend) {
-		case MixBlend.setup:
-			return setup + value * alpha;
-		case MixBlend.first:
-		case MixBlend.replace:
-			value += setup - current;
+			case MixBlend.setup:
+				return setup + value * alpha;
+			case MixBlend.first:
+			case MixBlend.replace:
+				value += setup - current;
 		}
 		return current + value * alpha;
 	}
@@ -371,10 +371,10 @@ export abstract class CurveTimeline1 extends CurveTimeline {
 	getAbsoluteValue (time: number, alpha: number, blend: MixBlend, current: number, setup: number) {
 		if (time < this.frames[0]) {
 			switch (blend) {
-			case MixBlend.setup:
-				return setup;
-			case MixBlend.first:
-				return current + (setup - current) * alpha;
+				case MixBlend.setup:
+					return setup;
+				case MixBlend.first:
+					return current + (setup - current) * alpha;
 			}
 			return current;
 		}
@@ -383,13 +383,13 @@ export abstract class CurveTimeline1 extends CurveTimeline {
 		return current + (value - current) * alpha;
 	}
 
-	getAbsoluteValue2 (time: number, alpha: number, blend: MixBlend , current: number, setup: number, value: number) {
+	getAbsoluteValue2 (time: number, alpha: number, blend: MixBlend, current: number, setup: number, value: number) {
 		if (time < this.frames[0]) {
 			switch (blend) {
-			case MixBlend.setup:
-				return setup;
-			case MixBlend.first:
-				return current + (setup - current) * alpha;
+				case MixBlend.setup:
+					return setup;
+				case MixBlend.first:
+					return current + (setup - current) * alpha;
 			}
 			return current;
 		}
@@ -401,10 +401,10 @@ export abstract class CurveTimeline1 extends CurveTimeline {
 		const frames = this.frames;
 		if (time < frames[0]) {
 			switch (blend) {
-			case MixBlend.setup:
-				return setup;
-			case MixBlend.first:
-				return current + (setup - current) * alpha;
+				case MixBlend.setup:
+					return setup;
+				case MixBlend.first:
+					return current + (setup - current) * alpha;
 			}
 			return current;
 		}
@@ -416,22 +416,22 @@ export abstract class CurveTimeline1 extends CurveTimeline {
 		// Mixing out uses sign of setup or current pose, else use sign of key.
 		if (direction == MixDirection.mixOut) {
 			switch (blend) {
-			case MixBlend.setup:
-				return setup + (Math.abs(value) * MathUtils.signum(setup) - setup) * alpha;
-			case MixBlend.first:
-			case MixBlend.replace:
-				return current + (Math.abs(value) * MathUtils.signum(current) - current) * alpha;
+				case MixBlend.setup:
+					return setup + (Math.abs(value) * MathUtils.signum(setup) - setup) * alpha;
+				case MixBlend.first:
+				case MixBlend.replace:
+					return current + (Math.abs(value) * MathUtils.signum(current) - current) * alpha;
 			}
 		} else {
 			let s = 0;
 			switch (blend) {
-			case MixBlend.setup:
-				s = Math.abs(setup) * MathUtils.signum(value);
-				return s + (value - s) * alpha;
-			case MixBlend.first:
-			case MixBlend.replace:
-				s = Math.abs(current) * MathUtils.signum(value);
-				return s + (value - s) * alpha;
+				case MixBlend.setup:
+					s = Math.abs(setup) * MathUtils.signum(value);
+					return s + (value - s) * alpha;
+				case MixBlend.first:
+				case MixBlend.replace:
+					s = Math.abs(current) * MathUtils.signum(value);
+					return s + (value - s) * alpha;
 			}
 		}
 		return current + (value - setup) * alpha;
@@ -2024,220 +2024,220 @@ export abstract class PhysicsConstraintTimeline extends CurveTimeline1 {
 	abstract global (constraint: PhysicsConstraintData): boolean;
 }
 
-	/** Changes a physics constraint's {@link PhysicsConstraint#getInertia()}. */
-	export class PhysicsConstraintInertiaTimeline extends PhysicsConstraintTimeline {
-		constructor (frameCount: number, bezierCount: number, physicsConstraintIndex: number, property: number) {
-			super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintInertia);
-		}
+/** Changes a physics constraint's {@link PhysicsConstraint#getInertia()}. */
+export class PhysicsConstraintInertiaTimeline extends PhysicsConstraintTimeline {
+	constructor (frameCount: number, bezierCount: number, physicsConstraintIndex: number, property: number) {
+		super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintInertia);
+	}
 
-		setup (constraint: PhysicsConstraint): number {
-			return constraint.data.inertia;
-		}
+	setup (constraint: PhysicsConstraint): number {
+		return constraint.data.inertia;
+	}
 
-		get (constraint: PhysicsConstraint): number {
-			return constraint.inertia;
-		}
+	get (constraint: PhysicsConstraint): number {
+		return constraint.inertia;
+	}
 
-		set (constraint: PhysicsConstraint, value: number): void {
-			constraint.inertia = value;
-		}
+	set (constraint: PhysicsConstraint, value: number): void {
+		constraint.inertia = value;
+	}
 
-		global (constraint: PhysicsConstraintData): boolean {
-			return constraint.inertiaGlobal;
-		}
+	global (constraint: PhysicsConstraintData): boolean {
+		return constraint.inertiaGlobal;
 	}
+}
 
-	/** Changes a physics constraint's {@link PhysicsConstraint#getStrength()}. */
-	export class PhysicsConstraintStrengthTimeline extends PhysicsConstraintTimeline {
-		constructor (frameCount: number, bezierCount: number, physicsConstraintIndex: number, property: number) {
-			super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintStrength);
-		}
+/** Changes a physics constraint's {@link PhysicsConstraint#getStrength()}. */
+export class PhysicsConstraintStrengthTimeline extends PhysicsConstraintTimeline {
+	constructor (frameCount: number, bezierCount: number, physicsConstraintIndex: number, property: number) {
+		super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintStrength);
+	}
 
-		setup (constraint: PhysicsConstraint): number {
-			return constraint.data.strength;
-		}
+	setup (constraint: PhysicsConstraint): number {
+		return constraint.data.strength;
+	}
 
-		get (constraint: PhysicsConstraint): number {
-			return constraint.strength;
-		}
+	get (constraint: PhysicsConstraint): number {
+		return constraint.strength;
+	}
 
-		set (constraint: PhysicsConstraint, value: number): void {
-			constraint.strength = value;
-		}
+	set (constraint: PhysicsConstraint, value: number): void {
+		constraint.strength = value;
+	}
 
-		global (constraint: PhysicsConstraintData): boolean {
-			return constraint.strengthGlobal;
-		}
+	global (constraint: PhysicsConstraintData): boolean {
+		return constraint.strengthGlobal;
 	}
+}
 
-	/** Changes a physics constraint's {@link PhysicsConstraint#getDamping()}. */
-	export class PhysicsConstraintDampingTimeline extends PhysicsConstraintTimeline {
-		constructor (frameCount: number, bezierCount: number, physicsConstraintIndex: number, property: number) {
-			super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintDamping);
-		}
+/** Changes a physics constraint's {@link PhysicsConstraint#getDamping()}. */
+export class PhysicsConstraintDampingTimeline extends PhysicsConstraintTimeline {
+	constructor (frameCount: number, bezierCount: number, physicsConstraintIndex: number, property: number) {
+		super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintDamping);
+	}
 
-		setup (constraint: PhysicsConstraint): number {
-			return constraint.data.damping;
-		}
+	setup (constraint: PhysicsConstraint): number {
+		return constraint.data.damping;
+	}
 
-		get (constraint: PhysicsConstraint): number {
-			return constraint.damping;
-		}
+	get (constraint: PhysicsConstraint): number {
+		return constraint.damping;
+	}
 
-		set (constraint: PhysicsConstraint, value: number): void {
-			constraint.damping = value;
-		}
+	set (constraint: PhysicsConstraint, value: number): void {
+		constraint.damping = value;
+	}
 
-		global (constraint: PhysicsConstraintData): boolean {
-			return constraint.dampingGlobal;
-		}
+	global (constraint: PhysicsConstraintData): boolean {
+		return constraint.dampingGlobal;
 	}
+}
 
-	/** Changes a physics constraint's {@link PhysicsConstraint#getMassInverse()}. The timeline values are not inverted. */
-	export class PhysicsConstraintMassTimeline extends PhysicsConstraintTimeline {
-		constructor (frameCount: number, bezierCount: number, physicsConstraintIndex: number, property: number) {
-			super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintMass);
-		}
+/** Changes a physics constraint's {@link PhysicsConstraint#getMassInverse()}. The timeline values are not inverted. */
+export class PhysicsConstraintMassTimeline extends PhysicsConstraintTimeline {
+	constructor (frameCount: number, bezierCount: number, physicsConstraintIndex: number, property: number) {
+		super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintMass);
+	}
 
-		setup (constraint: PhysicsConstraint): number {
-			return 1 / constraint.data.massInverse;
-		}
+	setup (constraint: PhysicsConstraint): number {
+		return 1 / constraint.data.massInverse;
+	}
 
-		get (constraint: PhysicsConstraint): number {
-			return 1 / constraint.massInverse;
-		}
+	get (constraint: PhysicsConstraint): number {
+		return 1 / constraint.massInverse;
+	}
 
-		set (constraint: PhysicsConstraint, value: number): void {
-			constraint.massInverse = 1 / value;
-		}
+	set (constraint: PhysicsConstraint, value: number): void {
+		constraint.massInverse = 1 / value;
+	}
 
-		global (constraint: PhysicsConstraintData): boolean {
-			return constraint.massGlobal;
-		}
+	global (constraint: PhysicsConstraintData): boolean {
+		return constraint.massGlobal;
 	}
+}
 
-	/** Changes a physics constraint's {@link PhysicsConstraint#getWind()}. */
-	export class PhysicsConstraintWindTimeline extends PhysicsConstraintTimeline {
-		constructor (frameCount: number, bezierCount: number, physicsConstraintIndex: number, property: number) {
-			super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintWind);
-		}
+/** Changes a physics constraint's {@link PhysicsConstraint#getWind()}. */
+export class PhysicsConstraintWindTimeline extends PhysicsConstraintTimeline {
+	constructor (frameCount: number, bezierCount: number, physicsConstraintIndex: number, property: number) {
+		super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintWind);
+	}
 
-		setup (constraint: PhysicsConstraint): number {
-			return constraint.data.wind;
-		}
+	setup (constraint: PhysicsConstraint): number {
+		return constraint.data.wind;
+	}
 
-		get (constraint: PhysicsConstraint): number {
-			return constraint.wind;
-		}
+	get (constraint: PhysicsConstraint): number {
+		return constraint.wind;
+	}
 
-		set (constraint: PhysicsConstraint, value: number): void {
-			constraint.wind = value;
-		}
+	set (constraint: PhysicsConstraint, value: number): void {
+		constraint.wind = value;
+	}
 
-		global (constraint: PhysicsConstraintData): boolean {
-			return constraint.windGlobal;
-		}
+	global (constraint: PhysicsConstraintData): boolean {
+		return constraint.windGlobal;
 	}
+}
 
-	/** Changes a physics constraint's {@link PhysicsConstraint#getGravity()}. */
-	export class PhysicsConstraintGravityTimeline extends PhysicsConstraintTimeline {
-		constructor (frameCount: number, bezierCount: number, physicsConstraintIndex: number, property: number) {
-			super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintGravity);
-		}
+/** Changes a physics constraint's {@link PhysicsConstraint#getGravity()}. */
+export class PhysicsConstraintGravityTimeline extends PhysicsConstraintTimeline {
+	constructor (frameCount: number, bezierCount: number, physicsConstraintIndex: number, property: number) {
+		super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintGravity);
+	}
 
-		setup (constraint: PhysicsConstraint): number {
-			return constraint.data.gravity;
-		}
+	setup (constraint: PhysicsConstraint): number {
+		return constraint.data.gravity;
+	}
 
-		get (constraint: PhysicsConstraint): number {
-			return constraint.gravity;
-		}
+	get (constraint: PhysicsConstraint): number {
+		return constraint.gravity;
+	}
 
-		set (constraint: PhysicsConstraint, value: number): void {
-			constraint.gravity = value;
-		}
+	set (constraint: PhysicsConstraint, value: number): void {
+		constraint.gravity = value;
+	}
 
-		global (constraint: PhysicsConstraintData): boolean {
-			return constraint.gravityGlobal;
-		}
+	global (constraint: PhysicsConstraintData): boolean {
+		return constraint.gravityGlobal;
 	}
+}
 
-	/** Changes a physics constraint's {@link PhysicsConstraint#getMix()}. */
-	export class PhysicsConstraintMixTimeline extends PhysicsConstraintTimeline {
-		constructor (frameCount: number, bezierCount: number, physicsConstraintIndex: number, property: number) {
-			super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintMix);
-		}
+/** Changes a physics constraint's {@link PhysicsConstraint#getMix()}. */
+export class PhysicsConstraintMixTimeline extends PhysicsConstraintTimeline {
+	constructor (frameCount: number, bezierCount: number, physicsConstraintIndex: number, property: number) {
+		super(frameCount, bezierCount, physicsConstraintIndex, Property.physicsConstraintMix);
+	}
 
-		setup (constraint: PhysicsConstraint): number {
-			return constraint.data.mix;
-		}
+	setup (constraint: PhysicsConstraint): number {
+		return constraint.data.mix;
+	}
 
-		get (constraint: PhysicsConstraint): number {
-			return constraint.mix;
-		}
+	get (constraint: PhysicsConstraint): number {
+		return constraint.mix;
+	}
 
-		set (constraint: PhysicsConstraint, value: number): void {
-			constraint.mix = value;
-		}
+	set (constraint: PhysicsConstraint, value: number): void {
+		constraint.mix = value;
+	}
 
-		global (constraint: PhysicsConstraintData): boolean {
-			return constraint.mixGlobal;
-		}
+	global (constraint: PhysicsConstraintData): boolean {
+		return constraint.mixGlobal;
 	}
+}
 
-	/** Resets a physics constraint when specific animation times are reached. */
-	export class PhysicsConstraintResetTimeline extends Timeline {
-		private static propertyIds: string[] = [Property.physicsConstraintReset.toString()];
+/** Resets a physics constraint when specific animation times are reached. */
+export class PhysicsConstraintResetTimeline extends Timeline {
+	private static propertyIds: string[] = [Property.physicsConstraintReset.toString()];
 
-		/** The index of the physics constraint in {@link Skeleton#getPhysicsConstraints()} that will be reset when this timeline is
-		* applied, or -1 if all physics constraints in the skeleton will be reset. */
-		constraintIndex: number;
+	/** The index of the physics constraint in {@link Skeleton#getPhysicsConstraints()} that will be reset when this timeline is
+	* applied, or -1 if all physics constraints in the skeleton will be reset. */
+	constraintIndex: number;
 
-		/** @param physicsConstraintIndex -1 for all physics constraints in the skeleton. */
-		constructor (frameCount: number, physicsConstraintIndex: number) {
-			super(frameCount, PhysicsConstraintResetTimeline.propertyIds);
-			this.constraintIndex = physicsConstraintIndex;
-		}
+	/** @param physicsConstraintIndex -1 for all physics constraints in the skeleton. */
+	constructor (frameCount: number, physicsConstraintIndex: number) {
+		super(frameCount, PhysicsConstraintResetTimeline.propertyIds);
+		this.constraintIndex = physicsConstraintIndex;
+	}
 
-		getFrameCount () {
-			return this.frames.length;
-		}
+	getFrameCount () {
+		return this.frames.length;
+	}
+
+	/** Sets the time for the specified frame.
+	 * @param frame Between 0 and <code>frameCount</code>, inclusive. */
+	setFrame (frame: number, time: number) {
+		this.frames[frame] = time;
+	}
+
+	/** Resets the physics constraint when frames > <code>lastTime</code> and <= <code>time</code>. */
+	apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
 
-		/** Sets the time for the specified frame.
-		 * @param frame Between 0 and <code>frameCount</code>, inclusive. */
-		setFrame (frame: number, time: number) {
-			this.frames[frame] = time;
+		let constraint: PhysicsConstraint | undefined;
+		if (this.constraintIndex != -1) {
+			constraint = skeleton.physicsConstraints[this.constraintIndex];
+			if (!constraint.active) return;
 		}
 
-		/** Resets the physics constraint when frames > <code>lastTime</code> and <= <code>time</code>. */
-		apply (skeleton: Skeleton, lastTime: number, time: number, firedEvents: Array<Event>, alpha: number, blend: MixBlend, direction: MixDirection) {
+		const frames = this.frames;
 
-			let constraint: PhysicsConstraint | undefined;
-			if (this.constraintIndex != -1) {
-				constraint = skeleton.physicsConstraints[this.constraintIndex];
-				if (!constraint.active) return;
-			}
+		if (lastTime > time) { // Apply after lastTime for looped animations.
+			this.apply(skeleton, lastTime, Number.MAX_VALUE, [], alpha, blend, direction);
+			lastTime = -1;
+		} else if (lastTime >= frames[frames.length - 1]) // Last time is after last frame.
+			return;
+		if (time < frames[0]) return;
 
-			const frames = this.frames;
-
-			if (lastTime > time) { // Apply after lastTime for looped animations.
-				this.apply(skeleton, lastTime, Number.MAX_VALUE, [], alpha, blend, direction);
-				lastTime = -1;
-			} else if (lastTime >= frames[frames.length - 1]) // Last time is after last frame.
-				return;
-			if (time < frames[0]) return;
-
-			if (lastTime < frames[0] || time >= frames[Timeline.search1(frames, lastTime) + 1]) {
-				if (constraint != null)
-					constraint.reset();
-				else {
-					for (const constraint of skeleton.physicsConstraints) {
-						if (constraint.active) constraint.reset();
-					}
+		if (lastTime < frames[0] || time >= frames[Timeline.search1(frames, lastTime) + 1]) {
+			if (constraint != null)
+				constraint.reset();
+			else {
+				for (const constraint of skeleton.physicsConstraints) {
+					if (constraint.active) constraint.reset();
 				}
 			}
 		}
 	}
+}
 
 /** Changes a slot's {@link Slot#getSequenceIndex()} for an attachment's {@link Sequence}. */
 export class SequenceTimeline extends Timeline implements SlotTimeline {

+ 88 - 88
spine-ts/spine-core/src/PhysicsConstraint.ts

@@ -76,7 +76,7 @@ export class PhysicsConstraint implements Updatable {
 	remaining = 0;
 	lastTime = 0;
 
-	constructor(data: PhysicsConstraintData, skeleton: Skeleton) {
+	constructor (data: PhysicsConstraintData, skeleton: Skeleton) {
 		this.data = data;
 		this.skeleton = skeleton;
 		this.bone = skeleton.bones[data.bone.index];
@@ -128,102 +128,102 @@ export class PhysicsConstraint implements Updatable {
 		const l = bone.data.length;
 
 		switch (physics) {
-		case Physics.none:
-			return;
-		case Physics.reset:
-			this.reset();
+			case Physics.none:
+				return;
+			case Physics.reset:
+				this.reset();
 			// Fall through.
-		case Physics.update:
-			this.remaining += Math.max(this.skeleton.time - this.lastTime, 0);
-			this.lastTime = this.skeleton.time;
+			case Physics.update:
+				this.remaining += Math.max(this.skeleton.time - this.lastTime, 0);
+				this.lastTime = this.skeleton.time;
 
-			const bx = bone.worldX, by = bone.worldY;
-			if (this._reset) {
-				this._reset = false;
-				this.ux = bx;
-				this.uy = by;
-			} else {
-				let remaining = this.remaining, i = this.inertia, step = this.data.step;
-				if (x || y) {
-					if (x) {
-						this.xOffset += (this.ux - bx) * i;
-						this.ux = bx;
-					}
-					if (y) {
-						this.yOffset += (this.uy - by) * i;
-						this.uy = by;
-					}
-					if (remaining >= step) {
-						const m = this.massInverse * step, e = this.strength, w = this.wind * 100, g = this.gravity * -100;
-						const d = Math.pow(this.damping, 60 * step);
-						do {
-							if (x) {
-								this.xVelocity += (w - this.xOffset * e) * m;
-								this.xOffset += this.xVelocity * step;
-								this.xVelocity *= d;
-							}
-							if (y) {
-								this.yVelocity += (g - this.yOffset * e) * m;
-								this.yOffset += this.yVelocity * step;
-								this.yVelocity *= d;
-							}
-							remaining -= step;
-						} while (remaining >= step);
-					}
-					if (x) bone.worldX += this.xOffset * mix * this.data.x;
-					if (y) bone.worldY += this.yOffset * mix * this.data.y;
-				}
-				if (rotateOrShearX || scaleX) {
-					let ca = Math.atan2(bone.c, bone.a), c = 0, s = 0, mr = 0;
-					if (rotateOrShearX) {
-						mr = mix * this.data.rotate;
-						let dx = this.cx - bone.worldX, dy = this.cy - bone.worldY, r = Math.atan2(dy + this.ty, dx + this.tx) - ca - this.rotateOffset * mr;
-						this.rotateOffset += (r - Math.ceil(r * MathUtils.invPI2 - 0.5) * MathUtils.PI2) * i;
-						r = this.rotateOffset * mr + ca;
-						c = Math.cos(r);
-						s = Math.sin(r);
-						if (scaleX) {
-							r = l * bone.getWorldScaleX();
-							if (r > 0) this.scaleOffset += (dx * c + dy * s) * i / r;
+				const bx = bone.worldX, by = bone.worldY;
+				if (this._reset) {
+					this._reset = false;
+					this.ux = bx;
+					this.uy = by;
+				} else {
+					let remaining = this.remaining, i = this.inertia, step = this.data.step;
+					if (x || y) {
+						if (x) {
+							this.xOffset += (this.ux - bx) * i;
+							this.ux = bx;
+						}
+						if (y) {
+							this.yOffset += (this.uy - by) * i;
+							this.uy = by;
+						}
+						if (remaining >= step) {
+							const m = this.massInverse * step, e = this.strength, w = this.wind * 100, g = this.gravity * -100;
+							const d = Math.pow(this.damping, 60 * step);
+							do {
+								if (x) {
+									this.xVelocity += (w - this.xOffset * e) * m;
+									this.xOffset += this.xVelocity * step;
+									this.xVelocity *= d;
+								}
+								if (y) {
+									this.yVelocity += (g - this.yOffset * e) * m;
+									this.yOffset += this.yVelocity * step;
+									this.yVelocity *= d;
+								}
+								remaining -= step;
+							} while (remaining >= step);
 						}
-					} else {
-						c = Math.cos(ca);
-						s = Math.sin(ca);
-						const r = l * bone.getWorldScaleX();
-						if (r > 0) this.scaleOffset += ((this.cx - bone.worldX) * c + (this.cy - bone.worldY) * s) * i / r;
+						if (x) bone.worldX += this.xOffset * mix * this.data.x;
+						if (y) bone.worldY += this.yOffset * mix * this.data.y;
 					}
-					remaining = this.remaining;
-					if (remaining >= step) {
-						const m = this.massInverse * step, e = this.strength, w = this.wind, g = this.gravity;
-						const d = Math.pow(this.damping, 60 * step);
-						while (true) {
-							remaining -= step;
+					if (rotateOrShearX || scaleX) {
+						let ca = Math.atan2(bone.c, bone.a), c = 0, s = 0, mr = 0;
+						if (rotateOrShearX) {
+							mr = mix * this.data.rotate;
+							let dx = this.cx - bone.worldX, dy = this.cy - bone.worldY, r = Math.atan2(dy + this.ty, dx + this.tx) - ca - this.rotateOffset * mr;
+							this.rotateOffset += (r - Math.ceil(r * MathUtils.invPI2 - 0.5) * MathUtils.PI2) * i;
+							r = this.rotateOffset * mr + ca;
+							c = Math.cos(r);
+							s = Math.sin(r);
 							if (scaleX) {
-								this.scaleVelocity += (w * c - g * s - this.scaleOffset * e) * m;
-								this.scaleOffset += this.scaleVelocity * step;
-								this.scaleVelocity *= d;
+								r = l * bone.getWorldScaleX();
+								if (r > 0) this.scaleOffset += (dx * c + dy * s) * i / r;
+							}
+						} else {
+							c = Math.cos(ca);
+							s = Math.sin(ca);
+							const r = l * bone.getWorldScaleX();
+							if (r > 0) this.scaleOffset += ((this.cx - bone.worldX) * c + (this.cy - bone.worldY) * s) * i / r;
+						}
+						remaining = this.remaining;
+						if (remaining >= step) {
+							const m = this.massInverse * step, e = this.strength, w = this.wind, g = this.gravity;
+							const d = Math.pow(this.damping, 60 * step);
+							while (true) {
+								remaining -= step;
+								if (scaleX) {
+									this.scaleVelocity += (w * c - g * s - this.scaleOffset * e) * m;
+									this.scaleOffset += this.scaleVelocity * step;
+									this.scaleVelocity *= d;
+								}
+								if (rotateOrShearX) {
+									this.rotateVelocity += (-0.01 * l * (w * s + g * c) - this.rotateOffset * e) * m;
+									this.rotateOffset += this.rotateVelocity * step;
+									this.rotateVelocity *= d;
+									if (remaining < step) break;
+									const r = this.rotateOffset * mr + ca;
+									c = Math.cos(r);
+									s = Math.sin(r);
+								} else if (remaining < step) //
+									break;
 							}
-							if (rotateOrShearX) {
-								this.rotateVelocity += (-0.01 * l * (w * s + g * c) - this.rotateOffset * e) * m;
-								this.rotateOffset += this.rotateVelocity * step;
-								this.rotateVelocity *= d;
-								if (remaining < step) break;
-								const r = this.rotateOffset * mr + ca;
-								c = Math.cos(r);
-								s = Math.sin(r);
-							} else if (remaining < step) //
-								break;
 						}
 					}
+					this.remaining = remaining;
 				}
-				this.remaining = remaining;
-			}
-			this.cx = bone.worldX;
-			this.cy = bone.worldY;
-			break;
-		case Physics.pose:
-			if (x) bone.worldX += this.xOffset * mix * this.data.x;
-			if (y) bone.worldY += this.yOffset * mix * this.data.y;
+				this.cx = bone.worldX;
+				this.cy = bone.worldY;
+				break;
+			case Physics.pose:
+				if (x) bone.worldX += this.xOffset * mix * this.data.x;
+				if (y) bone.worldY += this.yOffset * mix * this.data.y;
 		}
 
 		if (rotateOrShearX) {

+ 1 - 1
spine-ts/spine-core/src/PhysicsConstraintData.ts

@@ -34,7 +34,7 @@ import { ConstraintData } from "./ConstraintData.js";
 /** Stores the setup pose for a {@link PhysicsConstraint}.
  * <p>
  * See <a href="http://esotericsoftware.com/spine-physics-constraints">Physics constraints</a> in the Spine User Guide. */
-export class  PhysicsConstraintData extends ConstraintData {
+export class PhysicsConstraintData extends ConstraintData {
 	private _bone: BoneData | null = null;
 	/** The bone constrained by this physics constraint. */
 	public set bone (boneData: BoneData) { this._bone = boneData; }

+ 1 - 1
spine-ts/spine-core/src/Utils.ts

@@ -199,7 +199,7 @@ export class MathUtils {
 		return Math.sin(degrees * MathUtils.degRad);
 	}
 
-	static atan2Deg(y: number, x: number) {
+	static atan2Deg (y: number, x: number) {
 		return Math.atan2(y, x) * MathUtils.degRad;
 	}