@opsydyn/effect-three-rapier 0.3.0 → 0.6.4

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/index.js CHANGED
@@ -1,13 +1,105 @@
1
1
  // src/index.ts
2
2
  import RAPIER from "@dimforge/rapier3d-compat";
3
+
4
+ // src/engine.ts
3
5
  import { interactionBits } from "@opsydyn/effect-three";
6
+
7
+ // src/snapshot.ts
8
+ var format = 1;
9
+ var encoder = new TextEncoder;
10
+ var decoder = new TextDecoder;
11
+ var writeSnapshot = (index, world) => {
12
+ const parts = [Uint8Array.of(format)];
13
+ const count = (value) => {
14
+ const bytes = new Uint8Array(4);
15
+ new DataView(bytes.buffer).setUint32(0, value, true);
16
+ parts.push(bytes);
17
+ };
18
+ const handle = (value) => {
19
+ const bytes = new Uint8Array(8);
20
+ new DataView(bytes.buffer).setFloat64(0, value, true);
21
+ parts.push(bytes);
22
+ };
23
+ const text = (value) => {
24
+ const bytes = encoder.encode(value);
25
+ count(bytes.length);
26
+ parts.push(bytes);
27
+ };
28
+ count(index.bodies.length);
29
+ for (const body of index.bodies) {
30
+ text(body.key);
31
+ handle(body.handle);
32
+ count(body.colliders.length);
33
+ for (const collider of body.colliders) {
34
+ handle(collider.handle);
35
+ text(collider.part === undefined ? "" : `:${collider.part}`);
36
+ }
37
+ }
38
+ count(index.joints.length);
39
+ for (const joint of index.joints) {
40
+ text(joint.id);
41
+ handle(joint.handle);
42
+ text(joint.a);
43
+ text(joint.b);
44
+ }
45
+ parts.push(world);
46
+ const out = new Uint8Array(parts.reduce((length, part) => length + part.length, 0));
47
+ let at = 0;
48
+ for (const part of parts) {
49
+ out.set(part, at);
50
+ at += part.length;
51
+ }
52
+ return out;
53
+ };
54
+ var readSnapshot = (snapshot) => {
55
+ if (snapshot[0] !== format)
56
+ throw new Error("Not a snapshot of an effect-three Rapier world");
57
+ const view = new DataView(snapshot.buffer, snapshot.byteOffset, snapshot.byteLength);
58
+ let at = 1;
59
+ const count = () => {
60
+ const value = view.getUint32(at, true);
61
+ at += 4;
62
+ return value;
63
+ };
64
+ const handle = () => {
65
+ const value = view.getFloat64(at, true);
66
+ at += 8;
67
+ return value;
68
+ };
69
+ const text = () => {
70
+ const length = count();
71
+ const value = decoder.decode(snapshot.subarray(at, at + length));
72
+ at += length;
73
+ return value;
74
+ };
75
+ function collider() {
76
+ const colliderHandle = handle();
77
+ const part = text();
78
+ return part === "" ? { handle: colliderHandle } : { handle: colliderHandle, part: part.slice(1) };
79
+ }
80
+ function body() {
81
+ const key = text();
82
+ const bodyHandle = handle();
83
+ return { key, handle: bodyHandle, colliders: Array.from({ length: count() }, collider) };
84
+ }
85
+ const bodies = Array.from({ length: count() }, body);
86
+ const joints = Array.from({ length: count() }, () => ({
87
+ id: text(),
88
+ handle: handle(),
89
+ a: text(),
90
+ b: text()
91
+ }));
92
+ return { index: { bodies, joints }, world: snapshot.subarray(at) };
93
+ };
94
+
95
+ // src/engine.ts
4
96
  var vector = ([x, y, z]) => ({ x, y, z });
5
97
  var rotation = ([x, y, z, w]) => ({ x, y, z, w });
