@codexo/exojs-physics 0.14.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/PhysicsBody.d.ts +32 -0
- package/dist/esm/PhysicsBody.js +60 -2
- package/dist/esm/PhysicsBody.js.map +1 -1
- package/dist/esm/PhysicsWorld.d.ts +74 -8
- package/dist/esm/PhysicsWorld.js +279 -7
- package/dist/esm/PhysicsWorld.js.map +1 -1
- package/dist/esm/binding/BindingRegistry.d.ts +1 -2
- package/dist/esm/binding/BindingRegistry.js +2 -2
- package/dist/esm/binding/BindingRegistry.js.map +1 -1
- package/dist/esm/binding/PhysicsBinding.d.ts +1 -12
- package/dist/esm/binding/PhysicsBinding.js +1 -3
- package/dist/esm/binding/PhysicsBinding.js.map +1 -1
- package/dist/esm/debug/PhysicsDebugDraw.d.ts +6 -0
- package/dist/esm/debug/PhysicsDebugDraw.js +24 -1
- package/dist/esm/debug/PhysicsDebugDraw.js.map +1 -1
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/joints/DistanceJoint.d.ts +71 -0
- package/dist/esm/joints/DistanceJoint.js +176 -0
- package/dist/esm/joints/DistanceJoint.js.map +1 -0
- package/dist/esm/joints/Joint.d.ts +25 -0
- package/dist/esm/joints/Joint.js +24 -0
- package/dist/esm/joints/Joint.js.map +1 -0
- package/dist/esm/joints/MouseJoint.d.ts +57 -0
- package/dist/esm/joints/MouseJoint.js +137 -0
- package/dist/esm/joints/MouseJoint.js.map +1 -0
- package/dist/esm/joints/PrismaticJoint.d.ts +85 -0
- package/dist/esm/joints/PrismaticJoint.js +241 -0
- package/dist/esm/joints/PrismaticJoint.js.map +1 -0
- package/dist/esm/joints/RevoluteJoint.d.ts +81 -0
- package/dist/esm/joints/RevoluteJoint.js +217 -0
- package/dist/esm/joints/RevoluteJoint.js.map +1 -0
- package/dist/esm/joints/WeldJoint.d.ts +61 -0
- package/dist/esm/joints/WeldJoint.js +159 -0
- package/dist/esm/joints/WeldJoint.js.map +1 -0
- package/dist/esm/joints/WheelJoint.d.ts +92 -0
- package/dist/esm/joints/WheelJoint.js +256 -0
- package/dist/esm/joints/WheelJoint.js.map +1 -0
- package/dist/esm/math.js +15 -1
- package/dist/esm/math.js.map +1 -1
- package/dist/esm/physicsBuildInfo.js +2 -2
- package/dist/esm/public.d.ts +7 -1
- package/dist/esm/solver/ContactSolver.js +7 -0
- package/dist/esm/solver/ContactSolver.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { applyInverseTransform, applyTransform } from '../math.js';
|
|
2
|
+
import { Joint } from './Joint.js';
|
|
3
|
+
|
|
4
|
+
/** Reused output sink — physics steps single-threaded, so a shared scratch is safe. */
|
|
5
|
+
const scratch = { x: 0, y: 0 };
|
|
6
|
+
/** Box2D-v3 soft-constraint factors at sub-step `h`, or rigid Baumgarte when `hertz === 0`. */
|
|
7
|
+
const computeSoftFactors = (hertz, dampingRatio, h, out) => {
|
|
8
|
+
if (hertz > 0) {
|
|
9
|
+
const omega = 2 * Math.PI * hertz;
|
|
10
|
+
const a1 = 2 * dampingRatio + h * omega;
|
|
11
|
+
const a2 = h * omega * a1;
|
|
12
|
+
const a3 = 1 / (1 + a2);
|
|
13
|
+
out.biasRate = omega / a1;
|
|
14
|
+
out.massScale = a2 * a3;
|
|
15
|
+
out.impulseScale = a3;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
out.biasRate = 0.2 / h;
|
|
19
|
+
out.massScale = 1;
|
|
20
|
+
out.impulseScale = 0;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Rigidly fixes the relative position and orientation of two bodies (they move
|
|
25
|
+
* as one rigid body). A 2-DOF point constraint (like {@link RevoluteJoint}) plus
|
|
26
|
+
* a 1-DOF angular constraint, solved in the sub-step loop. Both locks default to
|
|
27
|
+
* rigid; set `linearHertz`/`angularHertz` for a springy weld.
|
|
28
|
+
*/
|
|
29
|
+
class WeldJoint extends Joint {
|
|
30
|
+
/** Locked relative angle `angleB − angleA`. */
|
|
31
|
+
referenceAngle;
|
|
32
|
+
/** Soft frequency for the position lock (`0` = rigid). */
|
|
33
|
+
linearHertz;
|
|
34
|
+
/** Soft frequency for the angle lock (`0` = rigid). */
|
|
35
|
+
angularHertz;
|
|
36
|
+
/** Soft damping ratio. */
|
|
37
|
+
dampingRatio;
|
|
38
|
+
_localAnchorAx;
|
|
39
|
+
_localAnchorAy;
|
|
40
|
+
_localAnchorBx;
|
|
41
|
+
_localAnchorBy;
|
|
42
|
+
_rAx = 0;
|
|
43
|
+
_rAy = 0;
|
|
44
|
+
_rBx = 0;
|
|
45
|
+
_rBy = 0;
|
|
46
|
+
_cx = 0;
|
|
47
|
+
_cy = 0;
|
|
48
|
+
_invK11 = 0;
|
|
49
|
+
_invK12 = 0;
|
|
50
|
+
_invK22 = 0;
|
|
51
|
+
_angleError = 0;
|
|
52
|
+
_effMassAngle = 0;
|
|
53
|
+
_linear = { biasRate: 0, massScale: 1, impulseScale: 0 };
|
|
54
|
+
_angular = { biasRate: 0, massScale: 1, impulseScale: 0 };
|
|
55
|
+
_impulseX = 0;
|
|
56
|
+
_impulseY = 0;
|
|
57
|
+
_impulseAngle = 0;
|
|
58
|
+
constructor(options) {
|
|
59
|
+
super(options.bodyA, options.bodyB);
|
|
60
|
+
const ax = options.anchor?.x ?? (options.bodyA.x + options.bodyB.x) / 2;
|
|
61
|
+
const ay = options.anchor?.y ?? (options.bodyA.y + options.bodyB.y) / 2;
|
|
62
|
+
applyInverseTransform(options.bodyA.transform, ax, ay, scratch);
|
|
63
|
+
this._localAnchorAx = scratch.x;
|
|
64
|
+
this._localAnchorAy = scratch.y;
|
|
65
|
+
applyInverseTransform(options.bodyB.transform, ax, ay, scratch);
|
|
66
|
+
this._localAnchorBx = scratch.x;
|
|
67
|
+
this._localAnchorBy = scratch.y;
|
|
68
|
+
this.referenceAngle = options.referenceAngle ?? options.bodyB.angle - options.bodyA.angle;
|
|
69
|
+
this.linearHertz = options.linearHertz ?? 0;
|
|
70
|
+
this.angularHertz = options.angularHertz ?? 0;
|
|
71
|
+
this.dampingRatio = options.dampingRatio ?? 1;
|
|
72
|
+
}
|
|
73
|
+
_prepare(h) {
|
|
74
|
+
const bodyA = this.bodyA;
|
|
75
|
+
const bodyB = this.bodyB;
|
|
76
|
+
this._active = this.enabled && !bodyA.isSleeping && !bodyB.isSleeping && (bodyA.invMass > 0 || bodyB.invMass > 0);
|
|
77
|
+
if (!this._active) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
applyTransform(bodyA.transform, this._localAnchorAx, this._localAnchorAy, scratch);
|
|
81
|
+
const pAx = scratch.x;
|
|
82
|
+
const pAy = scratch.y;
|
|
83
|
+
applyTransform(bodyB.transform, this._localAnchorBx, this._localAnchorBy, scratch);
|
|
84
|
+
const pBx = scratch.x;
|
|
85
|
+
const pBy = scratch.y;
|
|
86
|
+
this._rAx = pAx - bodyA.worldCenterOfMassX;
|
|
87
|
+
this._rAy = pAy - bodyA.worldCenterOfMassY;
|
|
88
|
+
this._rBx = pBx - bodyB.worldCenterOfMassX;
|
|
89
|
+
this._rBy = pBy - bodyB.worldCenterOfMassY;
|
|
90
|
+
this._cx = pBx - pAx;
|
|
91
|
+
this._cy = pBy - pAy;
|
|
92
|
+
const mA = bodyA.invMass;
|
|
93
|
+
const mB = bodyB.invMass;
|
|
94
|
+
const iA = bodyA.invInertia;
|
|
95
|
+
const iB = bodyB.invInertia;
|
|
96
|
+
const k11 = mA + mB + iA * this._rAy * this._rAy + iB * this._rBy * this._rBy;
|
|
97
|
+
const k12 = -iA * this._rAx * this._rAy - iB * this._rBx * this._rBy;
|
|
98
|
+
const k22 = mA + mB + iA * this._rAx * this._rAx + iB * this._rBx * this._rBx;
|
|
99
|
+
const det = k11 * k22 - k12 * k12;
|
|
100
|
+
const invDet = det !== 0 ? 1 / det : 0;
|
|
101
|
+
this._invK11 = invDet * k22;
|
|
102
|
+
this._invK12 = -invDet * k12;
|
|
103
|
+
this._invK22 = invDet * k11;
|
|
104
|
+
this._angleError = bodyB.angle - bodyA.angle - this.referenceAngle;
|
|
105
|
+
const kAngle = iA + iB;
|
|
106
|
+
this._effMassAngle = kAngle > 0 ? 1 / kAngle : 0;
|
|
107
|
+
computeSoftFactors(this.linearHertz, this.dampingRatio, h, this._linear);
|
|
108
|
+
computeSoftFactors(this.angularHertz, this.dampingRatio, h, this._angular);
|
|
109
|
+
}
|
|
110
|
+
_warmStart() {
|
|
111
|
+
if (!this._active) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const bodyA = this.bodyA;
|
|
115
|
+
const bodyB = this.bodyB;
|
|
116
|
+
bodyA.angularVelocity -= bodyA.invInertia * this._impulseAngle;
|
|
117
|
+
bodyB.angularVelocity += bodyB.invInertia * this._impulseAngle;
|
|
118
|
+
this._applyLinearImpulse(this._impulseX, this._impulseY);
|
|
119
|
+
}
|
|
120
|
+
_solve(useBias) {
|
|
121
|
+
if (!this._active) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const bodyA = this.bodyA;
|
|
125
|
+
const bodyB = this.bodyB;
|
|
126
|
+
// Angular lock first.
|
|
127
|
+
const cdotAngle = bodyB.angularVelocity - bodyA.angularVelocity;
|
|
128
|
+
const biasAngle = useBias ? this._angular.biasRate * this._angleError : 0;
|
|
129
|
+
const impulseAngle = -this._effMassAngle * this._angular.massScale * (cdotAngle + biasAngle) - this._angular.impulseScale * this._impulseAngle;
|
|
130
|
+
this._impulseAngle += impulseAngle;
|
|
131
|
+
bodyA.angularVelocity -= bodyA.invInertia * impulseAngle;
|
|
132
|
+
bodyB.angularVelocity += bodyB.invInertia * impulseAngle;
|
|
133
|
+
// Linear (point) lock.
|
|
134
|
+
const cdotX = bodyB.linearVelocityX - bodyB.angularVelocity * this._rBy - (bodyA.linearVelocityX - bodyA.angularVelocity * this._rAy);
|
|
135
|
+
const cdotY = bodyB.linearVelocityY + bodyB.angularVelocity * this._rBx - (bodyA.linearVelocityY + bodyA.angularVelocity * this._rAx);
|
|
136
|
+
const rhsX = cdotX + (useBias ? this._linear.biasRate * this._cx : 0);
|
|
137
|
+
const rhsY = cdotY + (useBias ? this._linear.biasRate * this._cy : 0);
|
|
138
|
+
const solvedX = this._invK11 * rhsX + this._invK12 * rhsY;
|
|
139
|
+
const solvedY = this._invK12 * rhsX + this._invK22 * rhsY;
|
|
140
|
+
const impulseX = -this._linear.massScale * solvedX - this._linear.impulseScale * this._impulseX;
|
|
141
|
+
const impulseY = -this._linear.massScale * solvedY - this._linear.impulseScale * this._impulseY;
|
|
142
|
+
this._impulseX += impulseX;
|
|
143
|
+
this._impulseY += impulseY;
|
|
144
|
+
this._applyLinearImpulse(impulseX, impulseY);
|
|
145
|
+
}
|
|
146
|
+
_applyLinearImpulse(jx, jy) {
|
|
147
|
+
const bodyA = this.bodyA;
|
|
148
|
+
const bodyB = this.bodyB;
|
|
149
|
+
bodyA.linearVelocityX -= bodyA.invMass * jx;
|
|
150
|
+
bodyA.linearVelocityY -= bodyA.invMass * jy;
|
|
151
|
+
bodyA.angularVelocity -= bodyA.invInertia * (this._rAx * jy - this._rAy * jx);
|
|
152
|
+
bodyB.linearVelocityX += bodyB.invMass * jx;
|
|
153
|
+
bodyB.linearVelocityY += bodyB.invMass * jy;
|
|
154
|
+
bodyB.angularVelocity += bodyB.invInertia * (this._rBx * jy - this._rBy * jx);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export { WeldJoint };
|
|
159
|
+
//# sourceMappingURL=WeldJoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WeldJoint.js","sources":["../../../../src/joints/WeldJoint.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { PhysicsBody } from '../PhysicsBody';
|
|
2
|
+
import type { VectorLike } from '../types';
|
|
3
|
+
import { Joint } from './Joint';
|
|
4
|
+
/** Construction options for a {@link WheelJoint}. */
|
|
5
|
+
export interface WheelJointOptions {
|
|
6
|
+
/** First body (the chassis). */
|
|
7
|
+
bodyA: PhysicsBody;
|
|
8
|
+
/** Second body (the wheel). */
|
|
9
|
+
bodyB: PhysicsBody;
|
|
10
|
+
/** Shared world-space anchor at creation (the wheel hub). */
|
|
11
|
+
anchor: VectorLike;
|
|
12
|
+
/** Suspension axis in world space at creation (normalised internally). */
|
|
13
|
+
axis: VectorLike;
|
|
14
|
+
/** Suspension spring frequency in Hz (`0` makes the axis rigid). Default `0`. */
|
|
15
|
+
hertz?: number;
|
|
16
|
+
/** Suspension spring damping ratio. Default `1`. */
|
|
17
|
+
dampingRatio?: number;
|
|
18
|
+
/** Enable the rotation motor (drives the wheel's spin). Default `false`. */
|
|
19
|
+
enableMotor?: boolean;
|
|
20
|
+
/** Target relative angular velocity (rad/s) for the motor. Default `0`. */
|
|
21
|
+
motorSpeed?: number;
|
|
22
|
+
/** Maximum motor torque. Default `0`. */
|
|
23
|
+
maxMotorTorque?: number;
|
|
24
|
+
/** Enable the suspension-travel limit (keeps the axis translation in `[lowerTranslation, upperTranslation]`). Default `false`. */
|
|
25
|
+
enableLimit?: boolean;
|
|
26
|
+
/** Lower suspension-travel limit along the axis (relative to the creation position). Default `0`. */
|
|
27
|
+
lowerTranslation?: number;
|
|
28
|
+
/** Upper suspension-travel limit along the axis. Default `0`. */
|
|
29
|
+
upperTranslation?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A wheel attached to a chassis: free to **spin** (no rotation lock) and sprung
|
|
33
|
+
* along a **suspension axis** (a soft spring), but locked **laterally** (it
|
|
34
|
+
* cannot slide perpendicular to the axis). Optionally driven by a rotation
|
|
35
|
+
* motor and/or bounded by a suspension-travel limit. Used for vehicles. Solved
|
|
36
|
+
* in the sub-step loop, warm-started.
|
|
37
|
+
*/
|
|
38
|
+
export declare class WheelJoint extends Joint {
|
|
39
|
+
/** Suspension spring frequency in Hz (`0` = rigid axis). */
|
|
40
|
+
hertz: number;
|
|
41
|
+
/** Suspension spring damping ratio. */
|
|
42
|
+
dampingRatio: number;
|
|
43
|
+
/** When `true`, the motor drives the wheel's spin toward {@link motorSpeed}. */
|
|
44
|
+
enableMotor: boolean;
|
|
45
|
+
/** Target relative angular velocity (rad/s) for the motor. */
|
|
46
|
+
motorSpeed: number;
|
|
47
|
+
/** Maximum motor torque. */
|
|
48
|
+
maxMotorTorque: number;
|
|
49
|
+
/** When `true`, the axis translation is constrained to `[lowerTranslation, upperTranslation]`. */
|
|
50
|
+
enableLimit: boolean;
|
|
51
|
+
/** Lower suspension-travel limit along the axis. */
|
|
52
|
+
lowerTranslation: number;
|
|
53
|
+
/** Upper suspension-travel limit along the axis. */
|
|
54
|
+
upperTranslation: number;
|
|
55
|
+
private readonly _localAnchorAx;
|
|
56
|
+
private readonly _localAnchorAy;
|
|
57
|
+
private readonly _localAnchorBx;
|
|
58
|
+
private readonly _localAnchorBy;
|
|
59
|
+
private readonly _localAxisAx;
|
|
60
|
+
private readonly _localAxisAy;
|
|
61
|
+
private _axisX;
|
|
62
|
+
private _axisY;
|
|
63
|
+
private _perpX;
|
|
64
|
+
private _perpY;
|
|
65
|
+
private _a1;
|
|
66
|
+
private _a2;
|
|
67
|
+
private _s1;
|
|
68
|
+
private _s2;
|
|
69
|
+
private _perpMass;
|
|
70
|
+
private _axialMass;
|
|
71
|
+
private _angularMass;
|
|
72
|
+
private _springBiasRate;
|
|
73
|
+
private _springMassScale;
|
|
74
|
+
private _springImpulseScale;
|
|
75
|
+
private _cPerp;
|
|
76
|
+
private _translation;
|
|
77
|
+
private _h;
|
|
78
|
+
private _invH;
|
|
79
|
+
private _perpImpulse;
|
|
80
|
+
private _springImpulse;
|
|
81
|
+
private _motorImpulse;
|
|
82
|
+
private _lowerImpulse;
|
|
83
|
+
private _upperImpulse;
|
|
84
|
+
constructor(options: WheelJointOptions);
|
|
85
|
+
_prepare(h: number): void;
|
|
86
|
+
_warmStart(): void;
|
|
87
|
+
_solve(useBias: boolean): void;
|
|
88
|
+
private _axisVelocity;
|
|
89
|
+
private _perpVelocity;
|
|
90
|
+
private _applyAxial;
|
|
91
|
+
private _applyPerp;
|
|
92
|
+
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { applyInverseTransform, applyInverseRotation, applyRotation, applyTransform } from '../math.js';
|
|
2
|
+
import { Joint } from './Joint.js';
|
|
3
|
+
|
|
4
|
+
/** Reused output sink — physics steps single-threaded, so a shared scratch is safe. */
|
|
5
|
+
const scratch = { x: 0, y: 0 };
|
|
6
|
+
/**
|
|
7
|
+
* A wheel attached to a chassis: free to **spin** (no rotation lock) and sprung
|
|
8
|
+
* along a **suspension axis** (a soft spring), but locked **laterally** (it
|
|
9
|
+
* cannot slide perpendicular to the axis). Optionally driven by a rotation
|
|
10
|
+
* motor and/or bounded by a suspension-travel limit. Used for vehicles. Solved
|
|
11
|
+
* in the sub-step loop, warm-started.
|
|
12
|
+
*/
|
|
13
|
+
class WheelJoint extends Joint {
|
|
14
|
+
/** Suspension spring frequency in Hz (`0` = rigid axis). */
|
|
15
|
+
hertz;
|
|
16
|
+
/** Suspension spring damping ratio. */
|
|
17
|
+
dampingRatio;
|
|
18
|
+
/** When `true`, the motor drives the wheel's spin toward {@link motorSpeed}. */
|
|
19
|
+
enableMotor;
|
|
20
|
+
/** Target relative angular velocity (rad/s) for the motor. */
|
|
21
|
+
motorSpeed;
|
|
22
|
+
/** Maximum motor torque. */
|
|
23
|
+
maxMotorTorque;
|
|
24
|
+
/** When `true`, the axis translation is constrained to `[lowerTranslation, upperTranslation]`. */
|
|
25
|
+
enableLimit;
|
|
26
|
+
/** Lower suspension-travel limit along the axis. */
|
|
27
|
+
lowerTranslation;
|
|
28
|
+
/** Upper suspension-travel limit along the axis. */
|
|
29
|
+
upperTranslation;
|
|
30
|
+
_localAnchorAx;
|
|
31
|
+
_localAnchorAy;
|
|
32
|
+
_localAnchorBx;
|
|
33
|
+
_localAnchorBy;
|
|
34
|
+
_localAxisAx;
|
|
35
|
+
_localAxisAy;
|
|
36
|
+
_axisX = 1;
|
|
37
|
+
_axisY = 0;
|
|
38
|
+
_perpX = 0;
|
|
39
|
+
_perpY = 1;
|
|
40
|
+
_a1 = 0;
|
|
41
|
+
_a2 = 0;
|
|
42
|
+
_s1 = 0;
|
|
43
|
+
_s2 = 0;
|
|
44
|
+
_perpMass = 0;
|
|
45
|
+
_axialMass = 0;
|
|
46
|
+
_angularMass = 0;
|
|
47
|
+
_springBiasRate = 0;
|
|
48
|
+
_springMassScale = 1;
|
|
49
|
+
_springImpulseScale = 0;
|
|
50
|
+
_cPerp = 0;
|
|
51
|
+
_translation = 0;
|
|
52
|
+
_h = 0;
|
|
53
|
+
_invH = 0;
|
|
54
|
+
_perpImpulse = 0;
|
|
55
|
+
_springImpulse = 0;
|
|
56
|
+
_motorImpulse = 0;
|
|
57
|
+
_lowerImpulse = 0;
|
|
58
|
+
_upperImpulse = 0;
|
|
59
|
+
constructor(options) {
|
|
60
|
+
super(options.bodyA, options.bodyB);
|
|
61
|
+
applyInverseTransform(options.bodyA.transform, options.anchor.x, options.anchor.y, scratch);
|
|
62
|
+
this._localAnchorAx = scratch.x;
|
|
63
|
+
this._localAnchorAy = scratch.y;
|
|
64
|
+
applyInverseTransform(options.bodyB.transform, options.anchor.x, options.anchor.y, scratch);
|
|
65
|
+
this._localAnchorBx = scratch.x;
|
|
66
|
+
this._localAnchorBy = scratch.y;
|
|
67
|
+
const axisLength = Math.hypot(options.axis.x, options.axis.y) || 1;
|
|
68
|
+
applyInverseRotation(options.bodyA.transform, options.axis.x / axisLength, options.axis.y / axisLength, scratch);
|
|
69
|
+
this._localAxisAx = scratch.x;
|
|
70
|
+
this._localAxisAy = scratch.y;
|
|
71
|
+
this.hertz = options.hertz ?? 0;
|
|
72
|
+
this.dampingRatio = options.dampingRatio ?? 1;
|
|
73
|
+
this.enableMotor = options.enableMotor ?? false;
|
|
74
|
+
this.motorSpeed = options.motorSpeed ?? 0;
|
|
75
|
+
this.maxMotorTorque = options.maxMotorTorque ?? 0;
|
|
76
|
+
this.enableLimit = options.enableLimit ?? false;
|
|
77
|
+
this.lowerTranslation = options.lowerTranslation ?? 0;
|
|
78
|
+
this.upperTranslation = options.upperTranslation ?? 0;
|
|
79
|
+
}
|
|
80
|
+
_prepare(h) {
|
|
81
|
+
const bodyA = this.bodyA;
|
|
82
|
+
const bodyB = this.bodyB;
|
|
83
|
+
this._active = this.enabled && !bodyA.isSleeping && !bodyB.isSleeping && (bodyA.invMass > 0 || bodyB.invMass > 0);
|
|
84
|
+
if (!this._active) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
applyRotation(bodyA.transform, this._localAxisAx, this._localAxisAy, scratch);
|
|
88
|
+
const axisX = scratch.x;
|
|
89
|
+
const axisY = scratch.y;
|
|
90
|
+
const perpX = -axisY;
|
|
91
|
+
const perpY = axisX;
|
|
92
|
+
this._axisX = axisX;
|
|
93
|
+
this._axisY = axisY;
|
|
94
|
+
this._perpX = perpX;
|
|
95
|
+
this._perpY = perpY;
|
|
96
|
+
applyTransform(bodyA.transform, this._localAnchorAx, this._localAnchorAy, scratch);
|
|
97
|
+
const pAx = scratch.x;
|
|
98
|
+
const pAy = scratch.y;
|
|
99
|
+
applyTransform(bodyB.transform, this._localAnchorBx, this._localAnchorBy, scratch);
|
|
100
|
+
const pBx = scratch.x;
|
|
101
|
+
const pBy = scratch.y;
|
|
102
|
+
const rAx = pAx - bodyA.worldCenterOfMassX;
|
|
103
|
+
const rAy = pAy - bodyA.worldCenterOfMassY;
|
|
104
|
+
const rBx = pBx - bodyB.worldCenterOfMassX;
|
|
105
|
+
const rBy = pBy - bodyB.worldCenterOfMassY;
|
|
106
|
+
const dx = pBx - pAx;
|
|
107
|
+
const dy = pBy - pAy;
|
|
108
|
+
this._a1 = (dx + rAx) * axisY - (dy + rAy) * axisX;
|
|
109
|
+
this._a2 = rBx * axisY - rBy * axisX;
|
|
110
|
+
this._s1 = (dx + rAx) * perpY - (dy + rAy) * perpX;
|
|
111
|
+
this._s2 = rBx * perpY - rBy * perpX;
|
|
112
|
+
const mA = bodyA.invMass;
|
|
113
|
+
const mB = bodyB.invMass;
|
|
114
|
+
const iA = bodyA.invInertia;
|
|
115
|
+
const iB = bodyB.invInertia;
|
|
116
|
+
const kPerp = mA + mB + iA * this._s1 * this._s1 + iB * this._s2 * this._s2;
|
|
117
|
+
this._perpMass = kPerp > 0 ? 1 / kPerp : 0;
|
|
118
|
+
const kAxial = mA + mB + iA * this._a1 * this._a1 + iB * this._a2 * this._a2;
|
|
119
|
+
this._axialMass = kAxial > 0 ? 1 / kAxial : 0;
|
|
120
|
+
this._angularMass = iA + iB > 0 ? 1 / (iA + iB) : 0;
|
|
121
|
+
this._cPerp = dx * perpX + dy * perpY;
|
|
122
|
+
this._translation = dx * axisX + dy * axisY;
|
|
123
|
+
this._h = h;
|
|
124
|
+
this._invH = 1 / h;
|
|
125
|
+
if (this.hertz > 0) {
|
|
126
|
+
const omega = 2 * Math.PI * this.hertz;
|
|
127
|
+
const a1 = 2 * this.dampingRatio + h * omega;
|
|
128
|
+
const a2 = h * omega * a1;
|
|
129
|
+
const a3 = 1 / (1 + a2);
|
|
130
|
+
this._springBiasRate = omega / a1;
|
|
131
|
+
this._springMassScale = a2 * a3;
|
|
132
|
+
this._springImpulseScale = a3;
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
this._springBiasRate = 0.2 / h;
|
|
136
|
+
this._springMassScale = 1;
|
|
137
|
+
this._springImpulseScale = 0;
|
|
138
|
+
}
|
|
139
|
+
if (!this.enableMotor) {
|
|
140
|
+
this._motorImpulse = 0;
|
|
141
|
+
}
|
|
142
|
+
if (!this.enableLimit) {
|
|
143
|
+
this._lowerImpulse = 0;
|
|
144
|
+
this._upperImpulse = 0;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
_warmStart() {
|
|
148
|
+
if (!this._active) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const bodyA = this.bodyA;
|
|
152
|
+
const bodyB = this.bodyB;
|
|
153
|
+
// Rotation motor (angular).
|
|
154
|
+
bodyA.angularVelocity -= bodyA.invInertia * this._motorImpulse;
|
|
155
|
+
bodyB.angularVelocity += bodyB.invInertia * this._motorImpulse;
|
|
156
|
+
this._applyAxial(this._springImpulse + this._lowerImpulse - this._upperImpulse);
|
|
157
|
+
this._applyPerp(this._perpImpulse);
|
|
158
|
+
}
|
|
159
|
+
_solve(useBias) {
|
|
160
|
+
if (!this._active) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const bodyA = this.bodyA;
|
|
164
|
+
const bodyB = this.bodyB;
|
|
165
|
+
// Rotation motor — drives the wheel's spin; rotation is otherwise free.
|
|
166
|
+
if (this.enableMotor) {
|
|
167
|
+
const cdot = bodyB.angularVelocity - bodyA.angularVelocity - this.motorSpeed;
|
|
168
|
+
const max = this.maxMotorTorque * this._h;
|
|
169
|
+
const old = this._motorImpulse;
|
|
170
|
+
this._motorImpulse = Math.min(max, Math.max(-max, old - this._angularMass * cdot));
|
|
171
|
+
const applied = this._motorImpulse - old;
|
|
172
|
+
bodyA.angularVelocity -= bodyA.invInertia * applied;
|
|
173
|
+
bodyB.angularVelocity += bodyB.invInertia * applied;
|
|
174
|
+
}
|
|
175
|
+
// Suspension spring along the axis (soft).
|
|
176
|
+
const cdotAxis = this._axisVelocity();
|
|
177
|
+
const springImpulse = -this._axialMass * this._springMassScale * (cdotAxis + this._springBiasRate * this._translation) - this._springImpulseScale * this._springImpulse;
|
|
178
|
+
this._springImpulse += springImpulse;
|
|
179
|
+
this._applyAxial(springImpulse);
|
|
180
|
+
// Suspension-travel limits along the axis.
|
|
181
|
+
if (this.enableLimit) {
|
|
182
|
+
// Lower limit (translation ≥ lowerTranslation): positive impulse pushes along +axis.
|
|
183
|
+
const cLower = this._translation - this.lowerTranslation;
|
|
184
|
+
let biasLower = 0;
|
|
185
|
+
if (cLower > 0) {
|
|
186
|
+
biasLower = cLower * this._invH;
|
|
187
|
+
}
|
|
188
|
+
else if (useBias) {
|
|
189
|
+
biasLower = 0.2 * this._invH * cLower;
|
|
190
|
+
}
|
|
191
|
+
const oldLower = this._lowerImpulse;
|
|
192
|
+
this._lowerImpulse = Math.max(0, oldLower - this._axialMass * (this._axisVelocity() + biasLower));
|
|
193
|
+
this._applyAxial(this._lowerImpulse - oldLower);
|
|
194
|
+
// Upper limit (translation ≤ upperTranslation): impulse pushes along −axis.
|
|
195
|
+
const cUpper = this.upperTranslation - this._translation;
|
|
196
|
+
let biasUpper = 0;
|
|
197
|
+
if (cUpper > 0) {
|
|
198
|
+
biasUpper = cUpper * this._invH;
|
|
199
|
+
}
|
|
200
|
+
else if (useBias) {
|
|
201
|
+
biasUpper = 0.2 * this._invH * cUpper;
|
|
202
|
+
}
|
|
203
|
+
const oldUpper = this._upperImpulse;
|
|
204
|
+
this._upperImpulse = Math.max(0, oldUpper - this._axialMass * (-this._axisVelocity() + biasUpper));
|
|
205
|
+
this._applyAxial(-(this._upperImpulse - oldUpper));
|
|
206
|
+
}
|
|
207
|
+
// Lateral lock (perpendicular, rigid).
|
|
208
|
+
const cdotPerp = this._perpVelocity();
|
|
209
|
+
const perpImpulse = -this._perpMass * (cdotPerp + (useBias ? 0.2 * this._invH * this._cPerp : 0));
|
|
210
|
+
this._perpImpulse += perpImpulse;
|
|
211
|
+
this._applyPerp(perpImpulse);
|
|
212
|
+
}
|
|
213
|
+
_axisVelocity() {
|
|
214
|
+
const bodyA = this.bodyA;
|
|
215
|
+
const bodyB = this.bodyB;
|
|
216
|
+
return (this._axisX * (bodyB.linearVelocityX - bodyA.linearVelocityX) +
|
|
217
|
+
this._axisY * (bodyB.linearVelocityY - bodyA.linearVelocityY) +
|
|
218
|
+
this._a2 * bodyB.angularVelocity -
|
|
219
|
+
this._a1 * bodyA.angularVelocity);
|
|
220
|
+
}
|
|
221
|
+
_perpVelocity() {
|
|
222
|
+
const bodyA = this.bodyA;
|
|
223
|
+
const bodyB = this.bodyB;
|
|
224
|
+
return (this._perpX * (bodyB.linearVelocityX - bodyA.linearVelocityX) +
|
|
225
|
+
this._perpY * (bodyB.linearVelocityY - bodyA.linearVelocityY) +
|
|
226
|
+
this._s2 * bodyB.angularVelocity -
|
|
227
|
+
this._s1 * bodyA.angularVelocity);
|
|
228
|
+
}
|
|
229
|
+
_applyAxial(impulse) {
|
|
230
|
+
const bodyA = this.bodyA;
|
|
231
|
+
const bodyB = this.bodyB;
|
|
232
|
+
const px = impulse * this._axisX;
|
|
233
|
+
const py = impulse * this._axisY;
|
|
234
|
+
bodyA.linearVelocityX -= bodyA.invMass * px;
|
|
235
|
+
bodyA.linearVelocityY -= bodyA.invMass * py;
|
|
236
|
+
bodyA.angularVelocity -= bodyA.invInertia * impulse * this._a1;
|
|
237
|
+
bodyB.linearVelocityX += bodyB.invMass * px;
|
|
238
|
+
bodyB.linearVelocityY += bodyB.invMass * py;
|
|
239
|
+
bodyB.angularVelocity += bodyB.invInertia * impulse * this._a2;
|
|
240
|
+
}
|
|
241
|
+
_applyPerp(impulse) {
|
|
242
|
+
const bodyA = this.bodyA;
|
|
243
|
+
const bodyB = this.bodyB;
|
|
244
|
+
const px = impulse * this._perpX;
|
|
245
|
+
const py = impulse * this._perpY;
|
|
246
|
+
bodyA.linearVelocityX -= bodyA.invMass * px;
|
|
247
|
+
bodyA.linearVelocityY -= bodyA.invMass * py;
|
|
248
|
+
bodyA.angularVelocity -= bodyA.invInertia * impulse * this._s1;
|
|
249
|
+
bodyB.linearVelocityX += bodyB.invMass * px;
|
|
250
|
+
bodyB.linearVelocityY += bodyB.invMass * py;
|
|
251
|
+
bodyB.angularVelocity += bodyB.invInertia * impulse * this._s2;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export { WheelJoint };
|
|
256
|
+
//# sourceMappingURL=WheelJoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WheelJoint.js","sources":["../../../../src/joints/WheelJoint.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
package/dist/esm/math.js
CHANGED
|
@@ -33,6 +33,20 @@ const applyRotation = (transform, x, y, out) => {
|
|
|
33
33
|
out.y = transform.sin * x + transform.cos * y;
|
|
34
34
|
return out;
|
|
35
35
|
};
|
|
36
|
+
/** Map a world point into `transform`'s local frame, writing into `out`. */
|
|
37
|
+
const applyInverseTransform = (transform, x, y, out) => {
|
|
38
|
+
const dx = x - transform.x;
|
|
39
|
+
const dy = y - transform.y;
|
|
40
|
+
out.x = transform.cos * dx + transform.sin * dy;
|
|
41
|
+
out.y = -transform.sin * dx + transform.cos * dy;
|
|
42
|
+
return out;
|
|
43
|
+
};
|
|
44
|
+
/** Map a world direction into `transform`'s local frame, writing into `out`. */
|
|
45
|
+
const applyInverseRotation = (transform, x, y, out) => {
|
|
46
|
+
out.x = transform.cos * x + transform.sin * y;
|
|
47
|
+
out.y = -transform.sin * x + transform.cos * y;
|
|
48
|
+
return out;
|
|
49
|
+
};
|
|
36
50
|
/**
|
|
37
51
|
* Compose `world = body ∘ local` into `out`. The local transform is expressed
|
|
38
52
|
* in the body frame (a collider's offset + local rotation); the result is the
|
|
@@ -44,5 +58,5 @@ const composeTransforms = (body, local, out) => {
|
|
|
44
58
|
return setTransform(out, x, y, body.angle + local.angle);
|
|
45
59
|
};
|
|
46
60
|
|
|
47
|
-
export { applyRotation, applyTransform, composeTransforms, createTransform, setTransform };
|
|
61
|
+
export { applyInverseRotation, applyInverseTransform, applyRotation, applyTransform, composeTransforms, createTransform, setTransform };
|
|
48
62
|
//# sourceMappingURL=math.js.map
|
package/dist/esm/math.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"math.js","sources":["../../../src/math.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AAkBA;AACO,MAAM,eAAe,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,MAAiB;IACtE,CAAC;IACD,CAAC;IACD,KAAK;AACL,IAAA,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;AACpB,IAAA,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;AACrB,CAAA;AAED;AACO,MAAM,YAAY,GAAG,CAAC,SAAoB,EAAE,CAAS,EAAE,CAAS,EAAE,KAAa,KAAe;AACnG,IAAA,SAAS,CAAC,CAAC,GAAG,CAAC;AACf,IAAA,SAAS,CAAC,CAAC,GAAG,CAAC;AAEf,IAAA,IAAI,SAAS,CAAC,KAAK,KAAK,KAAK,EAAE;AAC7B,QAAA,SAAS,CAAC,KAAK,GAAG,KAAK;QACvB,SAAS,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;QAC/B,SAAS,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;IACjC;AAEA,IAAA,OAAO,SAAS;AAClB;AAEA;AACO,MAAM,cAAc,GAAG,CAAC,SAAoB,EAAE,CAAS,EAAE,CAAS,EAAE,GAAc,KAAe;AACtG,IAAA,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;AAC3D,IAAA,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;AAE3D,IAAA,OAAO,GAAG;AACZ;AAEA;AACO,MAAM,aAAa,GAAG,CAAC,SAAoB,EAAE,CAAS,EAAE,CAAS,EAAE,GAAc,KAAe;AACrG,IAAA,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC;AAC7C,IAAA,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC;AAE7C,IAAA,OAAO,GAAG;AACZ;
|
|
1
|
+
{"version":3,"file":"math.js","sources":["../../../src/math.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
package/dist/esm/public.d.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
export type { Aabb } from './Aabb';
|
|
2
|
-
export type { BindingOptions } from './binding/PhysicsBinding';
|
|
3
2
|
export { PhysicsBinding } from './binding/PhysicsBinding';
|
|
4
3
|
export type { ColliderOptions } from './Collider';
|
|
5
4
|
export { Collider } from './Collider';
|
|
6
5
|
export type { CollisionEvent, ContactPoint, SensorEvent } from './events';
|
|
6
|
+
export { DistanceJoint, type DistanceJointOptions } from './joints/DistanceJoint';
|
|
7
|
+
export { Joint } from './joints/Joint';
|
|
8
|
+
export { MouseJoint, type MouseJointOptions } from './joints/MouseJoint';
|
|
9
|
+
export { PrismaticJoint, type PrismaticJointOptions } from './joints/PrismaticJoint';
|
|
10
|
+
export { RevoluteJoint, type RevoluteJointOptions } from './joints/RevoluteJoint';
|
|
11
|
+
export { WeldJoint, type WeldJointOptions } from './joints/WeldJoint';
|
|
12
|
+
export { WheelJoint, type WheelJointOptions } from './joints/WheelJoint';
|
|
7
13
|
export type { BodyOptions } from './PhysicsBody';
|
|
8
14
|
export { PhysicsBody } from './PhysicsBody';
|
|
9
15
|
export { type PhysicsBuildInfo, physicsBuildInfo } from './physicsBuildInfo';
|
|
@@ -119,6 +119,13 @@ class ContactSolver {
|
|
|
119
119
|
}
|
|
120
120
|
const bodyA = contact.a.body;
|
|
121
121
|
const bodyB = contact.b.body;
|
|
122
|
+
// Skip contacts where either body is asleep: a sleeping island's solid
|
|
123
|
+
// contacts are all sleeping↔sleeping or sleeping↔static (both at rest), so
|
|
124
|
+
// there is nothing to solve. A sleeping body touched by an awake one is
|
|
125
|
+
// woken (island merge) before this runs, so it is never skipped wrongly.
|
|
126
|
+
if (bodyA.isSleeping || bodyB.isSleeping) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
122
129
|
const constraint = this._acquire();
|
|
123
130
|
const nx = manifold.normalX;
|
|
124
131
|
const ny = manifold.normalY;
|