@flighthq/physics3d 0.4.0-next.1694.598ef6f
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/contacts.d.ts +4 -0
- package/dist/contacts.d.ts.map +1 -0
- package/dist/contacts.js +55 -0
- package/dist/contacts.js.map +1 -0
- package/dist/contract.d.ts +17 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +17 -0
- package/dist/contract.js.map +1 -0
- package/dist/enablePhysics3DGuards.d.ts +4 -0
- package/dist/enablePhysics3DGuards.d.ts.map +1 -0
- package/dist/enablePhysics3DGuards.js +68 -0
- package/dist/enablePhysics3DGuards.js.map +1 -0
- package/dist/explainPhysics3DJoints.d.ts +3 -0
- package/dist/explainPhysics3DJoints.d.ts.map +1 -0
- package/dist/explainPhysics3DJoints.js +32 -0
- package/dist/explainPhysics3DJoints.js.map +1 -0
- package/dist/explainPhysics3DStep.d.ts +3 -0
- package/dist/explainPhysics3DStep.d.ts.map +1 -0
- package/dist/explainPhysics3DStep.js +48 -0
- package/dist/explainPhysics3DStep.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/integrate.d.ts +6 -0
- package/dist/integrate.d.ts.map +1 -0
- package/dist/integrate.js +154 -0
- package/dist/integrate.js.map +1 -0
- package/dist/islands.d.ts +5 -0
- package/dist/islands.d.ts.map +1 -0
- package/dist/islands.js +316 -0
- package/dist/islands.js.map +1 -0
- package/dist/jointCollisionSuppression.d.ts +4 -0
- package/dist/jointCollisionSuppression.d.ts.map +1 -0
- package/dist/jointCollisionSuppression.js +40 -0
- package/dist/jointCollisionSuppression.js.map +1 -0
- package/dist/jointFactories.d.ts +8 -0
- package/dist/jointFactories.d.ts.map +1 -0
- package/dist/jointFactories.js +126 -0
- package/dist/jointFactories.js.map +1 -0
- package/dist/jointMath.d.ts +17 -0
- package/dist/jointMath.d.ts.map +1 -0
- package/dist/jointMath.js +361 -0
- package/dist/jointMath.js.map +1 -0
- package/dist/jointRegistry.d.ts +8 -0
- package/dist/jointRegistry.d.ts.map +1 -0
- package/dist/jointRegistry.js +144 -0
- package/dist/jointRegistry.js.map +1 -0
- package/dist/jointRows.d.ts +32 -0
- package/dist/jointRows.d.ts.map +1 -0
- package/dist/jointRows.js +308 -0
- package/dist/jointRows.js.map +1 -0
- package/dist/joints.d.ts +14 -0
- package/dist/joints.d.ts.map +1 -0
- package/dist/joints.js +758 -0
- package/dist/joints.js.map +1 -0
- package/dist/massProperties.d.ts +8 -0
- package/dist/massProperties.d.ts.map +1 -0
- package/dist/massProperties.js +169 -0
- package/dist/massProperties.js.map +1 -0
- package/dist/ownership.d.ts +5 -0
- package/dist/ownership.d.ts.map +1 -0
- package/dist/ownership.js +16 -0
- package/dist/ownership.js.map +1 -0
- package/dist/registerBuiltInPhysics3DJointSolvers.d.ts +3 -0
- package/dist/registerBuiltInPhysics3DJointSolvers.d.ts.map +1 -0
- package/dist/registerBuiltInPhysics3DJointSolvers.js +14 -0
- package/dist/registerBuiltInPhysics3DJointSolvers.js.map +1 -0
- package/dist/solver.d.ts +8 -0
- package/dist/solver.d.ts.map +1 -0
- package/dist/solver.js +383 -0
- package/dist/solver.js.map +1 -0
- package/dist/step.d.ts +5 -0
- package/dist/step.d.ts.map +1 -0
- package/dist/step.js +250 -0
- package/dist/step.js.map +1 -0
- package/dist/stepValidation.d.ts +12 -0
- package/dist/stepValidation.d.ts.map +1 -0
- package/dist/stepValidation.js +201 -0
- package/dist/stepValidation.js.map +1 -0
- package/dist/symmetricTensor.d.ts +11 -0
- package/dist/symmetricTensor.d.ts.map +1 -0
- package/dist/symmetricTensor.js +150 -0
- package/dist/symmetricTensor.js.map +1 -0
- package/dist/world.d.ts +19 -0
- package/dist/world.d.ts.map +1 -0
- package/dist/world.js +370 -0
- package/dist/world.js.map +1 -0
- package/package.json +49 -0
- package/src/contacts.test.ts +64 -0
- package/src/enablePhysics3DGuards.test.ts +105 -0
- package/src/explainPhysics3DJoints.test.ts +101 -0
- package/src/explainPhysics3DStep.test.ts +123 -0
- package/src/integrate.test.ts +249 -0
- package/src/islands.test.ts +357 -0
- package/src/jointCollisionSuppression.test.ts +94 -0
- package/src/jointFactories.test.ts +195 -0
- package/src/jointMath.test.ts +643 -0
- package/src/jointRegistry.test.ts +229 -0
- package/src/jointRows.test.ts +484 -0
- package/src/joints.test.ts +677 -0
- package/src/massProperties.test.ts +305 -0
- package/src/ownership.test.ts +36 -0
- package/src/registerBuiltInPhysics3DJointSolvers.test.ts +48 -0
- package/src/solver.test.ts +481 -0
- package/src/step.test.ts +390 -0
- package/src/stepValidation.test.ts +244 -0
- package/src/symmetricTensor.test.ts +166 -0
- package/src/world.test.ts +512 -0
package/dist/solver.js
ADDED
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
import { applySymmetricTensor, TENSOR_XX, TENSOR_XY, TENSOR_XZ, TENSOR_YY, TENSOR_YZ, TENSOR_ZZ, } from './symmetricTensor';
|
|
2
|
+
// Allocates one contact constraint with no points. The solver owns this record; nothing here belongs
|
|
3
|
+
// on `Physics3DContact`, which carries geometry and identity only.
|
|
4
|
+
export function createPhysics3DContactConstraint() {
|
|
5
|
+
return {
|
|
6
|
+
contact: -1,
|
|
7
|
+
pointCount: 0,
|
|
8
|
+
points: [],
|
|
9
|
+
tangent0X: 0,
|
|
10
|
+
tangent0Y: 0,
|
|
11
|
+
tangent0Z: 0,
|
|
12
|
+
tangent1X: 0,
|
|
13
|
+
tangent1Y: 0,
|
|
14
|
+
tangent1Z: 0,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
// Allocates one point's accumulators, zeroed. A fresh point warm-starts from nothing, which is the
|
|
18
|
+
// correct behaviour for a contact that did not exist last step.
|
|
19
|
+
export function createPhysics3DContactConstraintPoint() {
|
|
20
|
+
return {
|
|
21
|
+
bias: 0,
|
|
22
|
+
featureId: 0,
|
|
23
|
+
normalImpulse: 0,
|
|
24
|
+
normalMass: 0,
|
|
25
|
+
tangentImpulse0: 0,
|
|
26
|
+
tangentImpulse1: 0,
|
|
27
|
+
tangentMass0: 0,
|
|
28
|
+
tangentMass1: 0,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// Rebuilds the solver's working set from the world's contact list and prepares every constraint row:
|
|
32
|
+
// the friction basis, the three effective masses, and the restitution bias.
|
|
33
|
+
//
|
|
34
|
+
// Call once per sub-interval, after `buildPhysics3DSolveIslands` and before
|
|
35
|
+
// `warmStartPhysics3DContacts`. The island order is a real precondition rather than a convention: this
|
|
36
|
+
// reads the island contact slices, so a world whose workspace was never built has no contacts to
|
|
37
|
+
// prepare and produces no constraints at all.
|
|
38
|
+
//
|
|
39
|
+
// Two things happen here that cannot happen anywhere else. The restitution bias is captured from the
|
|
40
|
+
// approach speed BEFORE any impulse is applied — once the first iteration runs, the velocity it would
|
|
41
|
+
// be read from has already been changed by the solve, and restitution computed from it decays toward
|
|
42
|
+
// zero. And the accumulators are matched to last step's by `featureId` rather than by point index,
|
|
43
|
+
// because a narrow phase may report the same physical corner at a different index between steps, and
|
|
44
|
+
// warm starting the wrong corner is worse than not warm starting at all.
|
|
45
|
+
//
|
|
46
|
+
// Contacts that are disabled, sensors, non-touching, asleep, or between two bodies that both have
|
|
47
|
+
// infinite mass produce no constraint: they are skipped rather than emitted with zero rows, so the
|
|
48
|
+
// iteration loops never see work that cannot move anything.
|
|
49
|
+
//
|
|
50
|
+
// The disabled, sensor, and sleeping ones are already gone before this runs, because the iteration is
|
|
51
|
+
// over the SOLVE ISLAND contact slices rather than `world.contacts`. That is what makes a settled world
|
|
52
|
+
// cost nothing here: a sleeping island contributes no slice, so a thousand-body pile at rest is not
|
|
53
|
+
// re-scanned every sub-interval merely to discover there is nothing to do. It also groups the emitted
|
|
54
|
+
// constraints island-major, which disconnected islands cannot perturb for each other.
|
|
55
|
+
//
|
|
56
|
+
// The remaining velocity and position passes stay global over the emitted list rather than looping per
|
|
57
|
+
// island. With a fixed iteration count and no convergence test the two are the same work in the same
|
|
58
|
+
// order — islands are disconnected, so interleaving them cannot change a result — and the flat list is
|
|
59
|
+
// what lets joints and contacts share one interleaved pass.
|
|
60
|
+
export function preparePhysics3DContactConstraints(world) {
|
|
61
|
+
const state = world.solver;
|
|
62
|
+
const previousByPair = state.constraintByPair;
|
|
63
|
+
const constraints = [];
|
|
64
|
+
const nextByPair = new Map();
|
|
65
|
+
const config = world.config.sequentialImpulse;
|
|
66
|
+
for (let island = 0; island < world.solveIslandRoots.length; island += 1) {
|
|
67
|
+
const islandStart = world.solveIslandContactStarts[island];
|
|
68
|
+
const islandEnd = islandStart + world.solveIslandContactCounts[island];
|
|
69
|
+
for (let at = islandStart; at < islandEnd; at += 1) {
|
|
70
|
+
const contactIndex = world.solveIslandContactIndices[at];
|
|
71
|
+
const contact = world.contacts[contactIndex];
|
|
72
|
+
if (!contact.touching || contact.pointCount === 0)
|
|
73
|
+
continue;
|
|
74
|
+
const bodyA = world.bodyByIndex.get(contact.bodyA);
|
|
75
|
+
const bodyB = world.bodyByIndex.get(contact.bodyB);
|
|
76
|
+
if (bodyA === undefined || bodyB === undefined)
|
|
77
|
+
continue;
|
|
78
|
+
if (bodyA.inverseMass === 0 &&
|
|
79
|
+
bodyB.inverseMass === 0 &&
|
|
80
|
+
!hasRotationalFreedom(bodyA) &&
|
|
81
|
+
!hasRotationalFreedom(bodyB)) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const constraint = createPhysics3DContactConstraint();
|
|
85
|
+
constraint.contact = contactIndex;
|
|
86
|
+
writeFrictionBasis(contact.normalX, contact.normalY, contact.normalZ, constraint);
|
|
87
|
+
const previous = previousByPair.get(getContactPairKey(contact.bodyA, contact.bodyB));
|
|
88
|
+
for (let i = 0; i < contact.pointCount; i += 1) {
|
|
89
|
+
const source = contact.points[i];
|
|
90
|
+
const point = createPhysics3DContactConstraintPoint();
|
|
91
|
+
point.featureId = source.featureId;
|
|
92
|
+
if (config.warmStarting && previous !== undefined) {
|
|
93
|
+
const carried = findPointByFeatureId(previous, source.featureId);
|
|
94
|
+
if (carried !== null) {
|
|
95
|
+
point.normalImpulse = carried.normalImpulse;
|
|
96
|
+
point.tangentImpulse0 = carried.tangentImpulse0;
|
|
97
|
+
point.tangentImpulse1 = carried.tangentImpulse1;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
point.normalMass = getEffectiveMass(bodyA, bodyB, source.rAX, source.rAY, source.rAZ, source.rBX, source.rBY, source.rBZ, contact.normalX, contact.normalY, contact.normalZ);
|
|
101
|
+
point.tangentMass0 = getEffectiveMass(bodyA, bodyB, source.rAX, source.rAY, source.rAZ, source.rBX, source.rBY, source.rBZ, constraint.tangent0X, constraint.tangent0Y, constraint.tangent0Z);
|
|
102
|
+
point.tangentMass1 = getEffectiveMass(bodyA, bodyB, source.rAX, source.rAY, source.rAZ, source.rBX, source.rBY, source.rBZ, constraint.tangent1X, constraint.tangent1Y, constraint.tangent1Z);
|
|
103
|
+
const approach = getRelativeNormalVelocity(bodyA, bodyB, source.rAX, source.rAY, source.rAZ, source.rBX, source.rBY, source.rBZ, contact.normalX, contact.normalY, contact.normalZ);
|
|
104
|
+
point.bias = approach < -config.restitutionThreshold ? -contact.restitution * approach : 0;
|
|
105
|
+
constraint.points.push(point);
|
|
106
|
+
constraint.pointCount += 1;
|
|
107
|
+
}
|
|
108
|
+
constraints.push(constraint);
|
|
109
|
+
nextByPair.set(getContactPairKey(contact.bodyA, contact.bodyB), constraint);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
state.constraints = constraints;
|
|
113
|
+
state.constraintByPair = nextByPair;
|
|
114
|
+
}
|
|
115
|
+
// Resolves penetration by moving bodies directly, leaving `penetrationSlop` of overlap deliberately
|
|
116
|
+
// unresolved so resting bodies do not twitch against a target of exactly zero. Returns the deepest
|
|
117
|
+
// remaining penetration, so a caller can stop iterating once the stack is within tolerance.
|
|
118
|
+
//
|
|
119
|
+
// This is a separate pass from the velocity solve on purpose: correcting overlap by adding separating
|
|
120
|
+
// velocity injects energy the simulation never spent, and a deep stack resolved that way visibly
|
|
121
|
+
// launches itself apart.
|
|
122
|
+
//
|
|
123
|
+
// The lever arms are the ones captured at prepare time and are NOT recomputed as bodies move. A true
|
|
124
|
+
// non-linear Gauss-Seidel re-derives the contact from the shapes each iteration; this package has no
|
|
125
|
+
// shapes to re-derive from, so the approximation is structural rather than an omission — it is good for
|
|
126
|
+
// the small corrections that resting contact produces and degrades as a correction gets large.
|
|
127
|
+
export function solvePhysics3DContactPositions(world) {
|
|
128
|
+
const config = world.config.sequentialImpulse;
|
|
129
|
+
let deepest = 0;
|
|
130
|
+
for (const constraint of world.solver.constraints) {
|
|
131
|
+
const contact = world.contacts[constraint.contact];
|
|
132
|
+
const bodyA = world.bodyByIndex.get(contact.bodyA);
|
|
133
|
+
const bodyB = world.bodyByIndex.get(contact.bodyB);
|
|
134
|
+
if (bodyA === undefined || bodyB === undefined)
|
|
135
|
+
continue;
|
|
136
|
+
for (let i = 0; i < constraint.pointCount; i += 1) {
|
|
137
|
+
const source = contact.points[i];
|
|
138
|
+
const point = constraint.points[i];
|
|
139
|
+
const excess = source.depth - config.penetrationSlop;
|
|
140
|
+
if (excess > deepest)
|
|
141
|
+
deepest = excess;
|
|
142
|
+
if (excess <= 0)
|
|
143
|
+
continue;
|
|
144
|
+
const correction = config.positionCorrection * excess * point.normalMass;
|
|
145
|
+
applyPositionCorrection(bodyA, bodyB, source.rAX, source.rAY, source.rAZ, source.rBX, source.rBY, source.rBZ, contact.normalX * correction, contact.normalY * correction, contact.normalZ * correction);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return deepest;
|
|
149
|
+
}
|
|
150
|
+
// Runs one velocity iteration over every prepared constraint. Call `velocityIterations` times.
|
|
151
|
+
//
|
|
152
|
+
// Friction is solved before the normal, and the two tangents are clamped TOGETHER as a cone rather
|
|
153
|
+
// than independently. Clamping each to `friction * normalImpulse` on its own admits a combined
|
|
154
|
+
// magnitude of `sqrt(2) * friction * normalImpulse` along the diagonal, which presents as a box that
|
|
155
|
+
// slides measurably faster at 45 degrees than it does along either tangent — a bug that looks like bad
|
|
156
|
+
// friction tuning rather than like a geometry error, and one that cannot occur in 2D because there is
|
|
157
|
+
// only one tangent to clamp.
|
|
158
|
+
export function solvePhysics3DContactVelocities(world) {
|
|
159
|
+
for (const constraint of world.solver.constraints) {
|
|
160
|
+
const contact = world.contacts[constraint.contact];
|
|
161
|
+
const bodyA = world.bodyByIndex.get(contact.bodyA);
|
|
162
|
+
const bodyB = world.bodyByIndex.get(contact.bodyB);
|
|
163
|
+
if (bodyA === undefined || bodyB === undefined)
|
|
164
|
+
continue;
|
|
165
|
+
for (let i = 0; i < constraint.pointCount; i += 1) {
|
|
166
|
+
const source = contact.points[i];
|
|
167
|
+
const point = constraint.points[i];
|
|
168
|
+
const maxFriction = contact.friction * point.normalImpulse;
|
|
169
|
+
const tangentVelocity0 = getRelativeNormalVelocity(bodyA, bodyB, source.rAX, source.rAY, source.rAZ, source.rBX, source.rBY, source.rBZ, constraint.tangent0X, constraint.tangent0Y, constraint.tangent0Z);
|
|
170
|
+
let impulse0 = point.tangentImpulse0 - tangentVelocity0 * point.tangentMass0;
|
|
171
|
+
const tangentVelocity1 = getRelativeNormalVelocity(bodyA, bodyB, source.rAX, source.rAY, source.rAZ, source.rBX, source.rBY, source.rBZ, constraint.tangent1X, constraint.tangent1Y, constraint.tangent1Z);
|
|
172
|
+
let impulse1 = point.tangentImpulse1 - tangentVelocity1 * point.tangentMass1;
|
|
173
|
+
const magnitude = Math.sqrt(impulse0 * impulse0 + impulse1 * impulse1);
|
|
174
|
+
if (magnitude > maxFriction) {
|
|
175
|
+
const scale = maxFriction / magnitude;
|
|
176
|
+
impulse0 *= scale;
|
|
177
|
+
impulse1 *= scale;
|
|
178
|
+
}
|
|
179
|
+
const deltaTangent0 = impulse0 - point.tangentImpulse0;
|
|
180
|
+
const deltaTangent1 = impulse1 - point.tangentImpulse1;
|
|
181
|
+
point.tangentImpulse0 = impulse0;
|
|
182
|
+
point.tangentImpulse1 = impulse1;
|
|
183
|
+
applyContactImpulse(bodyA, bodyB, source.rAX, source.rAY, source.rAZ, source.rBX, source.rBY, source.rBZ, constraint.tangent0X * deltaTangent0 + constraint.tangent1X * deltaTangent1, constraint.tangent0Y * deltaTangent0 + constraint.tangent1Y * deltaTangent1, constraint.tangent0Z * deltaTangent0 + constraint.tangent1Z * deltaTangent1);
|
|
184
|
+
const normalVelocity = getRelativeNormalVelocity(bodyA, bodyB, source.rAX, source.rAY, source.rAZ, source.rBX, source.rBY, source.rBZ, contact.normalX, contact.normalY, contact.normalZ);
|
|
185
|
+
const normalImpulse = Math.max(point.normalImpulse + (point.bias - normalVelocity) * point.normalMass, 0);
|
|
186
|
+
const deltaNormal = normalImpulse - point.normalImpulse;
|
|
187
|
+
point.normalImpulse = normalImpulse;
|
|
188
|
+
applyContactImpulse(bodyA, bodyB, source.rAX, source.rAY, source.rAZ, source.rBX, source.rBY, source.rBZ, contact.normalX * deltaNormal, contact.normalY * deltaNormal, contact.normalZ * deltaNormal);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// Replays the accumulated impulses carried over from last step, so the solver starts an iteration
|
|
193
|
+
// budget from roughly the answer it converged to rather than from zero. A stack solved cold every step
|
|
194
|
+
// sinks visibly under its own weight at any practical iteration count.
|
|
195
|
+
//
|
|
196
|
+
// Runs after `preparePhysics3DContactConstraints` and before the first velocity iteration.
|
|
197
|
+
export function warmStartPhysics3DContacts(world) {
|
|
198
|
+
if (!world.config.sequentialImpulse.warmStarting)
|
|
199
|
+
return;
|
|
200
|
+
for (const constraint of world.solver.constraints) {
|
|
201
|
+
const contact = world.contacts[constraint.contact];
|
|
202
|
+
const bodyA = world.bodyByIndex.get(contact.bodyA);
|
|
203
|
+
const bodyB = world.bodyByIndex.get(contact.bodyB);
|
|
204
|
+
if (bodyA === undefined || bodyB === undefined)
|
|
205
|
+
continue;
|
|
206
|
+
for (let i = 0; i < constraint.pointCount; i += 1) {
|
|
207
|
+
const source = contact.points[i];
|
|
208
|
+
const point = constraint.points[i];
|
|
209
|
+
applyContactImpulse(bodyA, bodyB, source.rAX, source.rAY, source.rAZ, source.rBX, source.rBY, source.rBZ, contact.normalX * point.normalImpulse +
|
|
210
|
+
constraint.tangent0X * point.tangentImpulse0 +
|
|
211
|
+
constraint.tangent1X * point.tangentImpulse1, contact.normalY * point.normalImpulse +
|
|
212
|
+
constraint.tangent0Y * point.tangentImpulse0 +
|
|
213
|
+
constraint.tangent1Y * point.tangentImpulse1, contact.normalZ * point.normalImpulse +
|
|
214
|
+
constraint.tangent0Z * point.tangentImpulse0 +
|
|
215
|
+
constraint.tangent1Z * point.tangentImpulse1);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// Applies an equal and opposite impulse at the contact: A gains it, B loses it. The contact normal
|
|
220
|
+
// points out of B, so a positive normal impulse separates the pair.
|
|
221
|
+
function applyContactImpulse(bodyA, bodyB, rAX, rAY, rAZ, rBX, rBY, rBZ, impulseX, impulseY, impulseZ) {
|
|
222
|
+
applyBodyImpulse(bodyA, rAX, rAY, rAZ, impulseX, impulseY, impulseZ);
|
|
223
|
+
applyBodyImpulse(bodyB, rBX, rBY, rBZ, -impulseX, -impulseY, -impulseZ);
|
|
224
|
+
}
|
|
225
|
+
// A static body's zero inverse mass and zero inverse inertia make this a no-op with no branch, which is
|
|
226
|
+
// the whole reason infinite mass is represented as a zero inverse rather than as a flag.
|
|
227
|
+
function applyBodyImpulse(body, rX, rY, rZ, impulseX, impulseY, impulseZ) {
|
|
228
|
+
body.velocityX += impulseX * body.inverseMass;
|
|
229
|
+
body.velocityY += impulseY * body.inverseMass;
|
|
230
|
+
body.velocityZ += impulseZ * body.inverseMass;
|
|
231
|
+
const torqueX = rY * impulseZ - rZ * impulseY;
|
|
232
|
+
const torqueY = rZ * impulseX - rX * impulseZ;
|
|
233
|
+
const torqueZ = rX * impulseY - rY * impulseX;
|
|
234
|
+
readWorldInverseInertia(body, scratchTensor);
|
|
235
|
+
applySymmetricTensor(scratchTensor, torqueX, torqueY, torqueZ, scratchVector);
|
|
236
|
+
body.angularVelocityX += scratchVector[0];
|
|
237
|
+
body.angularVelocityY += scratchVector[1];
|
|
238
|
+
body.angularVelocityZ += scratchVector[2];
|
|
239
|
+
}
|
|
240
|
+
// Moves both bodies apart along an already-scaled correction vector, rotating each about its centre of
|
|
241
|
+
// mass by the same lever-arm term the velocity solve uses. Orientation is nudged by the small-angle
|
|
242
|
+
// quaternion update and renormalized, exactly as pose integration does.
|
|
243
|
+
function applyPositionCorrection(bodyA, bodyB, rAX, rAY, rAZ, rBX, rBY, rBZ, correctionX, correctionY, correctionZ) {
|
|
244
|
+
applyBodyPositionCorrection(bodyA, rAX, rAY, rAZ, correctionX, correctionY, correctionZ);
|
|
245
|
+
applyBodyPositionCorrection(bodyB, rBX, rBY, rBZ, -correctionX, -correctionY, -correctionZ);
|
|
246
|
+
}
|
|
247
|
+
function applyBodyPositionCorrection(body, rX, rY, rZ, correctionX, correctionY, correctionZ) {
|
|
248
|
+
body.x += correctionX * body.inverseMass;
|
|
249
|
+
body.y += correctionY * body.inverseMass;
|
|
250
|
+
body.z += correctionZ * body.inverseMass;
|
|
251
|
+
const turnX = rY * correctionZ - rZ * correctionY;
|
|
252
|
+
const turnY = rZ * correctionX - rX * correctionZ;
|
|
253
|
+
const turnZ = rX * correctionY - rY * correctionX;
|
|
254
|
+
readWorldInverseInertia(body, scratchTensor);
|
|
255
|
+
applySymmetricTensor(scratchTensor, turnX, turnY, turnZ, scratchVector);
|
|
256
|
+
const angleX = scratchVector[0];
|
|
257
|
+
const angleY = scratchVector[1];
|
|
258
|
+
const angleZ = scratchVector[2];
|
|
259
|
+
if (angleX === 0 && angleY === 0 && angleZ === 0)
|
|
260
|
+
return;
|
|
261
|
+
const qx = body.orientationX;
|
|
262
|
+
const qy = body.orientationY;
|
|
263
|
+
const qz = body.orientationZ;
|
|
264
|
+
const qw = body.orientationW;
|
|
265
|
+
let nextX = qx + 0.5 * (angleX * qw + angleY * qz - angleZ * qy);
|
|
266
|
+
let nextY = qy + 0.5 * (angleY * qw + angleZ * qx - angleX * qz);
|
|
267
|
+
let nextZ = qz + 0.5 * (angleZ * qw + angleX * qy - angleY * qx);
|
|
268
|
+
let nextW = qw - 0.5 * (angleX * qx + angleY * qy + angleZ * qz);
|
|
269
|
+
const length = Math.sqrt(nextX * nextX + nextY * nextY + nextZ * nextZ + nextW * nextW);
|
|
270
|
+
if (length === 0)
|
|
271
|
+
return;
|
|
272
|
+
const inverseLength = 1 / length;
|
|
273
|
+
nextX *= inverseLength;
|
|
274
|
+
nextY *= inverseLength;
|
|
275
|
+
nextZ *= inverseLength;
|
|
276
|
+
nextW *= inverseLength;
|
|
277
|
+
body.orientationX = nextX;
|
|
278
|
+
body.orientationY = nextY;
|
|
279
|
+
body.orientationZ = nextZ;
|
|
280
|
+
body.orientationW = nextW;
|
|
281
|
+
}
|
|
282
|
+
// Locates last step's accumulators for a feature. Linear because a manifold holds at most a handful of
|
|
283
|
+
// points and a map per contact would cost more than the scan.
|
|
284
|
+
function findPointByFeatureId(constraint, featureId) {
|
|
285
|
+
for (let i = 0; i < constraint.pointCount; i += 1) {
|
|
286
|
+
if (constraint.points[i].featureId === featureId)
|
|
287
|
+
return constraint.points[i];
|
|
288
|
+
}
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
// Packs a canonical body pair into one number by positional multiplication rather than bit shifting.
|
|
292
|
+
// `<<` truncates to 32 bits, so a shift-packed key would silently alias two unrelated pairs onto one
|
|
293
|
+
// entry once an index passed its field width — and the symptom would be a contact warm-started with an
|
|
294
|
+
// impulse belonging to a different pair entirely, which reads as jitter rather than as a fault. The
|
|
295
|
+
// widest key here is under 2^52, so every key is an exactly representable integer.
|
|
296
|
+
function getContactPairKey(bodyA, bodyB) {
|
|
297
|
+
return bodyA * PAIR_KEY_SCALE + bodyB;
|
|
298
|
+
}
|
|
299
|
+
// The constraint denominator along one direction: the scalar mass a unit impulse in that direction
|
|
300
|
+
// acts against, including both bodies' resistance to being spun about the contact.
|
|
301
|
+
//
|
|
302
|
+
// Returns 0 when the pair cannot move along the direction at all, so the impulse computed from it is
|
|
303
|
+
// zero rather than infinite.
|
|
304
|
+
function getEffectiveMass(bodyA, bodyB, rAX, rAY, rAZ, rBX, rBY, rBZ, directionX, directionY, directionZ) {
|
|
305
|
+
let denominator = bodyA.inverseMass + bodyB.inverseMass;
|
|
306
|
+
const crossAX = rAY * directionZ - rAZ * directionY;
|
|
307
|
+
const crossAY = rAZ * directionX - rAX * directionZ;
|
|
308
|
+
const crossAZ = rAX * directionY - rAY * directionX;
|
|
309
|
+
readWorldInverseInertia(bodyA, scratchTensor);
|
|
310
|
+
applySymmetricTensor(scratchTensor, crossAX, crossAY, crossAZ, scratchVector);
|
|
311
|
+
denominator += crossAX * scratchVector[0] + crossAY * scratchVector[1] + crossAZ * scratchVector[2];
|
|
312
|
+
const crossBX = rBY * directionZ - rBZ * directionY;
|
|
313
|
+
const crossBY = rBZ * directionX - rBX * directionZ;
|
|
314
|
+
const crossBZ = rBX * directionY - rBY * directionX;
|
|
315
|
+
readWorldInverseInertia(bodyB, scratchTensor);
|
|
316
|
+
applySymmetricTensor(scratchTensor, crossBX, crossBY, crossBZ, scratchVector);
|
|
317
|
+
denominator += crossBX * scratchVector[0] + crossBY * scratchVector[1] + crossBZ * scratchVector[2];
|
|
318
|
+
return denominator > 0 ? 1 / denominator : 0;
|
|
319
|
+
}
|
|
320
|
+
// The closing speed of the two contact points along a direction, positive when they separate. Each
|
|
321
|
+
// point's velocity is its body's linear velocity plus the rotational contribution at its lever arm,
|
|
322
|
+
// which is the term that makes a spinning body's surface move even when its centre is still.
|
|
323
|
+
function getRelativeNormalVelocity(bodyA, bodyB, rAX, rAY, rAZ, rBX, rBY, rBZ, directionX, directionY, directionZ) {
|
|
324
|
+
const pointAX = bodyA.velocityX + (bodyA.angularVelocityY * rAZ - bodyA.angularVelocityZ * rAY);
|
|
325
|
+
const pointAY = bodyA.velocityY + (bodyA.angularVelocityZ * rAX - bodyA.angularVelocityX * rAZ);
|
|
326
|
+
const pointAZ = bodyA.velocityZ + (bodyA.angularVelocityX * rAY - bodyA.angularVelocityY * rAX);
|
|
327
|
+
const pointBX = bodyB.velocityX + (bodyB.angularVelocityY * rBZ - bodyB.angularVelocityZ * rBY);
|
|
328
|
+
const pointBY = bodyB.velocityY + (bodyB.angularVelocityZ * rBX - bodyB.angularVelocityX * rBZ);
|
|
329
|
+
const pointBZ = bodyB.velocityZ + (bodyB.angularVelocityX * rBY - bodyB.angularVelocityY * rBX);
|
|
330
|
+
return (pointAX - pointBX) * directionX + (pointAY - pointBY) * directionY + (pointAZ - pointBZ) * directionZ;
|
|
331
|
+
}
|
|
332
|
+
function hasRotationalFreedom(body) {
|
|
333
|
+
return (body.inverseInertiaWorldXX !== 0 ||
|
|
334
|
+
body.inverseInertiaWorldYY !== 0 ||
|
|
335
|
+
body.inverseInertiaWorldZZ !== 0 ||
|
|
336
|
+
body.inverseInertiaWorldXY !== 0 ||
|
|
337
|
+
body.inverseInertiaWorldXZ !== 0 ||
|
|
338
|
+
body.inverseInertiaWorldYZ !== 0);
|
|
339
|
+
}
|
|
340
|
+
function readWorldInverseInertia(body, out) {
|
|
341
|
+
out[TENSOR_XX] = body.inverseInertiaWorldXX;
|
|
342
|
+
out[TENSOR_YY] = body.inverseInertiaWorldYY;
|
|
343
|
+
out[TENSOR_ZZ] = body.inverseInertiaWorldZZ;
|
|
344
|
+
out[TENSOR_XY] = body.inverseInertiaWorldXY;
|
|
345
|
+
out[TENSOR_XZ] = body.inverseInertiaWorldXZ;
|
|
346
|
+
out[TENSOR_YZ] = body.inverseInertiaWorldYZ;
|
|
347
|
+
}
|
|
348
|
+
// Builds an orthonormal pair spanning the plane orthogonal to the contact normal. The seed axis is
|
|
349
|
+
// whichever principal axis the normal leans on least, so the cross product is never near-degenerate:
|
|
350
|
+
// a normal within 1/sqrt(3) of x leans on x least often, and that threshold is exactly where the
|
|
351
|
+
// choice flips.
|
|
352
|
+
function writeFrictionBasis(normalX, normalY, normalZ, out) {
|
|
353
|
+
let seedX = 0;
|
|
354
|
+
let seedY = 0;
|
|
355
|
+
let seedZ = 0;
|
|
356
|
+
if (Math.abs(normalX) < AXIS_SELECTION_THRESHOLD)
|
|
357
|
+
seedX = 1;
|
|
358
|
+
else if (Math.abs(normalY) < AXIS_SELECTION_THRESHOLD)
|
|
359
|
+
seedY = 1;
|
|
360
|
+
else
|
|
361
|
+
seedZ = 1;
|
|
362
|
+
let tangent0X = normalY * seedZ - normalZ * seedY;
|
|
363
|
+
let tangent0Y = normalZ * seedX - normalX * seedZ;
|
|
364
|
+
let tangent0Z = normalX * seedY - normalY * seedX;
|
|
365
|
+
const length = Math.sqrt(tangent0X * tangent0X + tangent0Y * tangent0Y + tangent0Z * tangent0Z);
|
|
366
|
+
if (length > 0) {
|
|
367
|
+
const inverseLength = 1 / length;
|
|
368
|
+
tangent0X *= inverseLength;
|
|
369
|
+
tangent0Y *= inverseLength;
|
|
370
|
+
tangent0Z *= inverseLength;
|
|
371
|
+
}
|
|
372
|
+
out.tangent0X = tangent0X;
|
|
373
|
+
out.tangent0Y = tangent0Y;
|
|
374
|
+
out.tangent0Z = tangent0Z;
|
|
375
|
+
out.tangent1X = normalY * tangent0Z - normalZ * tangent0Y;
|
|
376
|
+
out.tangent1Y = normalZ * tangent0X - normalX * tangent0Z;
|
|
377
|
+
out.tangent1Z = normalX * tangent0Y - normalY * tangent0X;
|
|
378
|
+
}
|
|
379
|
+
const AXIS_SELECTION_THRESHOLD = 0.5773502691896258;
|
|
380
|
+
const PAIR_KEY_SCALE = 67108864;
|
|
381
|
+
const scratchTensor = [0, 0, 0, 0, 0, 0];
|
|
382
|
+
const scratchVector = [0, 0, 0];
|
|
383
|
+
//# sourceMappingURL=solver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solver.js","sourceRoot":"","sources":["../src/solver.ts"],"names":[],"mappings":"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"}
|
package/dist/step.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Physics3DStepGuard, Physics3DWorld } from '@flighthq/types/contract';
|
|
2
|
+
export declare function setPhysics3DStepGuard(guard: Physics3DStepGuard | null): void;
|
|
3
|
+
export declare function stepPhysics3D(world: Physics3DWorld, dt: number): void;
|
|
4
|
+
export declare function stepPhysics3DInterval(world: Physics3DWorld, dt: number): void;
|
|
5
|
+
//# sourceMappingURL=step.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step.d.ts","sourceRoot":"","sources":["../src/step.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAKV,kBAAkB,EAClB,cAAc,EAEf,MAAM,0BAA0B,CAAC;AAgClC,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,GAAG,IAAI,CAE5E;AAcD,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAgCrE;AAkBD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAwC7E"}
|