@codexo/exojs-physics 0.14.0 → 0.15.0
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,241 @@
|
|
|
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
|
+
* Constrains a body to **slide along a single axis** relative to another: the
|
|
8
|
+
* perpendicular translation and the relative rotation are locked (a 2×2 block);
|
|
9
|
+
* only translation along the axis is free, optionally driven by a motor and/or
|
|
10
|
+
* bounded by a translation limit. Solved in the sub-step loop, warm-started.
|
|
11
|
+
*/
|
|
12
|
+
class PrismaticJoint extends Joint {
|
|
13
|
+
/** When `true`, the motor drives the axis translation toward {@link motorSpeed}. */
|
|
14
|
+
enableMotor;
|
|
15
|
+
/** Target translation speed along the axis (px/s). */
|
|
16
|
+
motorSpeed;
|
|
17
|
+
/** Maximum motor force. */
|
|
18
|
+
maxMotorForce;
|
|
19
|
+
/** When `true`, the axis translation is constrained to `[lowerTranslation, upperTranslation]`. */
|
|
20
|
+
enableLimit;
|
|
21
|
+
/** Lower translation limit along the axis. */
|
|
22
|
+
lowerTranslation;
|
|
23
|
+
/** Upper translation limit along the axis. */
|
|
24
|
+
upperTranslation;
|
|
25
|
+
_localAnchorAx;
|
|
26
|
+
_localAnchorAy;
|
|
27
|
+
_localAnchorBx;
|
|
28
|
+
_localAnchorBy;
|
|
29
|
+
_localAxisAx;
|
|
30
|
+
_localAxisAy;
|
|
31
|
+
_referenceAngle;
|
|
32
|
+
_axisX = 1;
|
|
33
|
+
_axisY = 0;
|
|
34
|
+
_perpX = 0;
|
|
35
|
+
_perpY = 1;
|
|
36
|
+
_a1 = 0;
|
|
37
|
+
_a2 = 0;
|
|
38
|
+
_s1 = 0;
|
|
39
|
+
_s2 = 0;
|
|
40
|
+
_k11 = 0;
|
|
41
|
+
_k12 = 0;
|
|
42
|
+
_k22 = 0;
|
|
43
|
+
_cPerp = 0;
|
|
44
|
+
_cAngle = 0;
|
|
45
|
+
_translation = 0;
|
|
46
|
+
_axialMass = 0;
|
|
47
|
+
_h = 0;
|
|
48
|
+
_invH = 0;
|
|
49
|
+
_perpImpulse = 0;
|
|
50
|
+
_angularImpulse = 0;
|
|
51
|
+
_motorImpulse = 0;
|
|
52
|
+
_lowerImpulse = 0;
|
|
53
|
+
_upperImpulse = 0;
|
|
54
|
+
constructor(options) {
|
|
55
|
+
super(options.bodyA, options.bodyB);
|
|
56
|
+
applyInverseTransform(options.bodyA.transform, options.anchor.x, options.anchor.y, scratch);
|
|
57
|
+
this._localAnchorAx = scratch.x;
|
|
58
|
+
this._localAnchorAy = scratch.y;
|
|
59
|
+
applyInverseTransform(options.bodyB.transform, options.anchor.x, options.anchor.y, scratch);
|
|
60
|
+
this._localAnchorBx = scratch.x;
|
|
61
|
+
this._localAnchorBy = scratch.y;
|
|
62
|
+
const axisLength = Math.hypot(options.axis.x, options.axis.y) || 1;
|
|
63
|
+
applyInverseRotation(options.bodyA.transform, options.axis.x / axisLength, options.axis.y / axisLength, scratch);
|
|
64
|
+
this._localAxisAx = scratch.x;
|
|
65
|
+
this._localAxisAy = scratch.y;
|
|
66
|
+
this._referenceAngle = options.bodyB.angle - options.bodyA.angle;
|
|
67
|
+
this.enableMotor = options.enableMotor ?? false;
|
|
68
|
+
this.motorSpeed = options.motorSpeed ?? 0;
|
|
69
|
+
this.maxMotorForce = options.maxMotorForce ?? 0;
|
|
70
|
+
this.enableLimit = options.enableLimit ?? false;
|
|
71
|
+
this.lowerTranslation = options.lowerTranslation ?? 0;
|
|
72
|
+
this.upperTranslation = options.upperTranslation ?? 0;
|
|
73
|
+
}
|
|
74
|
+
_prepare(h) {
|
|
75
|
+
const bodyA = this.bodyA;
|
|
76
|
+
const bodyB = this.bodyB;
|
|
77
|
+
this._active = this.enabled && !bodyA.isSleeping && !bodyB.isSleeping && (bodyA.invMass > 0 || bodyB.invMass > 0);
|
|
78
|
+
if (!this._active) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// World axis + perpendicular (axis is local to body A).
|
|
82
|
+
applyRotation(bodyA.transform, this._localAxisAx, this._localAxisAy, scratch);
|
|
83
|
+
const axisX = scratch.x;
|
|
84
|
+
const axisY = scratch.y;
|
|
85
|
+
const perpX = -axisY;
|
|
86
|
+
const perpY = axisX;
|
|
87
|
+
this._axisX = axisX;
|
|
88
|
+
this._axisY = axisY;
|
|
89
|
+
this._perpX = perpX;
|
|
90
|
+
this._perpY = perpY;
|
|
91
|
+
applyTransform(bodyA.transform, this._localAnchorAx, this._localAnchorAy, scratch);
|
|
92
|
+
const pAx = scratch.x;
|
|
93
|
+
const pAy = scratch.y;
|
|
94
|
+
applyTransform(bodyB.transform, this._localAnchorBx, this._localAnchorBy, scratch);
|
|
95
|
+
const pBx = scratch.x;
|
|
96
|
+
const pBy = scratch.y;
|
|
97
|
+
const rAx = pAx - bodyA.worldCenterOfMassX;
|
|
98
|
+
const rAy = pAy - bodyA.worldCenterOfMassY;
|
|
99
|
+
const rBx = pBx - bodyB.worldCenterOfMassX;
|
|
100
|
+
const rBy = pBy - bodyB.worldCenterOfMassY;
|
|
101
|
+
const dx = pBx - pAx;
|
|
102
|
+
const dy = pBy - pAy;
|
|
103
|
+
// Jacobian cross terms for the axis (motor/limit) and the perpendicular (lock).
|
|
104
|
+
this._a1 = (dx + rAx) * axisY - (dy + rAy) * axisX;
|
|
105
|
+
this._a2 = rBx * axisY - rBy * axisX;
|
|
106
|
+
this._s1 = (dx + rAx) * perpY - (dy + rAy) * perpX;
|
|
107
|
+
this._s2 = rBx * perpY - rBy * perpX;
|
|
108
|
+
const mA = bodyA.invMass;
|
|
109
|
+
const mB = bodyB.invMass;
|
|
110
|
+
const iA = bodyA.invInertia;
|
|
111
|
+
const iB = bodyB.invInertia;
|
|
112
|
+
const kAxial = mA + mB + iA * this._a1 * this._a1 + iB * this._a2 * this._a2;
|
|
113
|
+
this._axialMass = kAxial > 0 ? 1 / kAxial : 0;
|
|
114
|
+
// Perpendicular + angular 2×2 block.
|
|
115
|
+
this._k11 = mA + mB + iA * this._s1 * this._s1 + iB * this._s2 * this._s2;
|
|
116
|
+
this._k12 = iA * this._s1 + iB * this._s2;
|
|
117
|
+
this._k22 = iA + iB;
|
|
118
|
+
if (this._k22 === 0) {
|
|
119
|
+
this._k22 = 1; // both bodies rotation-locked — keep the block invertible
|
|
120
|
+
}
|
|
121
|
+
this._cPerp = dx * perpX + dy * perpY;
|
|
122
|
+
this._cAngle = bodyB.angle - bodyA.angle - this._referenceAngle;
|
|
123
|
+
this._translation = dx * axisX + dy * axisY;
|
|
124
|
+
this._h = h;
|
|
125
|
+
this._invH = 1 / h;
|
|
126
|
+
if (!this.enableMotor) {
|
|
127
|
+
this._motorImpulse = 0;
|
|
128
|
+
}
|
|
129
|
+
if (!this.enableLimit) {
|
|
130
|
+
this._lowerImpulse = 0;
|
|
131
|
+
this._upperImpulse = 0;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
_warmStart() {
|
|
135
|
+
if (!this._active) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const axial = this._motorImpulse + this._lowerImpulse - this._upperImpulse;
|
|
139
|
+
this._applyBlock(this._perpImpulse, this._angularImpulse);
|
|
140
|
+
this._applyAxial(axial);
|
|
141
|
+
}
|
|
142
|
+
_solve(useBias) {
|
|
143
|
+
if (!this._active) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const bodyA = this.bodyA;
|
|
147
|
+
const bodyB = this.bodyB;
|
|
148
|
+
// Motor along the axis.
|
|
149
|
+
if (this.enableMotor) {
|
|
150
|
+
const cdot = this._axisVelocity() - this.motorSpeed;
|
|
151
|
+
const max = this.maxMotorForce * this._h;
|
|
152
|
+
const old = this._motorImpulse;
|
|
153
|
+
this._motorImpulse = Math.min(max, Math.max(-max, old - this._axialMass * cdot));
|
|
154
|
+
this._applyAxial(this._motorImpulse - old);
|
|
155
|
+
}
|
|
156
|
+
// Translation limits along the axis.
|
|
157
|
+
if (this.enableLimit) {
|
|
158
|
+
// Lower limit (translation ≥ lowerTranslation): positive impulse pushes along +axis.
|
|
159
|
+
const cLower = this._translation - this.lowerTranslation;
|
|
160
|
+
let biasLower = 0;
|
|
161
|
+
if (cLower > 0) {
|
|
162
|
+
biasLower = cLower * this._invH;
|
|
163
|
+
}
|
|
164
|
+
else if (useBias) {
|
|
165
|
+
biasLower = 0.2 * this._invH * cLower;
|
|
166
|
+
}
|
|
167
|
+
const oldLower = this._lowerImpulse;
|
|
168
|
+
this._lowerImpulse = Math.max(0, oldLower - this._axialMass * (this._axisVelocity() + biasLower));
|
|
169
|
+
this._applyAxial(this._lowerImpulse - oldLower);
|
|
170
|
+
// Upper limit (translation ≤ upperTranslation): impulse pushes along −axis.
|
|
171
|
+
const cUpper = this.upperTranslation - this._translation;
|
|
172
|
+
let biasUpper = 0;
|
|
173
|
+
if (cUpper > 0) {
|
|
174
|
+
biasUpper = cUpper * this._invH;
|
|
175
|
+
}
|
|
176
|
+
else if (useBias) {
|
|
177
|
+
biasUpper = 0.2 * this._invH * cUpper;
|
|
178
|
+
}
|
|
179
|
+
const oldUpper = this._upperImpulse;
|
|
180
|
+
this._upperImpulse = Math.max(0, oldUpper - this._axialMass * (-this._axisVelocity() + biasUpper));
|
|
181
|
+
this._applyAxial(-(this._upperImpulse - oldUpper));
|
|
182
|
+
}
|
|
183
|
+
// Perpendicular + angular lock (2×2 block).
|
|
184
|
+
const cdotPerp = this._perpVelocity();
|
|
185
|
+
const cdotAngle = bodyB.angularVelocity - bodyA.angularVelocity;
|
|
186
|
+
const rhs1 = -(cdotPerp + (useBias ? 0.2 * this._invH * this._cPerp : 0));
|
|
187
|
+
const rhs2 = -(cdotAngle + (useBias ? 0.2 * this._invH * this._cAngle : 0));
|
|
188
|
+
const det = this._k11 * this._k22 - this._k12 * this._k12;
|
|
189
|
+
const invDet = det !== 0 ? 1 / det : 0;
|
|
190
|
+
const dPerp = invDet * (this._k22 * rhs1 - this._k12 * rhs2);
|
|
191
|
+
const dAngle = invDet * (-this._k12 * rhs1 + this._k11 * rhs2);
|
|
192
|
+
this._perpImpulse += dPerp;
|
|
193
|
+
this._angularImpulse += dAngle;
|
|
194
|
+
this._applyBlock(dPerp, dAngle);
|
|
195
|
+
}
|
|
196
|
+
/** Relative velocity projected onto the axis (plus the rotation cross terms). */
|
|
197
|
+
_axisVelocity() {
|
|
198
|
+
const bodyA = this.bodyA;
|
|
199
|
+
const bodyB = this.bodyB;
|
|
200
|
+
return (this._axisX * (bodyB.linearVelocityX - bodyA.linearVelocityX) +
|
|
201
|
+
this._axisY * (bodyB.linearVelocityY - bodyA.linearVelocityY) +
|
|
202
|
+
this._a2 * bodyB.angularVelocity -
|
|
203
|
+
this._a1 * bodyA.angularVelocity);
|
|
204
|
+
}
|
|
205
|
+
/** Relative velocity projected onto the perpendicular (plus the rotation cross terms). */
|
|
206
|
+
_perpVelocity() {
|
|
207
|
+
const bodyA = this.bodyA;
|
|
208
|
+
const bodyB = this.bodyB;
|
|
209
|
+
return (this._perpX * (bodyB.linearVelocityX - bodyA.linearVelocityX) +
|
|
210
|
+
this._perpY * (bodyB.linearVelocityY - bodyA.linearVelocityY) +
|
|
211
|
+
this._s2 * bodyB.angularVelocity -
|
|
212
|
+
this._s1 * bodyA.angularVelocity);
|
|
213
|
+
}
|
|
214
|
+
_applyAxial(impulse) {
|
|
215
|
+
const bodyA = this.bodyA;
|
|
216
|
+
const bodyB = this.bodyB;
|
|
217
|
+
const px = impulse * this._axisX;
|
|
218
|
+
const py = impulse * this._axisY;
|
|
219
|
+
bodyA.linearVelocityX -= bodyA.invMass * px;
|
|
220
|
+
bodyA.linearVelocityY -= bodyA.invMass * py;
|
|
221
|
+
bodyA.angularVelocity -= bodyA.invInertia * impulse * this._a1;
|
|
222
|
+
bodyB.linearVelocityX += bodyB.invMass * px;
|
|
223
|
+
bodyB.linearVelocityY += bodyB.invMass * py;
|
|
224
|
+
bodyB.angularVelocity += bodyB.invInertia * impulse * this._a2;
|
|
225
|
+
}
|
|
226
|
+
_applyBlock(perpImpulse, angularImpulse) {
|
|
227
|
+
const bodyA = this.bodyA;
|
|
228
|
+
const bodyB = this.bodyB;
|
|
229
|
+
const px = perpImpulse * this._perpX;
|
|
230
|
+
const py = perpImpulse * this._perpY;
|
|
231
|
+
bodyA.linearVelocityX -= bodyA.invMass * px;
|
|
232
|
+
bodyA.linearVelocityY -= bodyA.invMass * py;
|
|
233
|
+
bodyA.angularVelocity -= bodyA.invInertia * (perpImpulse * this._s1 + angularImpulse);
|
|
234
|
+
bodyB.linearVelocityX += bodyB.invMass * px;
|
|
235
|
+
bodyB.linearVelocityY += bodyB.invMass * py;
|
|
236
|
+
bodyB.angularVelocity += bodyB.invInertia * (perpImpulse * this._s2 + angularImpulse);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export { PrismaticJoint };
|
|
241
|
+
//# sourceMappingURL=PrismaticJoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrismaticJoint.js","sources":["../../../../src/joints/PrismaticJoint.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { PhysicsBody } from '../PhysicsBody';
|
|
2
|
+
import type { VectorLike } from '../types';
|
|
3
|
+
import { Joint } from './Joint';
|
|
4
|
+
/** Construction options for a {@link RevoluteJoint}. */
|
|
5
|
+
export interface RevoluteJointOptions {
|
|
6
|
+
/** First body (often a static anchor). */
|
|
7
|
+
bodyA: PhysicsBody;
|
|
8
|
+
/** Second body. */
|
|
9
|
+
bodyB: PhysicsBody;
|
|
10
|
+
/** Shared world-space pivot point at creation. The two bodies are pinned here and may rotate freely about it. */
|
|
11
|
+
anchor: VectorLike;
|
|
12
|
+
/** Soft-spring frequency in Hz; `0` (default) makes it a rigid pin. */
|
|
13
|
+
hertz?: number;
|
|
14
|
+
/** Soft-spring damping ratio (used when `hertz > 0`). Default `1`. */
|
|
15
|
+
dampingRatio?: number;
|
|
16
|
+
/** Enable the angular motor (drives `ωB − ωA` toward {@link motorSpeed}). Default `false`. */
|
|
17
|
+
enableMotor?: boolean;
|
|
18
|
+
/** Target relative angular velocity in rad/s when the motor is enabled. Default `0`. */
|
|
19
|
+
motorSpeed?: number;
|
|
20
|
+
/** Maximum motor torque — clamps the per-step motor impulse. Default `0`. */
|
|
21
|
+
maxMotorTorque?: number;
|
|
22
|
+
/** Enable the angle limit (keeps the relative angle in `[lowerAngle, upperAngle]`). Default `false`. */
|
|
23
|
+
enableLimit?: boolean;
|
|
24
|
+
/** Lower relative-angle limit in radians (relative to the angle at creation). Default `0`. */
|
|
25
|
+
lowerAngle?: number;
|
|
26
|
+
/** Upper relative-angle limit in radians. Default `0`. */
|
|
27
|
+
upperAngle?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Pins a shared anchor point on two bodies (a hinge): the bodies may rotate
|
|
31
|
+
* freely about the pivot but the anchor points stay coincident. Solved as a
|
|
32
|
+
* 2-DOF point constraint (a 2×2 block) in the sub-step loop, warm-started.
|
|
33
|
+
*/
|
|
34
|
+
export declare class RevoluteJoint extends Joint {
|
|
35
|
+
/** Soft-spring frequency in Hz (`0` = rigid). */
|
|
36
|
+
hertz: number;
|
|
37
|
+
/** Soft-spring damping ratio. */
|
|
38
|
+
dampingRatio: number;
|
|
39
|
+
/** When `true`, the motor drives `ωB − ωA` toward {@link motorSpeed}. */
|
|
40
|
+
enableMotor: boolean;
|
|
41
|
+
/** Target relative angular velocity (rad/s) for the motor. */
|
|
42
|
+
motorSpeed: number;
|
|
43
|
+
/** Maximum motor torque. */
|
|
44
|
+
maxMotorTorque: number;
|
|
45
|
+
/** When `true`, the relative angle is constrained to `[lowerAngle, upperAngle]`. */
|
|
46
|
+
enableLimit: boolean;
|
|
47
|
+
/** Lower relative-angle limit (radians, relative to the creation angle). */
|
|
48
|
+
lowerAngle: number;
|
|
49
|
+
/** Upper relative-angle limit (radians). */
|
|
50
|
+
upperAngle: number;
|
|
51
|
+
private readonly _localAnchorAx;
|
|
52
|
+
private readonly _localAnchorAy;
|
|
53
|
+
private readonly _localAnchorBx;
|
|
54
|
+
private readonly _localAnchorBy;
|
|
55
|
+
private _rAx;
|
|
56
|
+
private _rAy;
|
|
57
|
+
private _rBx;
|
|
58
|
+
private _rBy;
|
|
59
|
+
private _cx;
|
|
60
|
+
private _cy;
|
|
61
|
+
private _invK11;
|
|
62
|
+
private _invK12;
|
|
63
|
+
private _invK22;
|
|
64
|
+
private _biasRate;
|
|
65
|
+
private _massScale;
|
|
66
|
+
private _impulseScale;
|
|
67
|
+
private _impulseX;
|
|
68
|
+
private _impulseY;
|
|
69
|
+
private readonly _referenceAngle;
|
|
70
|
+
private _axialMass;
|
|
71
|
+
private _h;
|
|
72
|
+
private _invH;
|
|
73
|
+
private _motorImpulse;
|
|
74
|
+
private _lowerImpulse;
|
|
75
|
+
private _upperImpulse;
|
|
76
|
+
constructor(options: RevoluteJointOptions);
|
|
77
|
+
_prepare(h: number): void;
|
|
78
|
+
_warmStart(): void;
|
|
79
|
+
_solve(useBias: boolean): void;
|
|
80
|
+
private _applyImpulse;
|
|
81
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
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
|
+
/**
|
|
7
|
+
* Pins a shared anchor point on two bodies (a hinge): the bodies may rotate
|
|
8
|
+
* freely about the pivot but the anchor points stay coincident. Solved as a
|
|
9
|
+
* 2-DOF point constraint (a 2×2 block) in the sub-step loop, warm-started.
|
|
10
|
+
*/
|
|
11
|
+
class RevoluteJoint extends Joint {
|
|
12
|
+
/** Soft-spring frequency in Hz (`0` = rigid). */
|
|
13
|
+
hertz;
|
|
14
|
+
/** Soft-spring damping ratio. */
|
|
15
|
+
dampingRatio;
|
|
16
|
+
/** When `true`, the motor drives `ωB − ωA` toward {@link motorSpeed}. */
|
|
17
|
+
enableMotor;
|
|
18
|
+
/** Target relative angular velocity (rad/s) for the motor. */
|
|
19
|
+
motorSpeed;
|
|
20
|
+
/** Maximum motor torque. */
|
|
21
|
+
maxMotorTorque;
|
|
22
|
+
/** When `true`, the relative angle is constrained to `[lowerAngle, upperAngle]`. */
|
|
23
|
+
enableLimit;
|
|
24
|
+
/** Lower relative-angle limit (radians, relative to the creation angle). */
|
|
25
|
+
lowerAngle;
|
|
26
|
+
/** Upper relative-angle limit (radians). */
|
|
27
|
+
upperAngle;
|
|
28
|
+
_localAnchorAx;
|
|
29
|
+
_localAnchorAy;
|
|
30
|
+
_localAnchorBx;
|
|
31
|
+
_localAnchorBy;
|
|
32
|
+
_rAx = 0;
|
|
33
|
+
_rAy = 0;
|
|
34
|
+
_rBx = 0;
|
|
35
|
+
_rBy = 0;
|
|
36
|
+
_cx = 0;
|
|
37
|
+
_cy = 0;
|
|
38
|
+
_invK11 = 0;
|
|
39
|
+
_invK12 = 0;
|
|
40
|
+
_invK22 = 0;
|
|
41
|
+
_biasRate = 0;
|
|
42
|
+
_massScale = 1;
|
|
43
|
+
_impulseScale = 0;
|
|
44
|
+
_impulseX = 0;
|
|
45
|
+
_impulseY = 0;
|
|
46
|
+
_referenceAngle;
|
|
47
|
+
_axialMass = 0;
|
|
48
|
+
_h = 0;
|
|
49
|
+
_invH = 0;
|
|
50
|
+
_motorImpulse = 0;
|
|
51
|
+
_lowerImpulse = 0;
|
|
52
|
+
_upperImpulse = 0;
|
|
53
|
+
constructor(options) {
|
|
54
|
+
super(options.bodyA, options.bodyB);
|
|
55
|
+
applyInverseTransform(options.bodyA.transform, options.anchor.x, options.anchor.y, scratch);
|
|
56
|
+
this._localAnchorAx = scratch.x;
|
|
57
|
+
this._localAnchorAy = scratch.y;
|
|
58
|
+
applyInverseTransform(options.bodyB.transform, options.anchor.x, options.anchor.y, scratch);
|
|
59
|
+
this._localAnchorBx = scratch.x;
|
|
60
|
+
this._localAnchorBy = scratch.y;
|
|
61
|
+
this.hertz = options.hertz ?? 0;
|
|
62
|
+
this.dampingRatio = options.dampingRatio ?? 1;
|
|
63
|
+
this.enableMotor = options.enableMotor ?? false;
|
|
64
|
+
this.motorSpeed = options.motorSpeed ?? 0;
|
|
65
|
+
this.maxMotorTorque = options.maxMotorTorque ?? 0;
|
|
66
|
+
this.enableLimit = options.enableLimit ?? false;
|
|
67
|
+
this.lowerAngle = options.lowerAngle ?? 0;
|
|
68
|
+
this.upperAngle = options.upperAngle ?? 0;
|
|
69
|
+
this._referenceAngle = options.bodyB.angle - options.bodyA.angle;
|
|
70
|
+
}
|
|
71
|
+
_prepare(h) {
|
|
72
|
+
const bodyA = this.bodyA;
|
|
73
|
+
const bodyB = this.bodyB;
|
|
74
|
+
this._active = this.enabled && !bodyA.isSleeping && !bodyB.isSleeping && (bodyA.invMass > 0 || bodyB.invMass > 0);
|
|
75
|
+
if (!this._active) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
applyTransform(bodyA.transform, this._localAnchorAx, this._localAnchorAy, scratch);
|
|
79
|
+
const pAx = scratch.x;
|
|
80
|
+
const pAy = scratch.y;
|
|
81
|
+
applyTransform(bodyB.transform, this._localAnchorBx, this._localAnchorBy, scratch);
|
|
82
|
+
const pBx = scratch.x;
|
|
83
|
+
const pBy = scratch.y;
|
|
84
|
+
this._rAx = pAx - bodyA.worldCenterOfMassX;
|
|
85
|
+
this._rAy = pAy - bodyA.worldCenterOfMassY;
|
|
86
|
+
this._rBx = pBx - bodyB.worldCenterOfMassX;
|
|
87
|
+
this._rBy = pBy - bodyB.worldCenterOfMassY;
|
|
88
|
+
// Position error (the anchors should coincide).
|
|
89
|
+
this._cx = pBx - pAx;
|
|
90
|
+
this._cy = pBy - pAy;
|
|
91
|
+
const mA = bodyA.invMass;
|
|
92
|
+
const mB = bodyB.invMass;
|
|
93
|
+
const iA = bodyA.invInertia;
|
|
94
|
+
const iB = bodyB.invInertia;
|
|
95
|
+
// 2×2 effective-mass matrix K and its inverse.
|
|
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
|
+
// Angular (motor/limit) effective mass + sub-step rate.
|
|
105
|
+
this._axialMass = iA + iB > 0 ? 1 / (iA + iB) : 0;
|
|
106
|
+
this._h = h;
|
|
107
|
+
this._invH = 1 / h;
|
|
108
|
+
if (!this.enableMotor) {
|
|
109
|
+
this._motorImpulse = 0;
|
|
110
|
+
}
|
|
111
|
+
if (!this.enableLimit) {
|
|
112
|
+
this._lowerImpulse = 0;
|
|
113
|
+
this._upperImpulse = 0;
|
|
114
|
+
}
|
|
115
|
+
if (this.hertz > 0) {
|
|
116
|
+
const omega = 2 * Math.PI * this.hertz;
|
|
117
|
+
const a1 = 2 * this.dampingRatio + h * omega;
|
|
118
|
+
const a2 = h * omega * a1;
|
|
119
|
+
const a3 = 1 / (1 + a2);
|
|
120
|
+
this._biasRate = omega / a1;
|
|
121
|
+
this._massScale = a2 * a3;
|
|
122
|
+
this._impulseScale = a3;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
this._biasRate = 0.2 / h;
|
|
126
|
+
this._massScale = 1;
|
|
127
|
+
this._impulseScale = 0;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
_warmStart() {
|
|
131
|
+
if (!this._active) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
// Angular warm-start: motor + limits (lower pushes +, upper pushes −).
|
|
135
|
+
const axial = this._motorImpulse + this._lowerImpulse - this._upperImpulse;
|
|
136
|
+
this.bodyA.angularVelocity -= this.bodyA.invInertia * axial;
|
|
137
|
+
this.bodyB.angularVelocity += this.bodyB.invInertia * axial;
|
|
138
|
+
this._applyImpulse(this._impulseX, this._impulseY);
|
|
139
|
+
}
|
|
140
|
+
_solve(useBias) {
|
|
141
|
+
if (!this._active) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const bodyA = this.bodyA;
|
|
145
|
+
const bodyB = this.bodyB;
|
|
146
|
+
const iA = bodyA.invInertia;
|
|
147
|
+
const iB = bodyB.invInertia;
|
|
148
|
+
// Angular motor: drive ωB − ωA toward motorSpeed, clamped to ±maxMotorTorque·h.
|
|
149
|
+
if (this.enableMotor) {
|
|
150
|
+
const cdot = bodyB.angularVelocity - bodyA.angularVelocity - this.motorSpeed;
|
|
151
|
+
const max = this.maxMotorTorque * this._h;
|
|
152
|
+
const old = this._motorImpulse;
|
|
153
|
+
this._motorImpulse = Math.min(max, Math.max(-max, old - this._axialMass * cdot));
|
|
154
|
+
const applied = this._motorImpulse - old;
|
|
155
|
+
bodyA.angularVelocity -= iA * applied;
|
|
156
|
+
bodyB.angularVelocity += iB * applied;
|
|
157
|
+
}
|
|
158
|
+
// Angle limits: one-sided constraints keeping the relative angle in [lower, upper].
|
|
159
|
+
if (this.enableLimit) {
|
|
160
|
+
const angle = bodyB.angle + bodyB._deltaAngle - (bodyA.angle + bodyA._deltaAngle) - this._referenceAngle;
|
|
161
|
+
// Lower limit (angle ≥ lowerAngle): a positive impulse increases the angle.
|
|
162
|
+
const cLower = angle - this.lowerAngle;
|
|
163
|
+
let biasLower = 0;
|
|
164
|
+
if (cLower > 0) {
|
|
165
|
+
biasLower = cLower * this._invH; // speculative: allow approach, engage at the surface
|
|
166
|
+
}
|
|
167
|
+
else if (useBias) {
|
|
168
|
+
biasLower = 0.2 * this._invH * cLower; // Baumgarte push-back when violated
|
|
169
|
+
}
|
|
170
|
+
const oldLower = this._lowerImpulse;
|
|
171
|
+
this._lowerImpulse = Math.max(0, oldLower - this._axialMass * (bodyB.angularVelocity - bodyA.angularVelocity + biasLower));
|
|
172
|
+
const appliedLower = this._lowerImpulse - oldLower;
|
|
173
|
+
bodyA.angularVelocity -= iA * appliedLower;
|
|
174
|
+
bodyB.angularVelocity += iB * appliedLower;
|
|
175
|
+
// Upper limit (angle ≤ upperAngle): a positive impulse decreases the angle.
|
|
176
|
+
const cUpper = this.upperAngle - angle;
|
|
177
|
+
let biasUpper = 0;
|
|
178
|
+
if (cUpper > 0) {
|
|
179
|
+
biasUpper = cUpper * this._invH;
|
|
180
|
+
}
|
|
181
|
+
else if (useBias) {
|
|
182
|
+
biasUpper = 0.2 * this._invH * cUpper;
|
|
183
|
+
}
|
|
184
|
+
const oldUpper = this._upperImpulse;
|
|
185
|
+
this._upperImpulse = Math.max(0, oldUpper - this._axialMass * (bodyA.angularVelocity - bodyB.angularVelocity + biasUpper));
|
|
186
|
+
const appliedUpper = this._upperImpulse - oldUpper;
|
|
187
|
+
bodyA.angularVelocity += iA * appliedUpper;
|
|
188
|
+
bodyB.angularVelocity -= iB * appliedUpper;
|
|
189
|
+
}
|
|
190
|
+
// Relative velocity of the anchors.
|
|
191
|
+
const cdotX = bodyB.linearVelocityX - bodyB.angularVelocity * this._rBy - (bodyA.linearVelocityX - bodyA.angularVelocity * this._rAy);
|
|
192
|
+
const cdotY = bodyB.linearVelocityY + bodyB.angularVelocity * this._rBx - (bodyA.linearVelocityY + bodyA.angularVelocity * this._rAx);
|
|
193
|
+
const rhsX = cdotX + (useBias ? this._biasRate * this._cx : 0);
|
|
194
|
+
const rhsY = cdotY + (useBias ? this._biasRate * this._cy : 0);
|
|
195
|
+
// Solve K·λ = −rhs, then apply the soft mass/impulse scaling.
|
|
196
|
+
const solvedX = this._invK11 * rhsX + this._invK12 * rhsY;
|
|
197
|
+
const solvedY = this._invK12 * rhsX + this._invK22 * rhsY;
|
|
198
|
+
const impulseX = -this._massScale * solvedX - this._impulseScale * this._impulseX;
|
|
199
|
+
const impulseY = -this._massScale * solvedY - this._impulseScale * this._impulseY;
|
|
200
|
+
this._impulseX += impulseX;
|
|
201
|
+
this._impulseY += impulseY;
|
|
202
|
+
this._applyImpulse(impulseX, impulseY);
|
|
203
|
+
}
|
|
204
|
+
_applyImpulse(jx, jy) {
|
|
205
|
+
const bodyA = this.bodyA;
|
|
206
|
+
const bodyB = this.bodyB;
|
|
207
|
+
bodyA.linearVelocityX -= bodyA.invMass * jx;
|
|
208
|
+
bodyA.linearVelocityY -= bodyA.invMass * jy;
|
|
209
|
+
bodyA.angularVelocity -= bodyA.invInertia * (this._rAx * jy - this._rAy * jx);
|
|
210
|
+
bodyB.linearVelocityX += bodyB.invMass * jx;
|
|
211
|
+
bodyB.linearVelocityY += bodyB.invMass * jy;
|
|
212
|
+
bodyB.angularVelocity += bodyB.invInertia * (this._rBx * jy - this._rBy * jx);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export { RevoluteJoint };
|
|
217
|
+
//# sourceMappingURL=RevoluteJoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RevoluteJoint.js","sources":["../../../../src/joints/RevoluteJoint.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { PhysicsBody } from '../PhysicsBody';
|
|
2
|
+
import type { VectorLike } from '../types';
|
|
3
|
+
import { Joint } from './Joint';
|
|
4
|
+
/** Construction options for a {@link WeldJoint}. */
|
|
5
|
+
export interface WeldJointOptions {
|
|
6
|
+
/** First body. */
|
|
7
|
+
bodyA: PhysicsBody;
|
|
8
|
+
/** Second body. */
|
|
9
|
+
bodyB: PhysicsBody;
|
|
10
|
+
/** World-space anchor the linear constraint acts at. Default: the midpoint of the two bodies. */
|
|
11
|
+
anchor?: VectorLike;
|
|
12
|
+
/** Locked relative angle `angleB − angleA`. Default: the current relative angle at creation. */
|
|
13
|
+
referenceAngle?: number;
|
|
14
|
+
/** Soft frequency (Hz) for the position lock; `0` (default) is rigid. */
|
|
15
|
+
linearHertz?: number;
|
|
16
|
+
/** Soft frequency (Hz) for the angle lock; `0` (default) is rigid. */
|
|
17
|
+
angularHertz?: number;
|
|
18
|
+
/** Soft damping ratio (used when a hertz is `> 0`). Default `1`. */
|
|
19
|
+
dampingRatio?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Rigidly fixes the relative position and orientation of two bodies (they move
|
|
23
|
+
* as one rigid body). A 2-DOF point constraint (like {@link RevoluteJoint}) plus
|
|
24
|
+
* a 1-DOF angular constraint, solved in the sub-step loop. Both locks default to
|
|
25
|
+
* rigid; set `linearHertz`/`angularHertz` for a springy weld.
|
|
26
|
+
*/
|
|
27
|
+
export declare class WeldJoint extends Joint {
|
|
28
|
+
/** Locked relative angle `angleB − angleA`. */
|
|
29
|
+
referenceAngle: number;
|
|
30
|
+
/** Soft frequency for the position lock (`0` = rigid). */
|
|
31
|
+
linearHertz: number;
|
|
32
|
+
/** Soft frequency for the angle lock (`0` = rigid). */
|
|
33
|
+
angularHertz: number;
|
|
34
|
+
/** Soft damping ratio. */
|
|
35
|
+
dampingRatio: number;
|
|
36
|
+
private readonly _localAnchorAx;
|
|
37
|
+
private readonly _localAnchorAy;
|
|
38
|
+
private readonly _localAnchorBx;
|
|
39
|
+
private readonly _localAnchorBy;
|
|
40
|
+
private _rAx;
|
|
41
|
+
private _rAy;
|
|
42
|
+
private _rBx;
|
|
43
|
+
private _rBy;
|
|
44
|
+
private _cx;
|
|
45
|
+
private _cy;
|
|
46
|
+
private _invK11;
|
|
47
|
+
private _invK12;
|
|
48
|
+
private _invK22;
|
|
49
|
+
private _angleError;
|
|
50
|
+
private _effMassAngle;
|
|
51
|
+
private readonly _linear;
|
|
52
|
+
private readonly _angular;
|
|
53
|
+
private _impulseX;
|
|
54
|
+
private _impulseY;
|
|
55
|
+
private _impulseAngle;
|
|
56
|
+
constructor(options: WeldJointOptions);
|
|
57
|
+
_prepare(h: number): void;
|
|
58
|
+
_warmStart(): void;
|
|
59
|
+
_solve(useBias: boolean): void;
|
|
60
|
+
private _applyLinearImpulse;
|
|
61
|
+
}
|