6
- var bodyTypes = {
7
- dynamic: RAPIER.RigidBodyType.Dynamic,
8
- fixed: RAPIER.RigidBodyType.Fixed,
9
- kinematic: RAPIER.RigidBodyType.KinematicPositionBased
10
- };
98
+ var bodyType = (rapier, type) => ({
99
+ dynamic: rapier.RigidBodyType.Dynamic,
100
+ fixed: rapier.RigidBodyType.Fixed,
101
+ kinematic: rapier.RigidBodyType.KinematicPositionBased
102
+ })[type];
11
103
  var shapeDesc = (rapier, shape) => {
12
104
  switch (shape._tag) {
13
105
  case "Cuboid":
@@ -27,13 +119,13 @@ var shapeDesc = (rapier, shape) => {
27
119
  }
28
120
  };
29
121
  var colliderDesc = (rapier, collider) => shapeDesc(rapier, collider.shape).setTranslation(...collider.translation).setRotation(rotation(collider.rotation));
30
- var reporting = (colliders, body) => {
122
+ var reporting = (rapier, colliders, body) => {
31
123
  for (const collider of colliders) {
32
124
  if (body.contactForces === null) {
33
- collider.setActiveEvents(RAPIER.ActiveEvents.COLLISION_EVENTS);
125
+ collider.setActiveEvents(rapier.ActiveEvents.COLLISION_EVENTS);
34
126
  continue;
35
127
  }
36
- collider.setActiveEvents(RAPIER.ActiveEvents.COLLISION_EVENTS | RAPIER.ActiveEvents.CONTACT_FORCE_EVENTS);
128
+ collider.setActiveEvents(rapier.ActiveEvents.COLLISION_EVENTS | rapier.ActiveEvents.CONTACT_FORCE_EVENTS);
37
129
  collider.setContactForceEventThreshold(body.contactForces);
38
130
  }
39
131
  };
@@ -50,8 +142,8 @@ var surface = (colliders, body) => {
50
142
  collider.setSolverGroups(interactionBits(body.solverGroups));
51
143
  }
52
144
  };
53
- var motion = (rigidBody, body) => {
54
- rigidBody.setBodyType(bodyTypes[body.type], true);
145
+ var motion = (rapier, rigidBody, body) => {
146
+ rigidBody.setBodyType(bodyType(rapier, body.type), true);
55
147
  rigidBody.setLinearDamping(body.linearDamping);
56
148
  rigidBody.setAngularDamping(body.angularDamping);
57
149
  rigidBody.setGravityScale(body.gravityScale, true);
@@ -59,13 +151,13 @@ var motion = (rigidBody, body) => {
59
151
  };
60
152
  var limitsOf = (joint) => joint.kind._tag === "Revolute" || joint.kind._tag === "Prismatic" ? joint.kind.limits : null;
61
153
  var motorOf = (joint) => joint.kind._tag === "Revolute" || joint.kind._tag === "Prismatic" ? joint.kind.motor : null;
62
- var drive = (made, motor) => {
63
- if (motor !== null && made instanceof RAPIER.UnitImpulseJoint) {
154
+ var drive = (rapier, made, motor) => {
155
+ if (motor !== null && made instanceof rapier.UnitImpulseJoint) {
64
156
  made.configureMotor(motor.position, motor.velocity, motor.stiffness, motor.damping);
65
157
  }
66
158
  };
67
- var limit = (made, limits) => {
68
- if (limits !== null && made instanceof RAPIER.UnitImpulseJoint)
159
+ var limit = (rapier, made, limits) => {
160
+ if (limits !== null && made instanceof rapier.UnitImpulseJoint)
69
161
  made.setLimits(...limits);
70
162
  };
71
163
  var jointData = (rapier, joint) => {
@@ -93,18 +185,26 @@ var pair = (a, b) => ({
93
185
  ...a.part === undefined ? {} : { aPart: a.part },
94
186
  ...b.part === undefined ? {} : { bPart: b.part }
95
187
  });
96
- var createWorld = (rapier) => (initial) => {
97
- const world = new rapier.World(vector(initial.gravity));
188
+ var hostWorld = (rapier) => (world, index = { bodies: [], joints: [] }) => {
98
189
  const events = new rapier.EventQueue(true);
99
- const bodies = new Map;
100
- const keysByCollider = new Map;
101
- const joints = new Map;
190
+ const bodies = new Map(index.bodies.map((body) => [
191
+ body.key,
192
+ {
193
+ rigidBody: world.getRigidBody(body.handle),
194
+ colliders: body.colliders.map((collider) => world.getCollider(collider.handle))
195
+ }
196
+ ]));
197
+ const keysByCollider = new Map(index.bodies.flatMap(({ key, colliders }) => colliders.map(({ handle, part }) => [handle, part === undefined ? { key } : { key, part }])));
198
+ const joints = new Map(index.joints.map(({ id, handle, a, b }) => [
199
+ id,
200
+ { joint: world.getImpulseJoint(handle), a, b }
201
+ ]));
102
202
  const add = (key, body, colliders, pose) => {
103
- const desc = new rapier.RigidBodyDesc(bodyTypes[body.type]).setTranslation(...pose.position).setRotation(rotation(pose.quaternion)).setLinvel(...body.linearVelocity).setAngvel(vector(body.angularVelocity)).setLinearDamping(body.linearDamping).setAngularDamping(body.angularDamping).setGravityScale(body.gravityScale).setCcdEnabled(body.ccd);
203
+ const desc = new rapier.RigidBodyDesc(bodyType(rapier, body.type)).setTranslation(...pose.position).setRotation(rotation(pose.quaternion)).setLinvel(...body.linearVelocity).setAngvel(vector(body.angularVelocity)).setLinearDamping(body.linearDamping).setAngularDamping(body.angularDamping).setGravityScale(body.gravityScale).setCcdEnabled(body.ccd);
104
204
  const rigidBody = world.createRigidBody(desc);
105
205
  const made = colliders.map((collider) => world.createCollider(colliderDesc(rapier, collider), rigidBody));
106
206
  surface(made, body);
107
- reporting(made, body);
207
+ reporting(rapier, made, body);
108
208
  bodies.set(key, { rigidBody, colliders: made });
109
209
  made.forEach((collider, i) => {
110
210
  const part = colliders[i]?.part;
@@ -129,8 +229,8 @@ var createWorld = (rapier) => (initial) => {
129
229
  if (first === undefined || second === undefined)
130
230
  return;
131
231
  const made = world.createImpulseJoint(jointData(rapier, joint), first.rigidBody, second.rigidBody, true);
132
- limit(made, limitsOf(joint));
133
- drive(made, motorOf(joint));
232
+ limit(rapier, made, limitsOf(joint));
233
+ drive(rapier, made, motorOf(joint));
134
234
  made.setContactsEnabled(joint.contacts);
135
235
  joints.set(id, { joint: made, a, b });
136
236
  };
@@ -168,6 +268,10 @@ var createWorld = (rapier) => (initial) => {
168
268
  });
169
269
  }
170
270
  const drainForces = () => events.drainContactForceEvents(recordForce);
271
+ function indexed(collider) {
272
+ const part = keysByCollider.get(collider.handle)?.part;
273
+ return part === undefined ? { handle: collider.handle } : { handle: collider.handle, part };
274
+ }
171
275
  return {
172
276
  configure: (physics) => {
173
277
  world.gravity = vector(physics.gravity);
@@ -177,9 +281,9 @@ var createWorld = (rapier) => (initial) => {
177
281
  const held = bodies.get(key);
178
282
  if (held === undefined)
179
283
  return;
180
- motion(held.rigidBody, body);
284
+ motion(rapier, held.rigidBody, body);
181
285
  surface(held.colliders, body);
182
- reporting(held.colliders, body);
286
+ reporting(rapier, held.colliders, body);
183
287
  },
184
288
  teleport: (key, pose) => {
185
289
  const held = bodies.get(key);
@@ -233,6 +337,19 @@ var createWorld = (rapier) => (initial) => {
233
337
  }
234
338
  return false;
235
339
  },
340
+ snapshot: () => writeSnapshot({
341
+ bodies: [...bodies].map(([key, held]) => ({
342
+ key,
343
+ handle: held.rigidBody.handle,
344
+ colliders: held.colliders.map(indexed)
345
+ })),
346
+ joints: [...joints].map(([id, { joint, a, b }]) => ({
347
+ id,
348
+ handle: joint.handle,
349
+ a,
350
+ b
351
+ }))
352
+ }, world.takeSnapshot()),
236
353
  dispose: () => {
237
354
  bodies.clear();
238
355
  keysByCollider.clear();
@@ -242,13 +359,29 @@ var createWorld = (rapier) => (initial) => {
242
359
  }
243
360
  };
244
361
  };
362
+ var engineOf = (rapier) => {
363
+ const host = hostWorld(rapier);
364
+ return {
365
+ createWorld: (initial) => host(new rapier.World(vector(initial.gravity))),
366
+ restoreWorld: (_physics, snapshot) => {
367
+ const { index, world } = readSnapshot(snapshot);
368
+ return {
369
+ world: host(rapier.World.restoreSnapshot(world), index),
370
+ bodies: index.bodies.map((body) => body.key),
371
+ joints: index.joints.map((joint) => joint.id)
372
+ };
373
+ }
374
+ };
375
+ };
376
+
377
+ // src/index.ts
245
378
  var loadRapier = async () => {
246
379
  await RAPIER.init();
247
- return { createWorld: createWorld(RAPIER) };
380
+ return engineOf(RAPIER);
248
381
  };
249
382
  export {
250
383
  loadRapier
251
384
  };
252
385
 
253
- //# debugId=1F8003691871788E64756E2164756E21
386
+ //# debugId=BF71FE688A93448964756E2164756E21
254
387
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/index.ts"],
3
+ "sources": ["../src/index.ts", "../src/engine.ts", "../src/snapshot.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * Rapier physics for `@opsydyn/effect-three`: a `PhysicsEngine` that the scene graph\n * steps. Load it once, before making the environment, and pass it on:\n *\n * ```ts\n * const physics = await loadRapier();\n * const environment = EffectThreeFoldkit.makeEnvironment(window, { physics });\n * ```\n *\n * Bodies are described on meshes (`body()`) under a scene's `physics()`; this package\n * only turns those descriptions into Rapier bodies and colliders, as react-three-rapier's\n * `RigidBody` does (`ae5c3fe`, `src/utils/utils-rigidbody.ts` and `utils-collider.ts`),\n * and joints into impulse joints, as its joint hooks do (`src/hooks/joints.ts`).\n *\n * Rapier (`@dimforge/rapier3d-compat`) is Apache-2.0; its WebAssembly is embedded, so\n * nothing extra is fetched.\n *\n * @module\n */\nimport RAPIER from '@dimforge/rapier3d-compat';\nimport { interactionBits } from '@opsydyn/effect-three';\nimport type {\n Body,\n BodyPose,\n Collider,\n ColliderShape,\n Collision,\n Physics,\n ContactForce,\n JointLimits,\n JointMotor,\n PhysicsEngine,\n PhysicsJoint,\n PhysicsWorld,\n Vec3,\n} from '@opsydyn/effect-three';\n\ntype Rapier = typeof RAPIER;\n\nconst vector = ([x, y, z]: Vec3) => ({ x, y, z });\n\nconst rotation = ([x, y, z, w]: BodyPose['quaternion']) => ({ x, y, z, w });\n\n/** Body types by our names. Kinematic bodies are position based, as react-three-rapier's default. */\nconst bodyTypes = {\n dynamic: RAPIER.RigidBodyType.Dynamic,\n fixed: RAPIER.RigidBodyType.Fixed,\n kinematic: RAPIER.RigidBodyType.KinematicPositionBased,\n} satisfies Record<Body['type'], RAPIER.RigidBodyType>;\n\n/** The collider description for a shape; a hull Rapier cannot build becomes a small ball. */\nconst shapeDesc = (rapier: Rapier, shape: ColliderShape): RAPIER.ColliderDesc => {\n switch (shape._tag) {\n case 'Cuboid':\n return rapier.ColliderDesc.cuboid(...shape.halfExtents);\n case 'Ball':\n return rapier.ColliderDesc.ball(shape.radius);\n case 'Hull':\n return rapier.ColliderDesc.convexHull(shape.points) ?? rapier.ColliderDesc.ball(1e-3);\n case 'Capsule':\n return rapier.ColliderDesc.capsule(shape.halfHeight, shape.radius);\n case 'Cylinder':\n return rapier.ColliderDesc.cylinder(shape.halfHeight, shape.radius);\n case 'Cone':\n return rapier.ColliderDesc.cone(shape.halfHeight, shape.radius);\n case 'Trimesh':\n return rapier.ColliderDesc.trimesh(shape.vertices, shape.indices);\n }\n};\n\n/** A collider placed in its body. */\nconst colliderDesc = (rapier: Rapier, collider: Collider): RAPIER.ColliderDesc =>\n shapeDesc(rapier, collider.shape)\n .setTranslation(...collider.translation)\n .setRotation(rotation(collider.rotation));\n\n/**\n * The events a body's colliders report: collisions always, contact forces over its\n * threshold when it has one (react-three-rapier's `onContactForce` turns on\n * `CONTACT_FORCE_EVENTS`).\n */\nconst reporting = (colliders: ReadonlyArray<RAPIER.Collider>, body: Body): void => {\n for (const collider of colliders) {\n if (body.contactForces === null) {\n collider.setActiveEvents(RAPIER.ActiveEvents.COLLISION_EVENTS);\n continue;\n }\n collider.setActiveEvents(\n RAPIER.ActiveEvents.COLLISION_EVENTS | RAPIER.ActiveEvents.CONTACT_FORCE_EVENTS,\n );\n collider.setContactForceEventThreshold(body.contactForces);\n }\n};\n\n/**\n * Applies a body's surface and mass settings to its colliders. A given mass is shared\n * among them; otherwise each has density 1.\n */\nconst surface = (colliders: ReadonlyArray<RAPIER.Collider>, body: Body): void => {\n for (const collider of colliders) {\n collider.setFriction(body.friction);\n collider.setRestitution(body.restitution);\n collider.setSensor(body.sensor);\n if (body.mass === null) collider.setDensity(1);\n else collider.setMass(body.mass / colliders.length);\n collider.setCollisionGroups(interactionBits(body.collisionGroups));\n collider.setSolverGroups(interactionBits(body.solverGroups));\n }\n};\n\n/** Applies a body's motion settings. */\nconst motion = (rigidBody: RAPIER.RigidBody, body: Body): void => {\n rigidBody.setBodyType(bodyTypes[body.type], true);\n rigidBody.setLinearDamping(body.linearDamping);\n rigidBody.setAngularDamping(body.angularDamping);\n rigidBody.setGravityScale(body.gravityScale, true);\n rigidBody.enableCcd(body.ccd);\n};\n\n/** The limits a joint has, if it is a hinge or slider with limits. */\nconst limitsOf = (joint: PhysicsJoint): JointLimits | null =>\n joint.kind._tag === 'Revolute' || joint.kind._tag === 'Prismatic' ? joint.kind.limits : null;\n\n/** The motor a joint has, if it is a hinge or slider with one. */\nconst motorOf = (joint: PhysicsJoint): JointMotor | null =>\n joint.kind._tag === 'Revolute' || joint.kind._tag === 'Prismatic' ? joint.kind.motor : null;\n\n/** Drives a hinge or slider once made: Rapier's `configureMotor`, set on the joint. */\nconst drive = (made: RAPIER.ImpulseJoint, motor: JointMotor | null): void => {\n if (motor !== null && made instanceof RAPIER.UnitImpulseJoint) {\n made.configureMotor(motor.position, motor.velocity, motor.stiffness, motor.damping);\n }\n};\n\n/**\n * Limits a hinge or slider once made. React-three-rapier sets them on the joint data, but\n * Rapier's `JointData.intoRaw` (0.21) passes them on for prismatic joints only, so a\n * hinge's would be lost: they are set on the joint instead.\n */\nconst limit = (made: RAPIER.ImpulseJoint, limits: JointLimits | null): void => {\n if (limits !== null && made instanceof RAPIER.UnitImpulseJoint) made.setLimits(...limits);\n};\n\n/** Rapier's joint data for a joint, anchors in each body's space. */\nconst jointData = (rapier: Rapier, joint: PhysicsJoint): RAPIER.JointData => {\n const a = vector(joint.anchorA);\n const b = vector(joint.anchorB);\n const { kind } = joint;\n switch (kind._tag) {\n case 'Fixed':\n return rapier.JointData.fixed(a, rotation(kind.frameA), b, rotation(kind.frameB));\n case 'Spherical':\n return rapier.JointData.spherical(a, b);\n case 'Revolute':\n return rapier.JointData.revolute(a, b, vector(kind.axis));\n case 'Prismatic':\n return rapier.JointData.prismatic(a, b, vector(kind.axis));\n case 'Rope':\n return rapier.JointData.rope(kind.length, a, b);\n case 'Spring':\n return rapier.JointData.spring(kind.restLength, kind.stiffness, kind.damping, a, b);\n }\n};\n\n/** Which body a collider belongs to, and which part of it, by name. */\ntype Owner = { readonly key: string; readonly part?: string };\n\n/** Two colliders' owners as an event's `a` and `b`, with their parts. */\nconst pair = (a: Owner, b: Owner) => ({\n a: a.key,\n b: b.key,\n ...(a.part === undefined ? {} : { aPart: a.part }),\n ...(b.part === undefined ? {} : { bPart: b.part }),\n});\n\ntype Held = {\n readonly rigidBody: RAPIER.RigidBody;\n readonly colliders: ReadonlyArray<RAPIER.Collider>;\n};\n\nconst createWorld =\n (rapier: Rapier) =>\n (initial: Physics): PhysicsWorld => {\n const world = new rapier.World(vector(initial.gravity));\n const events = new rapier.EventQueue(true);\n const bodies = new Map<string, Held>();\n /** Each collider's body, and the part of it the collider is (when named). */\n const keysByCollider = new Map<number, Owner>();\n const joints = new Map<\n string,\n { readonly joint: RAPIER.ImpulseJoint; readonly a: string; readonly b: string }\n >();\n\n const add: PhysicsWorld['add'] = (key, body, colliders, pose) => {\n const desc = new rapier.RigidBodyDesc(bodyTypes[body.type])\n .setTranslation(...pose.position)\n .setRotation(rotation(pose.quaternion))\n .setLinvel(...body.linearVelocity)\n .setAngvel(vector(body.angularVelocity))\n .setLinearDamping(body.linearDamping)\n .setAngularDamping(body.angularDamping)\n .setGravityScale(body.gravityScale)\n .setCcdEnabled(body.ccd);\n const rigidBody = world.createRigidBody(desc);\n const made = colliders.map((collider) =>\n world.createCollider(colliderDesc(rapier, collider), rigidBody),\n );\n surface(made, body);\n reporting(made, body);\n bodies.set(key, { rigidBody, colliders: made });\n made.forEach((collider, i) => {\n const part = colliders[i]?.part;\n keysByCollider.set(collider.handle, { key, ...(part === undefined ? {} : { part }) });\n });\n };\n\n const remove: PhysicsWorld['remove'] = (key) => {\n const held = bodies.get(key);\n if (held === undefined) return;\n for (const collider of held.colliders) keysByCollider.delete(collider.handle);\n // Rapier removes the body's joints with it; forget them, as their handles are reused.\n for (const [id, joined] of joints)\n if (joined.a === key || joined.b === key) joints.delete(id);\n world.removeRigidBody(held.rigidBody);\n bodies.delete(key);\n };\n\n const addJoint: PhysicsWorld['addJoint'] = (id, joint, a, b) => {\n const first = bodies.get(a);\n const second = bodies.get(b);\n if (first === undefined || second === undefined) return;\n const made = world.createImpulseJoint(\n jointData(rapier, joint),\n first.rigidBody,\n second.rigidBody,\n true,\n );\n limit(made, limitsOf(joint));\n drive(made, motorOf(joint));\n made.setContactsEnabled(joint.contacts);\n joints.set(id, { joint: made, a, b });\n };\n\n const removeJoint: PhysicsWorld['removeJoint'] = (id) => {\n const joined = joints.get(id);\n if (joined === undefined) return;\n world.removeImpulseJoint(joined.joint, true);\n joints.delete(id);\n };\n\n const collisionsOf = (): ReadonlyArray<Collision> => {\n const collisions: Array<Collision> = [];\n events.drainCollisionEvents((first, second, started) => {\n const a = keysByCollider.get(first);\n const b = keysByCollider.get(second);\n if (a !== undefined && b !== undefined) collisions.push({ ...pair(a, b), started });\n });\n return collisions;\n };\n\n /** Contact force events since the last call, kept across steps until asked for. */\n let forces: Array<ContactForce> = [];\n function recordForce(event: RAPIER.TempContactForceEvent): void {\n const a = keysByCollider.get(event.collider1());\n const b = keysByCollider.get(event.collider2());\n if (a === undefined || b === undefined) return;\n const total = event.totalForce();\n const direction = event.maxForceDirection();\n forces.push({\n ...pair(a, b),\n totalForce: [total.x, total.y, total.z],\n totalForceMagnitude: event.totalForceMagnitude(),\n maxForceDirection: [direction.x, direction.y, direction.z],\n maxForceMagnitude: event.maxForceMagnitude(),\n });\n }\n const drainForces = (): void => events.drainContactForceEvents(recordForce);\n\n return {\n configure: (physics) => {\n world.gravity = vector(physics.gravity);\n },\n add,\n update: (key, body) => {\n const held = bodies.get(key);\n if (held === undefined) return;\n motion(held.rigidBody, body);\n surface(held.colliders, body);\n reporting(held.colliders, body);\n },\n teleport: (key, pose) => {\n const held = bodies.get(key);\n if (held === undefined) return;\n held.rigidBody.setTranslation(vector(pose.position), true);\n held.rigidBody.setRotation(rotation(pose.quaternion), true);\n held.rigidBody.setLinvel({ x: 0, y: 0, z: 0 }, true);\n held.rigidBody.setAngvel({ x: 0, y: 0, z: 0 }, true);\n },\n moveKinematic: (key, pose) => {\n const held = bodies.get(key);\n if (held === undefined) return;\n held.rigidBody.setNextKinematicTranslation(vector(pose.position));\n held.rigidBody.setNextKinematicRotation(rotation(pose.quaternion));\n },\n applyImpulse: (key, impulse) => {\n bodies.get(key)?.rigidBody.applyImpulse(vector(impulse), true);\n },\n remove,\n addJoint,\n removeJoint,\n step: (seconds) => {\n world.timestep = seconds;\n world.step(events);\n drainForces();\n return collisionsOf();\n },\n contactForces: () => {\n const drained = forces;\n forces = [];\n return drained;\n },\n // react-three-rapier's Debug: Rapier's own line rendering of colliders and joints.\n debugLines: () => {\n const { vertices, colors } = world.debugRender();\n return { vertices, colors };\n },\n pose: (key) => {\n const held = bodies.get(key);\n if (held === undefined) return undefined;\n const { x, y, z } = held.rigidBody.translation();\n const turn = held.rigidBody.rotation();\n return { position: [x, y, z], quaternion: [turn.x, turn.y, turn.z, turn.w] };\n },\n awake: () => {\n for (const { rigidBody } of bodies.values()) {\n if (rigidBody.isDynamic() && !rigidBody.isSleeping()) return true;\n }\n return false;\n },\n dispose: () => {\n bodies.clear();\n keysByCollider.clear();\n joints.clear();\n events.free();\n world.free();\n },\n };\n };\n\n/**\n * Loads Rapier's WebAssembly and returns the engine. Call once per page; the engine makes\n * a world for each scene with physics.\n */\nexport const loadRapier = async (): Promise<PhysicsEngine> => {\n await RAPIER.init();\n return { createWorld: createWorld(RAPIER) };\n};\n"
5
+ "/**\n * Rapier physics for `@opsydyn/effect-three`: a `PhysicsEngine` that the scene graph\n * steps. Load it once, before making the environment, and pass it on:\n *\n * ```ts\n * const physics = await loadRapier();\n * const environment = EffectThreeFoldkit.makeEnvironment(window, { physics });\n * ```\n *\n * Bodies are described on meshes (`body()`) under a scene's `physics()`; this package\n * only turns those descriptions into Rapier bodies and colliders, as react-three-rapier's\n * `RigidBody` does (`ae5c3fe`, `src/utils/utils-rigidbody.ts` and `utils-collider.ts`),\n * and joints into impulse joints, as its joint hooks do (`src/hooks/joints.ts`).\n *\n * Rapier (`@dimforge/rapier3d-compat`) is Apache-2.0; its WebAssembly is embedded, so\n * nothing extra is fetched. For a simulation that must come out the same on every\n * machine (lockstep, replays shared as links), load Rapier's deterministic build from\n * `@opsydyn/effect-three-rapier/deterministic` instead.\n *\n * @module\n */\nimport RAPIER from '@dimforge/rapier3d-compat';\nimport type { PhysicsEngine } from '@opsydyn/effect-three';\n\nimport { engineOf } from './engine.ts';\n\n/**\n * Loads Rapier's WebAssembly and returns the engine. Call once per page; the engine makes\n * a world for each scene with physics.\n */\nexport const loadRapier = async (): Promise<PhysicsEngine> => {\n await RAPIER.init();\n return engineOf(RAPIER);\n};\n",
6
+ "/**\n * The engine itself, for whichever Rapier build is loaded: the standard one\n * (`@dimforge/rapier3d-compat`, from the package's main entry) or the deterministic one\n * (`/deterministic`). Both have the same API.\n *\n * @module\n */\nimport type RAPIER from '@dimforge/rapier3d-compat';\nimport { interactionBits } from '@opsydyn/effect-three';\nimport type {\n Body,\n BodyPose,\n Collider,\n ColliderShape,\n Collision,\n Physics,\n ContactForce,\n JointLimits,\n JointMotor,\n PhysicsEngine,\n PhysicsJoint,\n PhysicsWorld,\n Vec3,\n} from '@opsydyn/effect-three';\n\nimport { type IndexedBody, readSnapshot, type SnapshotIndex, writeSnapshot } from './snapshot.ts';\n\n/** A loaded Rapier module: either build. */\nexport type Rapier = typeof RAPIER;\n\nconst vector = ([x, y, z]: Vec3) => ({ x, y, z });\n\nconst rotation = ([x, y, z, w]: BodyPose['quaternion']) => ({ x, y, z, w });\n\n/** Body types by our names. Kinematic bodies are position based, as react-three-rapier's default. */\nconst bodyType = (rapier: Rapier, type: Body['type']): RAPIER.RigidBodyType =>\n ({\n dynamic: rapier.RigidBodyType.Dynamic,\n fixed: rapier.RigidBodyType.Fixed,\n kinematic: rapier.RigidBodyType.KinematicPositionBased,\n })[type];\n\n/** The collider description for a shape; a hull Rapier cannot build becomes a small ball. */\nconst shapeDesc = (rapier: Rapier, shape: ColliderShape): RAPIER.ColliderDesc => {\n switch (shape._tag) {\n case 'Cuboid':\n return rapier.ColliderDesc.cuboid(...shape.halfExtents);\n case 'Ball':\n return rapier.ColliderDesc.ball(shape.radius);\n case 'Hull':\n return rapier.ColliderDesc.convexHull(shape.points) ?? rapier.ColliderDesc.ball(1e-3);\n case 'Capsule':\n return rapier.ColliderDesc.capsule(shape.halfHeight, shape.radius);\n case 'Cylinder':\n return rapier.ColliderDesc.cylinder(shape.halfHeight, shape.radius);\n case 'Cone':\n return rapier.ColliderDesc.cone(shape.halfHeight, shape.radius);\n case 'Trimesh':\n return rapier.ColliderDesc.trimesh(shape.vertices, shape.indices);\n }\n};\n\n/** A collider placed in its body. */\nconst colliderDesc = (rapier: Rapier, collider: Collider): RAPIER.ColliderDesc =>\n shapeDesc(rapier, collider.shape)\n .setTranslation(...collider.translation)\n .setRotation(rotation(collider.rotation));\n\n/**\n * The events a body's colliders report: collisions always, contact forces over its\n * threshold when it has one (react-three-rapier's `onContactForce` turns on\n * `CONTACT_FORCE_EVENTS`).\n */\nconst reporting = (rapier: Rapier, colliders: ReadonlyArray<RAPIER.Collider>, body: Body): void => {\n for (const collider of colliders) {\n if (body.contactForces === null) {\n collider.setActiveEvents(rapier.ActiveEvents.COLLISION_EVENTS);\n continue;\n }\n collider.setActiveEvents(\n rapier.ActiveEvents.COLLISION_EVENTS | rapier.ActiveEvents.CONTACT_FORCE_EVENTS,\n );\n collider.setContactForceEventThreshold(body.contactForces);\n }\n};\n\n/**\n * Applies a body's surface and mass settings to its colliders. A given mass is shared\n * among them; otherwise each has density 1.\n */\nconst surface = (colliders: ReadonlyArray<RAPIER.Collider>, body: Body): void => {\n for (const collider of colliders) {\n collider.setFriction(body.friction);\n collider.setRestitution(body.restitution);\n collider.setSensor(body.sensor);\n if (body.mass === null) collider.setDensity(1);\n else collider.setMass(body.mass / colliders.length);\n collider.setCollisionGroups(interactionBits(body.collisionGroups));\n collider.setSolverGroups(interactionBits(body.solverGroups));\n }\n};\n\n/** Applies a body's motion settings. */\nconst motion = (rapier: Rapier, rigidBody: RAPIER.RigidBody, body: Body): void => {\n rigidBody.setBodyType(bodyType(rapier, body.type), true);\n rigidBody.setLinearDamping(body.linearDamping);\n rigidBody.setAngularDamping(body.angularDamping);\n rigidBody.setGravityScale(body.gravityScale, true);\n rigidBody.enableCcd(body.ccd);\n};\n\n/** The limits a joint has, if it is a hinge or slider with limits. */\nconst limitsOf = (joint: PhysicsJoint): JointLimits | null =>\n joint.kind._tag === 'Revolute' || joint.kind._tag === 'Prismatic' ? joint.kind.limits : null;\n\n/** The motor a joint has, if it is a hinge or slider with one. */\nconst motorOf = (joint: PhysicsJoint): JointMotor | null =>\n joint.kind._tag === 'Revolute' || joint.kind._tag === 'Prismatic' ? joint.kind.motor : null;\n\n/** Drives a hinge or slider once made: Rapier's `configureMotor`, set on the joint. */\nconst drive = (rapier: Rapier, made: RAPIER.ImpulseJoint, motor: JointMotor | null): void => {\n if (motor !== null && made instanceof rapier.UnitImpulseJoint) {\n made.configureMotor(motor.position, motor.velocity, motor.stiffness, motor.damping);\n }\n};\n\n/**\n * Limits a hinge or slider once made. React-three-rapier sets them on the joint data, but\n * Rapier's `JointData.intoRaw` (0.21) passes them on for prismatic joints only, so a\n * hinge's would be lost: they are set on the joint instead.\n */\nconst limit = (rapier: Rapier, made: RAPIER.ImpulseJoint, limits: JointLimits | null): void => {\n if (limits !== null && made instanceof rapier.UnitImpulseJoint) made.setLimits(...limits);\n};\n\n/** Rapier's joint data for a joint, anchors in each body's space. */\nconst jointData = (rapier: Rapier, joint: PhysicsJoint): RAPIER.JointData => {\n const a = vector(joint.anchorA);\n const b = vector(joint.anchorB);\n const { kind } = joint;\n switch (kind._tag) {\n case 'Fixed':\n return rapier.JointData.fixed(a, rotation(kind.frameA), b, rotation(kind.frameB));\n case 'Spherical':\n return rapier.JointData.spherical(a, b);\n case 'Revolute':\n return rapier.JointData.revolute(a, b, vector(kind.axis));\n case 'Prismatic':\n return rapier.JointData.prismatic(a, b, vector(kind.axis));\n case 'Rope':\n return rapier.JointData.rope(kind.length, a, b);\n case 'Spring':\n return rapier.JointData.spring(kind.restLength, kind.stiffness, kind.damping, a, b);\n }\n};\n\n/** Which body a collider belongs to, and which part of it, by name. */\ntype Owner = { readonly key: string; readonly part?: string };\n\n/** Two colliders' owners as an event's `a` and `b`, with their parts. */\nconst pair = (a: Owner, b: Owner) => ({\n a: a.key,\n b: b.key,\n ...(a.part === undefined ? {} : { aPart: a.part }),\n ...(b.part === undefined ? {} : { bPart: b.part }),\n});\n\ntype Held = {\n readonly rigidBody: RAPIER.RigidBody;\n readonly colliders: ReadonlyArray<RAPIER.Collider>;\n};\n\ntype Joined = { readonly joint: RAPIER.ImpulseJoint; readonly a: string; readonly b: string };\n\n/**\n * A Rapier world as a `PhysicsWorld`: a new one, or one restored from a snapshot with the\n * index of what it holds.\n */\nconst hostWorld =\n (rapier: Rapier) =>\n (world: RAPIER.World, index: SnapshotIndex = { bodies: [], joints: [] }): PhysicsWorld => {\n const events = new rapier.EventQueue(true);\n const bodies = new Map<string, Held>(\n index.bodies.map((body) => [\n body.key,\n {\n rigidBody: world.getRigidBody(body.handle),\n colliders: body.colliders.map((collider) => world.getCollider(collider.handle)),\n },\n ]),\n );\n /** Each collider's body, and the part of it the collider is (when named). */\n const keysByCollider = new Map<number, Owner>(\n index.bodies.flatMap(({ key, colliders }) =>\n colliders.map(({ handle, part }) => [handle, part === undefined ? { key } : { key, part }]),\n ),\n );\n const joints = new Map<string, Joined>(\n index.joints.map(({ id, handle, a, b }) => [\n id,\n { joint: world.getImpulseJoint(handle), a, b },\n ]),\n );\n\n const add: PhysicsWorld['add'] = (key, body, colliders, pose) => {\n const desc = new rapier.RigidBodyDesc(bodyType(rapier, body.type))\n .setTranslation(...pose.position)\n .setRotation(rotation(pose.quaternion))\n .setLinvel(...body.linearVelocity)\n .setAngvel(vector(body.angularVelocity))\n .setLinearDamping(body.linearDamping)\n .setAngularDamping(body.angularDamping)\n .setGravityScale(body.gravityScale)\n .setCcdEnabled(body.ccd);\n const rigidBody = world.createRigidBody(desc);\n const made = colliders.map((collider) =>\n world.createCollider(colliderDesc(rapier, collider), rigidBody),\n );\n surface(made, body);\n reporting(rapier, made, body);\n bodies.set(key, { rigidBody, colliders: made });\n made.forEach((collider, i) => {\n const part = colliders[i]?.part;\n keysByCollider.set(collider.handle, { key, ...(part === undefined ? {} : { part }) });\n });\n };\n\n const remove: PhysicsWorld['remove'] = (key) => {\n const held = bodies.get(key);\n if (held === undefined) return;\n for (const collider of held.colliders) keysByCollider.delete(collider.handle);\n // Rapier removes the body's joints with it; forget them, as their handles are reused.\n for (const [id, joined] of joints)\n if (joined.a === key || joined.b === key) joints.delete(id);\n world.removeRigidBody(held.rigidBody);\n bodies.delete(key);\n };\n\n const addJoint: PhysicsWorld['addJoint'] = (id, joint, a, b) => {\n const first = bodies.get(a);\n const second = bodies.get(b);\n if (first === undefined || second === undefined) return;\n const made = world.createImpulseJoint(\n jointData(rapier, joint),\n first.rigidBody,\n second.rigidBody,\n true,\n );\n limit(rapier, made, limitsOf(joint));\n drive(rapier, made, motorOf(joint));\n made.setContactsEnabled(joint.contacts);\n joints.set(id, { joint: made, a, b });\n };\n\n const removeJoint: PhysicsWorld['removeJoint'] = (id) => {\n const joined = joints.get(id);\n if (joined === undefined) return;\n world.removeImpulseJoint(joined.joint, true);\n joints.delete(id);\n };\n\n const collisionsOf = (): ReadonlyArray<Collision> => {\n const collisions: Array<Collision> = [];\n events.drainCollisionEvents((first, second, started) => {\n const a = keysByCollider.get(first);\n const b = keysByCollider.get(second);\n if (a !== undefined && b !== undefined) collisions.push({ ...pair(a, b), started });\n });\n return collisions;\n };\n\n /** Contact force events since the last call, kept across steps until asked for. */\n let forces: Array<ContactForce> = [];\n function recordForce(event: RAPIER.TempContactForceEvent): void {\n const a = keysByCollider.get(event.collider1());\n const b = keysByCollider.get(event.collider2());\n if (a === undefined || b === undefined) return;\n const total = event.totalForce();\n const direction = event.maxForceDirection();\n forces.push({\n ...pair(a, b),\n totalForce: [total.x, total.y, total.z],\n totalForceMagnitude: event.totalForceMagnitude(),\n maxForceDirection: [direction.x, direction.y, direction.z],\n maxForceMagnitude: event.maxForceMagnitude(),\n });\n }\n const drainForces = (): void => events.drainContactForceEvents(recordForce);\n\n /** A collider as a snapshot indexes it: its handle, and its part when named. */\n function indexed(collider: RAPIER.Collider): IndexedBody['colliders'][number] {\n const part = keysByCollider.get(collider.handle)?.part;\n return part === undefined ? { handle: collider.handle } : { handle: collider.handle, part };\n }\n\n return {\n configure: (physics) => {\n world.gravity = vector(physics.gravity);\n },\n add,\n update: (key, body) => {\n const held = bodies.get(key);\n if (held === undefined) return;\n motion(rapier, held.rigidBody, body);\n surface(held.colliders, body);\n reporting(rapier, held.colliders, body);\n },\n teleport: (key, pose) => {\n const held = bodies.get(key);\n if (held === undefined) return;\n held.rigidBody.setTranslation(vector(pose.position), true);\n held.rigidBody.setRotation(rotation(pose.quaternion), true);\n held.rigidBody.setLinvel({ x: 0, y: 0, z: 0 }, true);\n held.rigidBody.setAngvel({ x: 0, y: 0, z: 0 }, true);\n },\n moveKinematic: (key, pose) => {\n const held = bodies.get(key);\n if (held === undefined) return;\n held.rigidBody.setNextKinematicTranslation(vector(pose.position));\n held.rigidBody.setNextKinematicRotation(rotation(pose.quaternion));\n },\n applyImpulse: (key, impulse) => {\n bodies.get(key)?.rigidBody.applyImpulse(vector(impulse), true);\n },\n remove,\n addJoint,\n removeJoint,\n step: (seconds) => {\n world.timestep = seconds;\n world.step(events);\n drainForces();\n return collisionsOf();\n },\n contactForces: () => {\n const drained = forces;\n forces = [];\n return drained;\n },\n // react-three-rapier's Debug: Rapier's own line rendering of colliders and joints.\n debugLines: () => {\n const { vertices, colors } = world.debugRender();\n return { vertices, colors };\n },\n pose: (key) => {\n const held = bodies.get(key);\n if (held === undefined) return undefined;\n const { x, y, z } = held.rigidBody.translation();\n const turn = held.rigidBody.rotation();\n return { position: [x, y, z], quaternion: [turn.x, turn.y, turn.z, turn.w] };\n },\n awake: () => {\n for (const { rigidBody } of bodies.values()) {\n if (rigidBody.isDynamic() && !rigidBody.isSleeping()) return true;\n }\n return false;\n },\n // Rapier's world, and which of its bodies, colliders and joints are which.\n snapshot: () =>\n writeSnapshot(\n {\n bodies: [...bodies].map(([key, held]) => ({\n key,\n handle: held.rigidBody.handle,\n colliders: held.colliders.map(indexed),\n })),\n joints: [...joints].map(([id, { joint, a, b }]) => ({\n id,\n handle: joint.handle,\n a,\n b,\n })),\n },\n world.takeSnapshot(),\n ),\n dispose: () => {\n bodies.clear();\n keysByCollider.clear();\n joints.clear();\n events.free();\n world.free();\n },\n };\n };\n\n/** The engine over a loaded Rapier module. */\nexport const engineOf = (rapier: Rapier): PhysicsEngine => {\n const host = hostWorld(rapier);\n return {\n createWorld: (initial: Physics) => host(new rapier.World(vector(initial.gravity))),\n // A snapshot carries its gravity and everything else in Rapier's world.\n restoreWorld: (_physics, snapshot) => {\n const { index, world } = readSnapshot(snapshot);\n return {\n world: host(rapier.World.restoreSnapshot(world), index),\n bodies: index.bodies.map((body) => body.key),\n joints: index.joints.map((joint) => joint.id),\n };\n },\n };\n};\n",
7
+ "/**\n * A snapshot of one of this package's worlds: Rapier's own (`World.takeSnapshot`), and an\n * index of which of its bodies, colliders and joints are which, by the keys the scene\n * graph knows them by. Nothing here needs Rapier, so the page side of a worker\n * (`remotePhysics`) can read the index of a snapshot the worker took.\n *\n * The layout: a format byte; the bodies (each its key, handle, and colliders with their\n * handles and parts); the joints (each its id, handle and bodies); then Rapier's bytes.\n * Counts and string lengths are 32-bit, handles 64-bit floats (Rapier's own numbers),\n * all little-endian.\n *\n * @module\n */\n\n/** A body in a snapshot: its key, Rapier handle, and its colliders'. */\nexport type IndexedBody = {\n readonly key: string;\n readonly handle: number;\n readonly colliders: ReadonlyArray<{ readonly handle: number; readonly part?: string }>;\n};\n\n/** A joint in a snapshot: its id, Rapier handle, and the keys of its bodies. */\nexport type IndexedJoint = {\n readonly id: string;\n readonly handle: number;\n readonly a: string;\n readonly b: string;\n};\n\nexport type SnapshotIndex = {\n readonly bodies: ReadonlyArray<IndexedBody>;\n readonly joints: ReadonlyArray<IndexedJoint>;\n};\n\n/** The format byte this version writes and reads. */\nconst format = 1;\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/** Writes `index` and Rapier's `world` bytes as one snapshot. */\nexport const writeSnapshot = (index: SnapshotIndex, world: Uint8Array): Uint8Array => {\n const parts: Array<Uint8Array> = [Uint8Array.of(format)];\n const count = (value: number): void => {\n const bytes = new Uint8Array(4);\n new DataView(bytes.buffer).setUint32(0, value, true);\n parts.push(bytes);\n };\n const handle = (value: number): void => {\n const bytes = new Uint8Array(8);\n new DataView(bytes.buffer).setFloat64(0, value, true);\n parts.push(bytes);\n };\n const text = (value: string): void => {\n const bytes = encoder.encode(value);\n count(bytes.length);\n parts.push(bytes);\n };\n count(index.bodies.length);\n for (const body of index.bodies) {\n text(body.key);\n handle(body.handle);\n count(body.colliders.length);\n for (const collider of body.colliders) {\n handle(collider.handle);\n // A part is written with a leading mark, so that no part and an empty one differ.\n text(collider.part === undefined ? '' : `:${collider.part}`);\n }\n }\n count(index.joints.length);\n for (const joint of index.joints) {\n text(joint.id);\n handle(joint.handle);\n text(joint.a);\n text(joint.b);\n }\n parts.push(world);\n const out = new Uint8Array(parts.reduce((length, part) => length + part.length, 0));\n let at = 0;\n for (const part of parts) {\n out.set(part, at);\n at += part.length;\n }\n return out;\n};\n\n/** Reads a snapshot written by `writeSnapshot`: its index, and Rapier's bytes. */\nexport const readSnapshot = (\n snapshot: Uint8Array,\n): { readonly index: SnapshotIndex; readonly world: Uint8Array } => {\n if (snapshot[0] !== format) throw new Error('Not a snapshot of an effect-three Rapier world');\n const view = new DataView(snapshot.buffer, snapshot.byteOffset, snapshot.byteLength);\n let at = 1;\n const count = (): number => {\n const value = view.getUint32(at, true);\n at += 4;\n return value;\n };\n const handle = (): number => {\n const value = view.getFloat64(at, true);\n at += 8;\n return value;\n };\n const text = (): string => {\n const length = count();\n const value = decoder.decode(snapshot.subarray(at, at + length));\n at += length;\n return value;\n };\n function collider(): IndexedBody['colliders'][number] {\n const colliderHandle = handle();\n const part = text();\n return part === ''\n ? { handle: colliderHandle }\n : { handle: colliderHandle, part: part.slice(1) };\n }\n function body(): IndexedBody {\n const key = text();\n const bodyHandle = handle();\n return { key, handle: bodyHandle, colliders: Array.from({ length: count() }, collider) };\n }\n const bodies: Array<IndexedBody> = Array.from({ length: count() }, body);\n const joints: Array<IndexedJoint> = Array.from({ length: count() }, () => ({\n id: text(),\n handle: handle(),\n a: text(),\n b: text(),\n }));\n return { index: { bodies, joints }, world: snapshot.subarray(at) };\n};\n"
6
8
  ],
7
- "mappings": "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",
8
- "debugId": "1F8003691871788E64756E2164756E21",
9
+ "mappings": "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",
10
+ "debugId": "BF71FE688A93448964756E2164756E21",
9
11
  "names": []
10
12
  }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * A snapshot of one of this package's worlds: Rapier's own (`World.takeSnapshot`), and an
3
+ * index of which of its bodies, colliders and joints are which, by the keys the scene
4
+ * graph knows them by. Nothing here needs Rapier, so the page side of a worker
5
+ * (`remotePhysics`) can read the index of a snapshot the worker took.
6
+ *
7
+ * The layout: a format byte; the bodies (each its key, handle, and colliders with their
8
+ * handles and parts); the joints (each its id, handle and bodies); then Rapier's bytes.
9
+ * Counts and string lengths are 32-bit, handles 64-bit floats (Rapier's own numbers),
10
+ * all little-endian.
11
+ *
12
+ * @module
13
+ */
14
+ /** A body in a snapshot: its key, Rapier handle, and its colliders'. */
15
+ export type IndexedBody = {
16
+ readonly key: string;
17
+ readonly handle: number;
18
+ readonly colliders: ReadonlyArray<{
19
+ readonly handle: number;
20
+ readonly part?: string;
21
+ }>;
22
+ };
23
+ /** A joint in a snapshot: its id, Rapier handle, and the keys of its bodies. */
24
+ export type IndexedJoint = {
25
+ readonly id: string;
26
+ readonly handle: number;
27
+ readonly a: string;
28
+ readonly b: string;
29
+ };
30
+ export type SnapshotIndex = {
31
+ readonly bodies: ReadonlyArray<IndexedBody>;
32
+ readonly joints: ReadonlyArray<IndexedJoint>;
33
+ };
34
+ /** Writes `index` and Rapier's `world` bytes as one snapshot. */
35
+ export declare const writeSnapshot: (index: SnapshotIndex, world: Uint8Array) => Uint8Array;
36
+ /** Reads a snapshot written by `writeSnapshot`: its index, and Rapier's bytes. */
37
+ export declare const readSnapshot: (snapshot: Uint8Array) => {
38
+ readonly index: SnapshotIndex;
39
+ readonly world: Uint8Array;
40
+ };
41
+ //# sourceMappingURL=snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,wEAAwE;AACxE,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxF,CAAC;AAEF,gFAAgF;AAChF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;CAC9C,CAAC;AAQF,iEAAiE;AACjE,eAAO,MAAM,aAAa,UAAW,aAAa,SAAS,UAAU,KAAG,UA2CvE,CAAC;AAEF,kFAAkF;AAClF,eAAO,MAAM,YAAY,aACb,UAAU,KACnB;IAAE,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;CAwC7D,CAAC"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Physics in a worker, behind the same engine contract (ADR-017). In the page,
3
+ * `remotePhysics(worker)` is a `PhysicsEngine` whose worlds send what the scene graph asks
4
+ * of them to the worker, a frame's worth in one message, and answer from what the worker
5
+ * last sent back. In the worker, `servePhysics(self, loadRapier())` does what each world
6
+ * is asked with a real engine and sends back the steps' collisions and forces and every
7
+ * body's pose. Nothing here imports Rapier, so the page does not load its WebAssembly.
8
+ *
9
+ * ```ts
10
+ * // physics.worker.ts
11
+ * import { loadRapier } from '@opsydyn/effect-three-rapier/deterministic';
12
+ * import { servePhysics } from '@opsydyn/effect-three-rapier/worker';
13
+ * servePhysics(self, loadRapier());
14
+ *
15
+ * // the page
16
+ * import { remotePhysics } from '@opsydyn/effect-three-rapier/worker';
17
+ * const worker = new Worker(new URL('./physics.worker.ts', import.meta.url), { type: 'module' });
18
+ * const environment = EffectThreeFoldkit.makeEnvironment(window, { physics: remotePhysics(worker) });
19
+ * ```
20
+ *
21
+ * The stepping is pipelined: what a world shows and reports lags what it was asked by
22
+ * the time the worker takes to answer, about a frame. A world on `physics({ until })` is
23
+ * reported as there only once all it was asked has come back, so its checksum is the one
24
+ * an engine in the page would give, a frame later.
25
+ *
26
+ * @module
27
+ */
28
+ import type { Body, BodyPose, Collider, Collision, ContactForce, DebugLines, Physics, PhysicsEngine, PhysicsJoint, Vec3 } from '@opsydyn/effect-three';
29
+ /** One thing a world is asked to do, as `PhysicsWorld`'s method of that name. */
30
+ export type Call = {
31
+ readonly _tag: 'Configure';
32
+ readonly physics: Physics;
33
+ } | {
34
+ readonly _tag: 'Add';
35
+ readonly key: string;
36
+ readonly body: Body;
37
+ readonly colliders: ReadonlyArray<Collider>;
38
+ readonly pose: BodyPose;
39
+ } | {
40
+ readonly _tag: 'Update';
41
+ readonly key: string;
42
+ readonly body: Body;
43
+ } | {
44
+ readonly _tag: 'Teleport';
45
+ readonly key: string;
46
+ readonly pose: BodyPose;
47
+ } | {
48
+ readonly _tag: 'MoveKinematic';
49
+ readonly key: string;
50
+ readonly pose: BodyPose;
51
+ } | {
52
+ readonly _tag: 'ApplyImpulse';
53
+ readonly key: string;
54
+ readonly impulse: Vec3;
55
+ } | {
56
+ readonly _tag: 'Remove';
57
+ readonly key: string;
58
+ } | {
59
+ readonly _tag: 'AddJoint';
60
+ readonly id: string;
61
+ readonly joint: PhysicsJoint;
62
+ readonly a: string;
63
+ readonly b: string;
64
+ } | {
65
+ readonly _tag: 'RemoveJoint';
66
+ readonly id: string;
67
+ } | {
68
+ readonly _tag: 'Step';
69
+ readonly seconds: number;
70
+ } | {
71
+ readonly _tag: 'Snapshot';
72
+ };
73
+ /**
74
+ * What the page sends the worker. A world's creation is answered as its batch 1; the
75
+ * batches after it are numbered on from 2.
76
+ */
77
+ export type ToWorker = {
78
+ readonly _tag: 'Create';
79
+ readonly world: number;
80
+ readonly physics: Physics;
81
+ /** A snapshot to make the world from (`PhysicsEngine.restoreWorld`). */
82
+ readonly snapshot?: Uint8Array;
83
+ } | {
84
+ readonly _tag: 'Batch';
85
+ readonly world: number;
86
+ readonly batch: number;
87
+ readonly calls: ReadonlyArray<Call>;
88
+ } | {
89
+ readonly _tag: 'Dispose';
90
+ readonly world: number;
91
+ };
92
+ /** What the worker sends back after each batch, or why one could not be done. */
93
+ export type FromWorker = {
94
+ readonly _tag: 'Done';
95
+ readonly world: number;
96
+ readonly batch: number;
97
+ readonly collisions: ReadonlyArray<Collision>;
98
+ readonly contactForces: ReadonlyArray<ContactForce>;
99
+ readonly poses: ReadonlyArray<readonly [string, BodyPose]>;
100
+ readonly awake: boolean;
101
+ /** The world as lines, while it is configured to draw them. */
102
+ readonly debugLines: DebugLines | null;
103
+ /** The world's snapshot, when the batch asked for one. */
104
+ readonly snapshot?: Uint8Array;
105
+ } | {
106
+ readonly _tag: 'Failed';
107
+ readonly world: number;
108
+ readonly reason: string;
109
+ };
110
+ /**
111
+ * Either end of the channel: a `Worker` in the page, the worker's own global scope (`self`)
112
+ * inside it, or a `MessagePort`.
113
+ */
114
+ export type PhysicsPort = {
115
+ readonly postMessage: (message: unknown) => void;
116
+ readonly addEventListener: (type: 'message', listener: (event: MessageEvent) => void) => void;
117
+ /** A `MessagePort`'s: it delivers nothing to its listeners until started. */
118
+ readonly start?: () => void;
119
+ };
120
+ /**
121
+ * A physics engine in a worker, for the page: each world it makes is made in the worker
122
+ * that `servePhysics` runs in, on the far end of `port`.
123
+ */
124
+ export declare const remotePhysics: (port: PhysicsPort) => PhysicsEngine;
125
+ /**
126
+ * Serves the worlds a page's `remotePhysics` makes, with `engine` (or the engine it is
127
+ * loading): in the worker, `servePhysics(self, loadRapier())`. Messages are handled in
128
+ * the order they came, once the engine has loaded.
129
+ */
130
+ export declare const servePhysics: (port: PhysicsPort, engine: PhysicsEngine | Promise<PhysicsEngine>) => void;
131
+ //# sourceMappingURL=worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"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"}