@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/step.js
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { clearRigidBody3DForces, integrateRigidBody3DPose, integrateRigidBody3DVelocity, refreshRigidBody3DWorldInertia, } from './integrate';
|
|
2
|
+
import { buildPhysics3DSolveIslands, updatePhysics3DSleep } from './islands';
|
|
3
|
+
import { steppingPhysics3DWorlds } from './ownership';
|
|
4
|
+
import { preparePhysics3DContactConstraints, solvePhysics3DContactPositions, solvePhysics3DContactVelocities, warmStartPhysics3DContacts, } from './solver';
|
|
5
|
+
import { isPhysics3DBodyStateValid, isPhysics3DContactStateValid, isPhysics3DContactValid, isPhysics3DGravityValid, isPhysics3DJointStateValid, isPhysics3DPositionIterationsValid, isPhysics3DSolverConfigValid, isPhysics3DSubstepsValid, isPhysics3DTimestepValid, isPhysics3DVelocityIterationsValid, } from './stepValidation';
|
|
6
|
+
// Installs the optional diagnostics seam consulted when a step declines its preconditions. Null by
|
|
7
|
+
// default and set only by `enablePhysics3DGuards`, so a build that never enables guards links neither the
|
|
8
|
+
// message text nor `@flighthq/log`.
|
|
9
|
+
export function setPhysics3DStepGuard(guard) {
|
|
10
|
+
physics3DStepGuard = guard;
|
|
11
|
+
}
|
|
12
|
+
// Advances the simulation by `dt` seconds. Everything the step does, it does because the caller asked:
|
|
13
|
+
// no implicit accumulation, no fixed-timestep loop hidden inside, and no allocation once the world's
|
|
14
|
+
// bodies, contacts, and joints exist.
|
|
15
|
+
//
|
|
16
|
+
// It declines SILENTLY on any failed precondition rather than throwing, because a NaN velocity or a zero
|
|
17
|
+
// timestep is a state a caller reaches by writing a field, and a throw from inside the step would take
|
|
18
|
+
// down a frame loop for something the caller can inspect and repair. `explainPhysics3DStep` is how a
|
|
19
|
+
// caller finds out which precondition failed, and it is separately importable so a shipping build that
|
|
20
|
+
// never asks never links it.
|
|
21
|
+
//
|
|
22
|
+
// Recursion IS a throw, because it is API misuse rather than data: reaching this from inside a contact
|
|
23
|
+
// hook would run a whole nested step against the arrays the outer one is midway through.
|
|
24
|
+
export function stepPhysics3D(world, dt) {
|
|
25
|
+
if (steppingPhysics3DWorlds.has(world)) {
|
|
26
|
+
throw new Error('Cannot step a physics world recursively');
|
|
27
|
+
}
|
|
28
|
+
const config = world.config;
|
|
29
|
+
if (!isPhysics3DTimestepValid(dt) ||
|
|
30
|
+
!isPhysics3DSubstepsValid(config) ||
|
|
31
|
+
!isPhysics3DVelocityIterationsValid(config) ||
|
|
32
|
+
!isPhysics3DPositionIterationsValid(config) ||
|
|
33
|
+
!isPhysics3DSolverConfigValid(config) ||
|
|
34
|
+
!isPhysics3DGravityValid(world) ||
|
|
35
|
+
!isPhysics3DBodyStateValid(world) ||
|
|
36
|
+
!isPhysics3DContactStateValid(world) ||
|
|
37
|
+
!isPhysics3DJointStateValid(world)) {
|
|
38
|
+
// The one place the silent decline is observable from outside. The seam takes the world and the
|
|
39
|
+
// timestep rather than a reason, so the guard asks `explainPhysics3DStep` for ALL of them — a world
|
|
40
|
+
// with two faults reported one at a time would be repaired one frame at a time.
|
|
41
|
+
physics3DStepGuard?.(world, dt);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// The flag is set and cleared in exactly one place, whatever the body does or throws. It is what makes
|
|
45
|
+
// every world lifecycle and joint lifecycle helper reject a call from inside a contact hook: the hook's
|
|
46
|
+
// sole mutation surface is the contact fields its contract names.
|
|
47
|
+
steppingPhysics3DWorlds.add(world);
|
|
48
|
+
try {
|
|
49
|
+
stepValidatedPhysics3D(world, dt);
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
steppingPhysics3DWorlds.delete(world);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// One sub-interval of a step: integrate velocities, solve the constraints, integrate poses, repair
|
|
56
|
+
// penetration.
|
|
57
|
+
//
|
|
58
|
+
// Exported because the solver ruling requires the step to ship as a composition of named functions rather
|
|
59
|
+
// than a monolith. A caller assembling its own loop wants exactly this piece, and a second solver would
|
|
60
|
+
// replace this while `stepPhysics3D` above it stays as it is.
|
|
61
|
+
//
|
|
62
|
+
// The substep loop is the OUTER loop, which is the whole reason this is a separate function. A solver
|
|
63
|
+
// that integrates once and then iterates cannot be turned into one that substeps without restructuring
|
|
64
|
+
// everything that reads the step, so the shape is reserved from the first release even at `substeps: 1`.
|
|
65
|
+
//
|
|
66
|
+
// The ordering is not arbitrary, and one piece of it is a trap. `refreshRigidBody3DWorldInertia` runs at
|
|
67
|
+
// the TOP, before the velocity integration reads the world tensor, and AGAIN once the poses have moved,
|
|
68
|
+
// before the position pass reads it. Integrating angular velocity against the previous sub-interval's
|
|
69
|
+
// world tensor is wrong in a way that shows only on a rotating asymmetric body — a slow, plausible
|
|
70
|
+
// precession no single-step assertion catches.
|
|
71
|
+
export function stepPhysics3DInterval(world, dt) {
|
|
72
|
+
const sequential = world.config.sequentialImpulse;
|
|
73
|
+
forEachSolveIslandBody(world, refreshRigidBody3DWorldInertia);
|
|
74
|
+
forEachSolveIslandBody(world, (body) => integrateRigidBody3DVelocity(body, world.gravityX, world.gravityY, world.gravityZ, dt));
|
|
75
|
+
preparePhysics3DContactConstraints(world);
|
|
76
|
+
forEachSolveIslandJoint(world, (joint, solver) => solver.prepare(world, joint, dt));
|
|
77
|
+
if (sequential.warmStarting) {
|
|
78
|
+
warmStartPhysics3DContacts(world);
|
|
79
|
+
// Warm starting is a per-KIND capability as well as a per-world preference. A kind that declares no
|
|
80
|
+
// `warmStart` never reapplies its accumulator, so that accumulator has to be cleared even while the
|
|
81
|
+
// world IS warm starting — an impulse that is never reapplied must be cleared, or it is neither warm
|
|
82
|
+
// nor cold, and it grows without ever acting.
|
|
83
|
+
forEachSolveIslandJoint(world, (joint, solver) => {
|
|
84
|
+
if (solver.warmStart !== undefined)
|
|
85
|
+
solver.warmStart(world, joint);
|
|
86
|
+
else
|
|
87
|
+
clearJointAccumulators(joint, solver);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// Contacts need no clearing here: `preparePhysics3DContactConstraints` carries an accumulator across
|
|
92
|
+
// only when the flag is set, so the constraint it just built is already cold.
|
|
93
|
+
forEachSolveIslandJoint(world, clearJointAccumulators);
|
|
94
|
+
}
|
|
95
|
+
// Joints and contacts share one iteration count and one interleaved pass. Solving them in separate
|
|
96
|
+
// passes would let each undo the other's correction — a hinge under load creeps if the contacts beneath
|
|
97
|
+
// it get a whole pass to themselves between joint iterations.
|
|
98
|
+
for (let iteration = 0; iteration < sequential.velocityIterations; iteration += 1) {
|
|
99
|
+
forEachSolveIslandJoint(world, (joint, solver) => solver.solve(world, joint, dt));
|
|
100
|
+
solvePhysics3DContactVelocities(world);
|
|
101
|
+
}
|
|
102
|
+
forEachSolveIslandPose(world, dt);
|
|
103
|
+
for (let iteration = 0; iteration < sequential.positionIterations; iteration += 1) {
|
|
104
|
+
solvePhysics3DContactPositions(world);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function clearJointAccumulators(joint, solver) {
|
|
108
|
+
solver.clearAccumulatedImpulses?.(joint);
|
|
109
|
+
joint.impulse0 = 0;
|
|
110
|
+
joint.impulse1 = 0;
|
|
111
|
+
joint.impulse2 = 0;
|
|
112
|
+
joint.impulse3 = 0;
|
|
113
|
+
joint.impulse4 = 0;
|
|
114
|
+
joint.impulse5 = 0;
|
|
115
|
+
}
|
|
116
|
+
// Visits every body the solve islands admit, in island-major order.
|
|
117
|
+
//
|
|
118
|
+
// The workspace holds only awake, non-static bodies, so this is also the sleeping skip — and the skip is
|
|
119
|
+
// a COST saving rather than a behavioural one, which is worth having in writing: a sleeping body's
|
|
120
|
+
// velocity is zeroed when it falls asleep and nothing can hand it more, because any awake neighbour puts
|
|
121
|
+
// it in an awake island before this point. What the skip buys is that a settled thousand-body pile costs
|
|
122
|
+
// no integration at all, which is the entire reason sleep exists.
|
|
123
|
+
function forEachSolveIslandBody(world, visit) {
|
|
124
|
+
for (let island = 0; island < world.solveIslandRoots.length; island += 1) {
|
|
125
|
+
const start = world.solveIslandBodyStarts[island];
|
|
126
|
+
const end = start + world.solveIslandBodyCounts[island];
|
|
127
|
+
for (let at = start; at < end; at += 1)
|
|
128
|
+
visit(world.bodies[world.solveIslandBodyIndices[at]]);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Visits every joint the solve islands admit, paired with its registered solver. The workspace already
|
|
132
|
+
// excluded unregistered kinds and sleeping islands, so the callback never has to ask again.
|
|
133
|
+
function forEachSolveIslandJoint(world, visit) {
|
|
134
|
+
for (let island = 0; island < world.solveIslandRoots.length; island += 1) {
|
|
135
|
+
const start = world.solveIslandJointStarts[island];
|
|
136
|
+
const end = start + world.solveIslandJointCounts[island];
|
|
137
|
+
for (let at = start; at < end; at += 1) {
|
|
138
|
+
const joint = world.joints[world.solveIslandJointIndices[at]];
|
|
139
|
+
const solver = world.jointSolvers.get(joint.kind);
|
|
140
|
+
if (solver !== undefined)
|
|
141
|
+
visit(joint, solver);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Moves every awake body by its solved velocity, then refreshes the world inertia the position pass is
|
|
146
|
+
// about to read. Two passes rather than one, because a body's pose must not move between another body's
|
|
147
|
+
// integration and its own: a single fused loop would have the second body's constraint arms measured
|
|
148
|
+
// against a world the first body had already left.
|
|
149
|
+
function forEachSolveIslandPose(world, dt) {
|
|
150
|
+
forEachSolveIslandBody(world, (body) => integrateRigidBody3DPose(body, dt));
|
|
151
|
+
forEachSolveIslandBody(world, refreshRigidBody3DWorldInertia);
|
|
152
|
+
}
|
|
153
|
+
function restoreContactHookFields(contact, friction, restitution, enabled, sensor) {
|
|
154
|
+
contact.friction = friction;
|
|
155
|
+
contact.restitution = restitution;
|
|
156
|
+
contact.enabled = enabled;
|
|
157
|
+
contact.sensor = sensor;
|
|
158
|
+
}
|
|
159
|
+
// Runs a contact hook over every resolvable contact, putting back the fields it may touch if it
|
|
160
|
+
// misbehaves.
|
|
161
|
+
//
|
|
162
|
+
// Sensors are skipped, because they produce no constraint to solve and there is nothing for a hook to
|
|
163
|
+
// adjust. A hook that throws, or that leaves a contact the step cannot use, has its four mutable fields
|
|
164
|
+
// restored before the failure propagates — otherwise a caller catching the error would resume against a
|
|
165
|
+
// world the hook half-edited.
|
|
166
|
+
function runPhysics3DContactHook(world, hook, phase) {
|
|
167
|
+
if (hook === null)
|
|
168
|
+
return;
|
|
169
|
+
for (const contact of world.contacts) {
|
|
170
|
+
if (contact.sensor)
|
|
171
|
+
continue;
|
|
172
|
+
const friction = contact.friction;
|
|
173
|
+
const restitution = contact.restitution;
|
|
174
|
+
const enabled = contact.enabled;
|
|
175
|
+
const sensor = contact.sensor;
|
|
176
|
+
try {
|
|
177
|
+
hook(world, contact);
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
restoreContactHookFields(contact, friction, restitution, enabled, sensor);
|
|
181
|
+
throw error;
|
|
182
|
+
}
|
|
183
|
+
if (!isPhysics3DContactValid(contact)) {
|
|
184
|
+
restoreContactHookFields(contact, friction, restitution, enabled, sensor);
|
|
185
|
+
throw new Error(`Physics3D ${phase} hook produced invalid contact state`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// Expresses every cached impulse in the interval it is about to be reapplied over.
|
|
190
|
+
//
|
|
191
|
+
// An accumulated impulse has force-times-time units. Reusing one unchanged across a different interval
|
|
192
|
+
// applies the wrong force before the first iteration can correct it, which presents as a stack or a motor
|
|
193
|
+
// kicking whenever a frame changes cadence. The comparison is against the previous SUB-interval rather
|
|
194
|
+
// than the previous whole step, because a sub-interval's iterations are what built the cache — which is
|
|
195
|
+
// also why changing `substeps` between steps rescales correctly rather than silently by the wrong factor.
|
|
196
|
+
//
|
|
197
|
+
// A non-finite ratio clears the cache rather than seeding infinity from two otherwise-valid timesteps.
|
|
198
|
+
function scalePhysics3DWarmStartCaches(world, dt) {
|
|
199
|
+
const previous = world.previousTimestep;
|
|
200
|
+
if (!(previous > 0) || previous === dt)
|
|
201
|
+
return;
|
|
202
|
+
const divided = dt / previous;
|
|
203
|
+
const timestepRatio = Number.isFinite(divided) ? divided : 0;
|
|
204
|
+
for (const constraint of world.solver.constraints) {
|
|
205
|
+
for (let i = 0; i < constraint.pointCount; i += 1) {
|
|
206
|
+
const point = constraint.points[i];
|
|
207
|
+
point.normalImpulse *= timestepRatio;
|
|
208
|
+
point.tangentImpulse0 *= timestepRatio;
|
|
209
|
+
point.tangentImpulse1 *= timestepRatio;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
for (const joint of world.joints) {
|
|
213
|
+
joint.impulse0 *= timestepRatio;
|
|
214
|
+
joint.impulse1 *= timestepRatio;
|
|
215
|
+
joint.impulse2 *= timestepRatio;
|
|
216
|
+
joint.impulse3 *= timestepRatio;
|
|
217
|
+
joint.impulse4 *= timestepRatio;
|
|
218
|
+
joint.impulse5 *= timestepRatio;
|
|
219
|
+
world.jointSolvers.get(joint.kind)?.scaleAccumulatedImpulses?.(joint, timestepRatio);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// The body of one step whose preconditions already hold.
|
|
223
|
+
function stepValidatedPhysics3D(world, dt) {
|
|
224
|
+
const substepDt = dt / world.config.substeps;
|
|
225
|
+
// Pre-solve runs before anything is scaled or prepared, so a hook that disables a contact for this step
|
|
226
|
+
// does so before the constraint that would have resolved it is built.
|
|
227
|
+
runPhysics3DContactHook(world, world.contactHooks.preSolve, 'pre-solve');
|
|
228
|
+
// Scale only after pre-solve succeeds. A callback may throw, and scaling first would leave the cache
|
|
229
|
+
// expressed in the new interval while `previousTimestep` still described the old one; a retry would
|
|
230
|
+
// then scale an already-scaled cache a second time.
|
|
231
|
+
scalePhysics3DWarmStartCaches(world, substepDt);
|
|
232
|
+
// Sleep is decided HERE — before anything integrates — which is what makes every wake transition cost
|
|
233
|
+
// zero steps. A body woken by a force, by a new neighbour, or by the caller writing a velocity is awake
|
|
234
|
+
// in time to be integrated by this same step; deciding after integration would skip it once and move it
|
|
235
|
+
// a step late. It is decided once per STEP rather than per sub-interval, because stillness measured over
|
|
236
|
+
// a fraction of a frame is a different and much twitchier quantity than the one `timeToSleep` names.
|
|
237
|
+
updatePhysics3DSleep(world, dt);
|
|
238
|
+
buildPhysics3DSolveIslands(world);
|
|
239
|
+
for (let substep = 0; substep < world.config.substeps; substep += 1) {
|
|
240
|
+
stepPhysics3DInterval(world, substepDt);
|
|
241
|
+
}
|
|
242
|
+
for (const body of world.bodies)
|
|
243
|
+
clearRigidBody3DForces(body);
|
|
244
|
+
world.previousTimestep = substepDt;
|
|
245
|
+
// Post-solve observes a committed step. A hook that throws here cannot prevent pose integration, force
|
|
246
|
+
// cleanup, or the timestep agreement above, so the next call never resumes a half-finished step.
|
|
247
|
+
runPhysics3DContactHook(world, world.contactHooks.postSolve, 'post-solve');
|
|
248
|
+
}
|
|
249
|
+
let physics3DStepGuard = null;
|
|
250
|
+
//# sourceMappingURL=step.js.map
|
package/dist/step.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step.js","sourceRoot":"","sources":["../src/step.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Physics3DContact, Physics3DSolverConfig, Physics3DWorld } from '@flighthq/types/contract';
|
|
2
|
+
export declare function isPhysics3DBodyStateValid(world: Readonly<Physics3DWorld>): boolean;
|
|
3
|
+
export declare function isPhysics3DContactStateValid(world: Readonly<Physics3DWorld>): boolean;
|
|
4
|
+
export declare function isPhysics3DContactValid(contact: Readonly<Physics3DContact>): boolean;
|
|
5
|
+
export declare function isPhysics3DGravityValid(world: Readonly<Physics3DWorld>): boolean;
|
|
6
|
+
export declare function isPhysics3DJointStateValid(world: Readonly<Physics3DWorld>): boolean;
|
|
7
|
+
export declare function isPhysics3DPositionIterationsValid(config: Readonly<Physics3DSolverConfig>): boolean;
|
|
8
|
+
export declare function isPhysics3DSolverConfigValid(config: Readonly<Physics3DSolverConfig>): boolean;
|
|
9
|
+
export declare function isPhysics3DSubstepsValid(config: Readonly<Physics3DSolverConfig>): boolean;
|
|
10
|
+
export declare function isPhysics3DTimestepValid(dt: number): boolean;
|
|
11
|
+
export declare function isPhysics3DVelocityIterationsValid(config: Readonly<Physics3DSolverConfig>): boolean;
|
|
12
|
+
//# sourceMappingURL=stepValidation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stepValidation.d.ts","sourceRoot":"","sources":["../src/stepValidation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAEhB,qBAAqB,EACrB,cAAc,EAEf,MAAM,0BAA0B,CAAC;AAclC,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,OAAO,CAMlF;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,OAAO,CAKrF;AAID,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,OAAO,CA6BpF;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,OAAO,CAEhF;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,OAAO,CAKnF;AAED,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,OAAO,CAGnG;AAKD,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,OAAO,CAsB7F;AAID,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,OAAO,CAEzF;AAED,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,OAAO,CAGnG"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// The preconditions one explicit step needs to be meaningful, each asked as its own question.
|
|
2
|
+
//
|
|
3
|
+
// Separate predicates rather than one `canStep`, because they are the rows of `Physics3DStepExplanation`
|
|
4
|
+
// and a caller diagnosing a world that will not advance needs to know WHICH one failed. `stepPhysics3D`
|
|
5
|
+
// asks all of them and returns silently on any false; `explainPhysics3DStep` asks the same ones and
|
|
6
|
+
// reports. That is the diagnostics inversion — the step carries no messages, and the explain seam is
|
|
7
|
+
// separately importable so a shipping build that never asks never links it.
|
|
8
|
+
//
|
|
9
|
+
// A world that fails one of these is not an error to throw on: a NaN velocity, a zero timestep, or a
|
|
10
|
+
// negative iteration count is a state a caller can reach by writing a field, and a throw from inside the
|
|
11
|
+
// step would take down a frame loop for something the caller can inspect and repair.
|
|
12
|
+
export function isPhysics3DBodyStateValid(world) {
|
|
13
|
+
if (!Number.isSafeInteger(world.nextBodyIndex) || world.nextBodyIndex < 0)
|
|
14
|
+
return false;
|
|
15
|
+
for (const body of world.bodies) {
|
|
16
|
+
if (!isRigidBody3DStateValid(body) || world.bodyByIndex.get(body.index) !== body)
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
export function isPhysics3DContactStateValid(world) {
|
|
22
|
+
for (const contact of world.contacts) {
|
|
23
|
+
if (!isPhysics3DContactValid(contact))
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
// Also the post-hook check: a pre-solve or post-solve callback may write contact fields, and this is what
|
|
29
|
+
// says whether what it wrote is still steppable.
|
|
30
|
+
export function isPhysics3DContactValid(contact) {
|
|
31
|
+
if (!Number.isSafeInteger(contact.bodyA) ||
|
|
32
|
+
!Number.isSafeInteger(contact.bodyB) ||
|
|
33
|
+
!Number.isSafeInteger(contact.pointCount) ||
|
|
34
|
+
contact.pointCount < 0 ||
|
|
35
|
+
contact.pointCount > contact.points.length ||
|
|
36
|
+
!Number.isFinite(contact.normalX) ||
|
|
37
|
+
!Number.isFinite(contact.normalY) ||
|
|
38
|
+
!Number.isFinite(contact.normalZ) ||
|
|
39
|
+
!Number.isFinite(contact.friction) ||
|
|
40
|
+
contact.friction < 0 ||
|
|
41
|
+
!Number.isFinite(contact.restitution) ||
|
|
42
|
+
contact.restitution < 0 ||
|
|
43
|
+
typeof contact.enabled !== 'boolean' ||
|
|
44
|
+
typeof contact.sensor !== 'boolean' ||
|
|
45
|
+
typeof contact.touching !== 'boolean') {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
for (let i = 0; i < contact.pointCount; i += 1) {
|
|
49
|
+
const point = contact.points[i];
|
|
50
|
+
if (point === undefined)
|
|
51
|
+
return false;
|
|
52
|
+
for (const key in point) {
|
|
53
|
+
const value = point[key];
|
|
54
|
+
if (typeof value === 'number' && !Number.isFinite(value))
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
export function isPhysics3DGravityValid(world) {
|
|
61
|
+
return Number.isFinite(world.gravityX) && Number.isFinite(world.gravityY) && Number.isFinite(world.gravityZ);
|
|
62
|
+
}
|
|
63
|
+
export function isPhysics3DJointStateValid(world) {
|
|
64
|
+
for (const joint of world.joints) {
|
|
65
|
+
if (!isPhysics3DJointValid(joint))
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
export function isPhysics3DPositionIterationsValid(config) {
|
|
71
|
+
const iterations = config.sequentialImpulse.positionIterations;
|
|
72
|
+
return Number.isSafeInteger(iterations) && iterations >= 0;
|
|
73
|
+
}
|
|
74
|
+
// The solver-independent knobs plus the sequential-impulse block. Iteration counts and `substeps` are
|
|
75
|
+
// asked separately, because they are the three a caller is most likely to have tuned by hand and the
|
|
76
|
+
// explanation names each of them.
|
|
77
|
+
export function isPhysics3DSolverConfigValid(config) {
|
|
78
|
+
const sequential = config.sequentialImpulse;
|
|
79
|
+
return (typeof config.allowSleeping === 'boolean' &&
|
|
80
|
+
Number.isFinite(config.sleepLinearThreshold) &&
|
|
81
|
+
config.sleepLinearThreshold >= 0 &&
|
|
82
|
+
Number.isFinite(config.sleepAngularThreshold) &&
|
|
83
|
+
config.sleepAngularThreshold >= 0 &&
|
|
84
|
+
Number.isFinite(config.timeToSleep) &&
|
|
85
|
+
config.timeToSleep >= 0 &&
|
|
86
|
+
typeof config.continuousCollision === 'boolean' &&
|
|
87
|
+
Number.isSafeInteger(config.maxCcdSubsteps) &&
|
|
88
|
+
config.maxCcdSubsteps >= 0 &&
|
|
89
|
+
Number.isFinite(sequential.penetrationSlop) &&
|
|
90
|
+
sequential.penetrationSlop >= 0 &&
|
|
91
|
+
Number.isFinite(sequential.positionCorrection) &&
|
|
92
|
+
sequential.positionCorrection >= 0 &&
|
|
93
|
+
sequential.positionCorrection <= 1 &&
|
|
94
|
+
Number.isFinite(sequential.restitutionThreshold) &&
|
|
95
|
+
sequential.restitutionThreshold >= 0 &&
|
|
96
|
+
typeof sequential.warmStarting === 'boolean');
|
|
97
|
+
}
|
|
98
|
+
// At least one, because `substeps` divides the timestep and the step runs the loop that many times. Zero
|
|
99
|
+
// would advance nothing while reporting a completed step, which is worse than declining to step at all.
|
|
100
|
+
export function isPhysics3DSubstepsValid(config) {
|
|
101
|
+
return Number.isSafeInteger(config.substeps) && config.substeps >= 1;
|
|
102
|
+
}
|
|
103
|
+
export function isPhysics3DTimestepValid(dt) {
|
|
104
|
+
return Number.isFinite(dt) && dt > 0;
|
|
105
|
+
}
|
|
106
|
+
export function isPhysics3DVelocityIterationsValid(config) {
|
|
107
|
+
const iterations = config.sequentialImpulse.velocityIterations;
|
|
108
|
+
return Number.isSafeInteger(iterations) && iterations >= 0;
|
|
109
|
+
}
|
|
110
|
+
function isPhysics3DJointValid(joint) {
|
|
111
|
+
if (typeof joint.kind !== 'string' ||
|
|
112
|
+
joint.kind.length === 0 ||
|
|
113
|
+
!Number.isSafeInteger(joint.bodyA) ||
|
|
114
|
+
!Number.isSafeInteger(joint.bodyB) ||
|
|
115
|
+
typeof joint.collideConnected !== 'boolean') {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
// Every numeric field, whatever the kind added — a limit, a motor speed, a frame component. Walking the
|
|
119
|
+
// object rather than a fixed key list is what makes this cover a user's own joint kind, which is the
|
|
120
|
+
// point of an open registry.
|
|
121
|
+
for (const key in joint) {
|
|
122
|
+
const value = joint[key];
|
|
123
|
+
if (typeof value === 'number' && !Number.isFinite(value))
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
function isRigidBody3DStateValid(body) {
|
|
129
|
+
if (!Number.isSafeInteger(body.index) ||
|
|
130
|
+
body.index < 0 ||
|
|
131
|
+
(body.type !== 'dynamic' && body.type !== 'kinematic' && body.type !== 'static') ||
|
|
132
|
+
typeof body.fixedRotation !== 'boolean' ||
|
|
133
|
+
typeof body.bullet !== 'boolean' ||
|
|
134
|
+
typeof body.sleeping !== 'boolean' ||
|
|
135
|
+
typeof body.sleepEnabled !== 'boolean' ||
|
|
136
|
+
!Number.isFinite(body.sleepTimer) ||
|
|
137
|
+
body.sleepTimer < 0 ||
|
|
138
|
+
!Number.isFinite(body.linearDamping) ||
|
|
139
|
+
body.linearDamping < 0 ||
|
|
140
|
+
!Number.isFinite(body.angularDamping) ||
|
|
141
|
+
body.angularDamping < 0 ||
|
|
142
|
+
!Number.isFinite(body.gravityScale) ||
|
|
143
|
+
!Number.isFinite(body.mass) ||
|
|
144
|
+
body.mass < 0 ||
|
|
145
|
+
!Number.isFinite(body.inverseMass) ||
|
|
146
|
+
body.inverseMass < 0) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
for (const key of rigidBody3DFiniteKeys) {
|
|
150
|
+
if (!Number.isFinite(body[key]))
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
// Every field that has to be a real number for the step to mean anything: the pose, the velocities, the
|
|
156
|
+
// accumulators, the centre of mass, and all three inertia tensors. The world tensor is derived and is
|
|
157
|
+
// included anyway — it is what every constraint row multiplies by, so a NaN there reaches both bodies of
|
|
158
|
+
// every contact and joint within one substep.
|
|
159
|
+
const rigidBody3DFiniteKeys = [
|
|
160
|
+
'x',
|
|
161
|
+
'y',
|
|
162
|
+
'z',
|
|
163
|
+
'orientationX',
|
|
164
|
+
'orientationY',
|
|
165
|
+
'orientationZ',
|
|
166
|
+
'orientationW',
|
|
167
|
+
'velocityX',
|
|
168
|
+
'velocityY',
|
|
169
|
+
'velocityZ',
|
|
170
|
+
'angularVelocityX',
|
|
171
|
+
'angularVelocityY',
|
|
172
|
+
'angularVelocityZ',
|
|
173
|
+
'forceX',
|
|
174
|
+
'forceY',
|
|
175
|
+
'forceZ',
|
|
176
|
+
'torqueX',
|
|
177
|
+
'torqueY',
|
|
178
|
+
'torqueZ',
|
|
179
|
+
'centerX',
|
|
180
|
+
'centerY',
|
|
181
|
+
'centerZ',
|
|
182
|
+
'inertiaXX',
|
|
183
|
+
'inertiaYY',
|
|
184
|
+
'inertiaZZ',
|
|
185
|
+
'inertiaXY',
|
|
186
|
+
'inertiaXZ',
|
|
187
|
+
'inertiaYZ',
|
|
188
|
+
'inverseInertiaXX',
|
|
189
|
+
'inverseInertiaYY',
|
|
190
|
+
'inverseInertiaZZ',
|
|
191
|
+
'inverseInertiaXY',
|
|
192
|
+
'inverseInertiaXZ',
|
|
193
|
+
'inverseInertiaYZ',
|
|
194
|
+
'inverseInertiaWorldXX',
|
|
195
|
+
'inverseInertiaWorldYY',
|
|
196
|
+
'inverseInertiaWorldZZ',
|
|
197
|
+
'inverseInertiaWorldXY',
|
|
198
|
+
'inverseInertiaWorldXZ',
|
|
199
|
+
'inverseInertiaWorldYZ',
|
|
200
|
+
];
|
|
201
|
+
//# sourceMappingURL=stepValidation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stepValidation.js","sourceRoot":"","sources":["../src/stepValidation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const TENSOR_XX = 0;
|
|
2
|
+
export declare const TENSOR_YY = 1;
|
|
3
|
+
export declare const TENSOR_ZZ = 2;
|
|
4
|
+
export declare const TENSOR_XY = 3;
|
|
5
|
+
export declare const TENSOR_XZ = 4;
|
|
6
|
+
export declare const TENSOR_YZ = 5;
|
|
7
|
+
export declare function applySymmetricTensor(tensor: Readonly<ArrayLike<number>>, vX: number, vY: number, vZ: number, out: number[]): void;
|
|
8
|
+
export declare function inverseSymmetricTensor(tensor: Readonly<ArrayLike<number>>, out: number[]): boolean;
|
|
9
|
+
export declare function rotateSymmetricTensor(tensor: Readonly<ArrayLike<number>>, quaternionX: number, quaternionY: number, quaternionZ: number, quaternionW: number, out: number[]): void;
|
|
10
|
+
export declare function translateSymmetricTensor(tensor: Readonly<ArrayLike<number>>, mass: number, dX: number, dY: number, dZ: number, out: number[]): void;
|
|
11
|
+
//# sourceMappingURL=symmetricTensor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"symmetricTensor.d.ts","sourceRoot":"","sources":["../src/symmetricTensor.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,SAAS,IAAI,CAAC;AAC3B,eAAO,MAAM,SAAS,IAAI,CAAC;AAC3B,eAAO,MAAM,SAAS,IAAI,CAAC;AAC3B,eAAO,MAAM,SAAS,IAAI,CAAC;AAC3B,eAAO,MAAM,SAAS,IAAI,CAAC;AAC3B,eAAO,MAAM,SAAS,IAAI,CAAC;AAI3B,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EACnC,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,MAAM,EAAE,GACZ,IAAI,CAWN;AAUD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAiClG;AAQD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EACnC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,EAAE,GACZ,IAAI,CAmDN;AAUD,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EACnC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,MAAM,EAAE,GACZ,IAAI,CAcN"}
|