@react-three/rapier 1.4.0 → 2.0.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,50 +1,56 @@
1
1
  import { Vector3 as Vector3$1, Quaternion as Quaternion$1, ActiveEvents, ColliderDesc, EventQueue, RigidBodyDesc } from '@dimforge/rapier3d-compat';
2
2
  export { CoefficientCombineRule, Collider as RapierCollider, RigidBody as RapierRigidBody } from '@dimforge/rapier3d-compat';
3
3
  import { useFrame, useThree } from '@react-three/fiber';
4
- import React, { useRef, useEffect, memo, useMemo, useContext, useState, createContext, useCallback, forwardRef, Fragment } from 'react';
4
+ import React, { useRef, useEffect, memo, useMemo, useContext, useState, createContext, useCallback, Fragment } from 'react';
5
5
  import { Quaternion, Euler, Vector3, Object3D, Matrix4, BufferAttribute, MathUtils, DynamicDrawUsage } from 'three';
6
6
  import { suspend } from 'suspend-react';
7
7
  import { mergeVertices } from 'three-stdlib';
8
8
 
9
- function _defineProperty(obj, key, value) {
10
- if (key in obj) {
11
- Object.defineProperty(obj, key, {
12
- value: value,
13
- enumerable: true,
14
- configurable: true,
15
- writable: true
16
- });
17
- } else {
18
- obj[key] = value;
9
+ function _toPrimitive(t, r) {
10
+ if ("object" != typeof t || !t) return t;
11
+ var e = t[Symbol.toPrimitive];
12
+ if (void 0 !== e) {
13
+ var i = e.call(t, r || "default");
14
+ if ("object" != typeof i) return i;
15
+ throw new TypeError("@@toPrimitive must return a primitive value.");
19
16
  }
17
+ return ("string" === r ? String : Number)(t);
18
+ }
20
19
 
21
- return obj;
20
+ function _toPropertyKey(t) {
21
+ var i = _toPrimitive(t, "string");
22
+ return "symbol" == typeof i ? i : i + "";
22
23
  }
23
24
 
24
- function ownKeys(object, enumerableOnly) {
25
- var keys = Object.keys(object);
25
+ function _defineProperty(e, r, t) {
26
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
27
+ value: t,
28
+ enumerable: !0,
29
+ configurable: !0,
30
+ writable: !0
31
+ }) : e[r] = t, e;
32
+ }
26
33
 
34
+ function ownKeys(e, r) {
35
+ var t = Object.keys(e);
27
36
  if (Object.getOwnPropertySymbols) {
28
- var symbols = Object.getOwnPropertySymbols(object);
29
- enumerableOnly && (symbols = symbols.filter(function (sym) {
30
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
31
- })), keys.push.apply(keys, symbols);
37
+ var o = Object.getOwnPropertySymbols(e);
38
+ r && (o = o.filter(function (r) {
39
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
40
+ })), t.push.apply(t, o);
32
41
  }
33
-
34
- return keys;
42
+ return t;
35
43
  }
36
-
37
- function _objectSpread2(target) {
38
- for (var i = 1; i < arguments.length; i++) {
39
- var source = null != arguments[i] ? arguments[i] : {};
40
- i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
41
- _defineProperty(target, key, source[key]);
42
- }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
43
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
44
+ function _objectSpread2(e) {
45
+ for (var r = 1; r < arguments.length; r++) {
46
+ var t = null != arguments[r] ? arguments[r] : {};
47
+ r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
48
+ _defineProperty(e, r, t[r]);
49
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
50
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
44
51
  });
45
52
  }
46
-
47
- return target;
53
+ return e;
48
54
  }
49
55
 
50
56
  const _quaternion = new Quaternion();
@@ -92,41 +98,33 @@ const rigidBodyTypeMap = {
92
98
  const rigidBodyTypeFromString = type => rigidBodyTypeMap[type];
93
99
  const scaleVertices = (vertices, scale) => {
94
100
  const scaledVerts = Array.from(vertices);
95
-
96
101
  for (let i = 0; i < vertices.length / 3; i++) {
97
102
  scaledVerts[i * 3] *= scale.x;
98
103
  scaledVerts[i * 3 + 1] *= scale.y;
99
104
  scaledVerts[i * 3 + 2] *= scale.z;
100
105
  }
101
-
102
106
  return scaledVerts;
103
107
  };
104
108
  const vectorToTuple = v => {
105
109
  if (!v) return [0];
106
-
107
110
  if (v instanceof Quaternion) {
108
111
  return [v.x, v.y, v.z, v.w];
109
112
  }
110
-
111
113
  if (v instanceof Vector3 || v instanceof Euler) {
112
114
  return [v.x, v.y, v.z];
113
115
  }
114
-
115
116
  if (Array.isArray(v)) {
116
117
  return v;
117
118
  }
118
-
119
119
  return [v];
120
120
  };
121
121
  function useConst(initialValue) {
122
- const ref = useRef();
123
-
122
+ const ref = useRef(undefined);
124
123
  if (ref.current === undefined) {
125
124
  ref.current = {
126
125
  value: typeof initialValue === "function" ? initialValue() : initialValue
127
126
  };
128
127
  }
129
-
130
128
  return ref.current.value;
131
129
  }
132
130
 
@@ -145,7 +143,6 @@ const useRaf = callback => {
145
143
  cb.current(delta / 1000);
146
144
  lastFrame.current = now;
147
145
  };
148
-
149
146
  raf.current = requestAnimationFrame(loop);
150
147
  return () => cancelAnimationFrame(raf.current);
151
148
  }, []);
@@ -160,7 +157,6 @@ const UseFrameStepper = ({
160
157
  }, updatePriority);
161
158
  return null;
162
159
  };
163
-
164
160
  const RafStepper = ({
165
161
  onStep
166
162
  }) => {
@@ -169,7 +165,6 @@ const RafStepper = ({
169
165
  });
170
166
  return null;
171
167
  };
172
-
173
168
  const FrameStepper = ({
174
169
  onStep,
175
170
  type,
@@ -182,98 +177,80 @@ const FrameStepper = ({
182
177
  updatePriority: updatePriority
183
178
  });
184
179
  };
185
-
186
180
  var FrameStepper$1 = /*#__PURE__*/memo(FrameStepper);
187
181
 
188
- function _objectWithoutPropertiesLoose(source, excluded) {
189
- if (source == null) return {};
190
- var target = {};
191
- var sourceKeys = Object.keys(source);
192
- var key, i;
193
-
194
- for (i = 0; i < sourceKeys.length; i++) {
195
- key = sourceKeys[i];
196
- if (excluded.indexOf(key) >= 0) continue;
197
- target[key] = source[key];
182
+ function _objectWithoutPropertiesLoose(r, e) {
183
+ if (null == r) return {};
184
+ var t = {};
185
+ for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
186
+ if (-1 !== e.indexOf(n)) continue;
187
+ t[n] = r[n];
198
188
  }
199
-
200
- return target;
189
+ return t;
201
190
  }
202
191
 
203
- function _objectWithoutProperties(source, excluded) {
204
- if (source == null) return {};
205
- var target = _objectWithoutPropertiesLoose(source, excluded);
206
- var key, i;
207
-
192
+ function _objectWithoutProperties(e, t) {
193
+ if (null == e) return {};
194
+ var o,
195
+ r,
196
+ i = _objectWithoutPropertiesLoose(e, t);
208
197
  if (Object.getOwnPropertySymbols) {
209
- var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
210
-
211
- for (i = 0; i < sourceSymbolKeys.length; i++) {
212
- key = sourceSymbolKeys[i];
213
- if (excluded.indexOf(key) >= 0) continue;
214
- if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
215
- target[key] = source[key];
216
- }
198
+ var n = Object.getOwnPropertySymbols(e);
199
+ for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
217
200
  }
218
-
219
- return target;
201
+ return i;
220
202
  }
221
203
 
222
- const _excluded$2 = ["mass", "linearDamping", "angularDamping", "type", "onCollisionEnter", "onCollisionExit", "onIntersectionEnter", "onIntersectionExit", "onContactForce", "children", "canSleep", "ccd", "gravityScale", "softCcdPrediction"];
204
+ const _excluded$2 = ["mass", "linearDamping", "angularDamping", "type", "onCollisionEnter", "onCollisionExit", "onIntersectionEnter", "onIntersectionExit", "onContactForce", "children", "canSleep", "ccd", "gravityScale", "softCcdPrediction", "ref"];
223
205
  const scaleColliderArgs = (shape, args, scale) => {
224
- const newArgs = args.slice(); // Heightfield uses a vector
206
+ const newArgs = args.slice();
225
207
 
208
+ // Heightfield uses a vector
226
209
  if (shape === "heightfield") {
227
210
  const s = newArgs[3];
228
211
  s.x *= scale.x;
229
212
  s.x *= scale.y;
230
213
  s.x *= scale.z;
231
214
  return newArgs;
232
- } // Trimesh and convex scale the vertices
233
-
215
+ }
234
216
 
217
+ // Trimesh and convex scale the vertices
235
218
  if (shape === "trimesh" || shape === "convexHull") {
236
219
  newArgs[0] = scaleVertices(newArgs[0], scale);
237
220
  return newArgs;
238
- } // Prepfill with some extra
239
-
221
+ }
240
222
 
223
+ // Prepfill with some extra
241
224
  const scaleArray = [scale.x, scale.y, scale.z, scale.x, scale.x];
242
225
  return newArgs.map((arg, index) => scaleArray[index] * arg);
243
226
  };
244
227
  const createColliderFromOptions = (options, world, scale, getRigidBody) => {
245
- const scaledArgs = scaleColliderArgs(options.shape, options.args, scale); // @ts-ignore
246
-
228
+ const scaledArgs = scaleColliderArgs(options.shape, options.args, scale);
229
+ // @ts-ignore
247
230
  const desc = ColliderDesc[options.shape](...scaledArgs);
248
231
  return world.createCollider(desc, getRigidBody === null || getRigidBody === void 0 ? void 0 : getRigidBody());
249
232
  };
250
233
  const immutableColliderOptions = ["shape", "args"];
251
234
  const massPropertiesConflictError = "Please pick ONLY ONE of the `density`, `mass` and `massProperties` options.";
252
-
253
235
  const setColliderMassOptions = (collider, options) => {
254
236
  if (options.density !== undefined) {
255
237
  if (options.mass !== undefined || options.massProperties !== undefined) {
256
238
  throw new Error(massPropertiesConflictError);
257
239
  }
258
-
259
240
  collider.setDensity(options.density);
260
241
  return;
261
242
  }
262
-
263
243
  if (options.mass !== undefined) {
264
244
  if (options.massProperties !== undefined) {
265
245
  throw new Error(massPropertiesConflictError);
266
246
  }
267
-
268
247
  collider.setMass(options.mass);
269
248
  return;
270
249
  }
271
-
272
250
  if (options.massProperties !== undefined) {
273
251
  collider.setMassProperties(options.massProperties.mass, options.massProperties.centerOfMass, options.massProperties.principalAngularInertia, options.massProperties.angularInertiaLocalFrame);
274
252
  }
275
253
  };
276
-
277
254
  const mutableColliderOptions = {
278
255
  sensor: (collider, value) => {
279
256
  collider.setSensor(value);
@@ -311,23 +288,17 @@ const mutableColliderOptions = {
311
288
  const mutableColliderOptionKeys = Object.keys(mutableColliderOptions);
312
289
  const setColliderOptions = (collider, options, states) => {
313
290
  const state = states.get(collider.handle);
314
-
315
291
  if (state) {
316
292
  var _state$worldParent;
317
-
318
293
  // Update collider position based on the object's position
319
294
  const parentWorldScale = state.object.parent.getWorldScale(_vector3);
320
295
  const parentInvertedWorldMatrix = (_state$worldParent = state.worldParent) === null || _state$worldParent === void 0 ? void 0 : _state$worldParent.matrixWorld.clone().invert();
321
296
  state.object.updateWorldMatrix(true, false);
322
-
323
297
  _matrix4.copy(state.object.matrixWorld);
324
-
325
298
  if (parentInvertedWorldMatrix) {
326
299
  _matrix4.premultiply(parentInvertedWorldMatrix);
327
300
  }
328
-
329
301
  _matrix4.decompose(_position, _rotation, _scale);
330
-
331
302
  if (collider.parent()) {
332
303
  collider.setTranslationWrtParent({
333
304
  x: _position.x * parentWorldScale.x,
@@ -343,16 +314,17 @@ const setColliderOptions = (collider, options, states) => {
343
314
  });
344
315
  collider.setRotation(_rotation);
345
316
  }
346
-
347
317
  mutableColliderOptionKeys.forEach(key => {
348
318
  if (key in options) {
349
319
  const option = options[key];
350
- mutableColliderOptions[key](collider, // @ts-ignore Option does not want to fit into the function, but it will
320
+ mutableColliderOptions[key](collider,
321
+ // @ts-ignore Option does not want to fit into the function, but it will
351
322
  option, options);
352
323
  }
353
- }); // handle mass separately, because the assignments
354
- // are exclusive.
324
+ });
355
325
 
326
+ // handle mass separately, because the assignments
327
+ // are exclusive.
356
328
  setColliderMassOptions(collider, options);
357
329
  }
358
330
  };
@@ -366,7 +338,6 @@ const useUpdateColliderOptions = (getCollider, props, states) => {
366
338
  setColliderOptions(collider, props, states);
367
339
  }, [...mutablePropsAsFlatArray, getCollider]);
368
340
  };
369
-
370
341
  const isChildOfMeshCollider = child => {
371
342
  let flag = false;
372
343
  child.traverseAncestors(a => {
@@ -374,7 +345,6 @@ const isChildOfMeshCollider = child => {
374
345
  });
375
346
  return flag;
376
347
  };
377
-
378
348
  const createColliderState = (collider, object, rigidBodyObject) => {
379
349
  return {
380
350
  collider,
@@ -396,16 +366,13 @@ const createColliderPropsFromChildren = ({
396
366
  const childColliderProps = [];
397
367
  object.updateWorldMatrix(true, false);
398
368
  const invertedParentMatrixWorld = object.matrixWorld.clone().invert();
399
-
400
369
  const colliderFromChild = child => {
401
370
  if ("isMesh" in child) {
402
371
  if (_ignoreMeshColliders && isChildOfMeshCollider(child)) return;
403
372
  const worldScale = child.getWorldScale(_scale);
404
373
  const shape = autoColliderMap[options.colliders || "cuboid"];
405
374
  child.updateWorldMatrix(true, false);
406
-
407
375
  _matrix4.copy(child.matrixWorld).premultiply(invertedParentMatrixWorld).decompose(_position, _rotation, _scale);
408
-
409
376
  const rotationEuler = new Euler().setFromQuaternion(_rotation, "XYZ");
410
377
  const {
411
378
  geometry
@@ -414,7 +381,6 @@ const createColliderPropsFromChildren = ({
414
381
  args,
415
382
  offset
416
383
  } = getColliderArgsFromGeometry(geometry, options.colliders || "cuboid");
417
-
418
384
  const colliderProps = _objectSpread2(_objectSpread2({}, cleanRigidBodyPropsForCollider(options)), {}, {
419
385
  args: args,
420
386
  shape: shape,
@@ -422,17 +388,14 @@ const createColliderPropsFromChildren = ({
422
388
  position: [_position.x + offset.x * worldScale.x, _position.y + offset.y * worldScale.y, _position.z + offset.z * worldScale.z],
423
389
  scale: [worldScale.x, worldScale.y, worldScale.z]
424
390
  });
425
-
426
391
  childColliderProps.push(colliderProps);
427
392
  }
428
393
  };
429
-
430
394
  if (options.includeInvisible) {
431
395
  object.traverse(colliderFromChild);
432
396
  } else {
433
397
  object.traverseVisible(colliderFromChild);
434
398
  }
435
-
436
399
  return childColliderProps;
437
400
  };
438
401
  const getColliderArgsFromGeometry = (geometry, colliders) => {
@@ -449,7 +412,6 @@ const getColliderArgsFromGeometry = (geometry, colliders) => {
449
412
  offset: boundingBox.getCenter(new Vector3())
450
413
  };
451
414
  }
452
-
453
415
  case "ball":
454
416
  {
455
417
  geometry.computeBoundingSphere();
@@ -462,18 +424,15 @@ const getColliderArgsFromGeometry = (geometry, colliders) => {
462
424
  offset: boundingSphere.center
463
425
  };
464
426
  }
465
-
466
427
  case "trimesh":
467
428
  {
468
429
  var _clonedGeometry$index;
469
-
470
430
  const clonedGeometry = geometry.index ? geometry.clone() : mergeVertices(geometry);
471
431
  return {
472
432
  args: [clonedGeometry.attributes.position.array, (_clonedGeometry$index = clonedGeometry.index) === null || _clonedGeometry$index === void 0 ? void 0 : _clonedGeometry$index.array],
473
433
  offset: new Vector3()
474
434
  };
475
435
  }
476
-
477
436
  case "hull":
478
437
  {
479
438
  const g = geometry.clone();
@@ -483,7 +442,6 @@ const getColliderArgsFromGeometry = (geometry, colliders) => {
483
442
  };
484
443
  }
485
444
  }
486
-
487
445
  return {
488
446
  args: [],
489
447
  offset: new Vector3()
@@ -509,7 +467,6 @@ activeEvents = {}) => {
509
467
  } = props;
510
468
  useEffect(() => {
511
469
  const collider = getCollider();
512
-
513
470
  if (collider) {
514
471
  const {
515
472
  collision: collisionEventsActive,
@@ -517,7 +474,6 @@ activeEvents = {}) => {
517
474
  } = getActiveCollisionEventsFromProps(props);
518
475
  const hasCollisionEvent = collisionEventsActive || activeEvents.collision;
519
476
  const hasContactForceEvent = contactForceEventsActive || activeEvents.contactForce;
520
-
521
477
  if (hasCollisionEvent && hasContactForceEvent) {
522
478
  collider.setActiveEvents(ActiveEvents.COLLISION_EVENTS | ActiveEvents.CONTACT_FORCE_EVENTS);
523
479
  } else if (hasCollisionEvent) {
@@ -525,7 +481,6 @@ activeEvents = {}) => {
525
481
  } else if (hasContactForceEvent) {
526
482
  collider.setActiveEvents(ActiveEvents.CONTACT_FORCE_EVENTS);
527
483
  }
528
-
529
484
  events.set(collider.handle, {
530
485
  onCollisionEnter,
531
486
  onCollisionExit,
@@ -534,7 +489,6 @@ activeEvents = {}) => {
534
489
  onContactForce
535
490
  });
536
491
  }
537
-
538
492
  return () => {
539
493
  if (collider) {
540
494
  events.delete(collider.handle);
@@ -544,34 +498,33 @@ activeEvents = {}) => {
544
498
  };
545
499
  const cleanRigidBodyPropsForCollider = (props = {}) => {
546
500
  const rest = _objectWithoutProperties(props, _excluded$2);
547
-
548
501
  return rest;
549
502
  };
550
503
 
504
+ // Utils
551
505
  const useMutableCallback = fn => {
552
506
  const ref = useRef(fn);
553
507
  useEffect(() => {
554
508
  ref.current = fn;
555
509
  }, [fn]);
556
510
  return ref;
557
- }; // External hooks
511
+ };
558
512
 
513
+ // External hooks
559
514
  /**
560
515
  * Exposes the Rapier context, and world
561
516
  * @category Hooks
562
517
  */
563
-
564
-
565
518
  const useRapier = () => {
566
519
  const rapier = useContext(rapierContext);
567
520
  if (!rapier) throw new Error("react-three-rapier: useRapier must be used within <Physics />!");
568
521
  return rapier;
569
522
  };
523
+
570
524
  /**
571
525
  * Registers a callback to be called before the physics step
572
526
  * @category Hooks
573
527
  */
574
-
575
528
  const useBeforePhysicsStep = callback => {
576
529
  const {
577
530
  beforeStepCallbacks
@@ -584,11 +537,11 @@ const useBeforePhysicsStep = callback => {
584
537
  };
585
538
  }, []);
586
539
  };
540
+
587
541
  /**
588
542
  * Registers a callback to be called after the physics step
589
543
  * @category Hooks
590
544
  */
591
-
592
545
  const useAfterPhysicsStep = callback => {
593
546
  const {
594
547
  afterStepCallbacks
@@ -600,17 +553,16 @@ const useAfterPhysicsStep = callback => {
600
553
  afterStepCallbacks.delete(ref);
601
554
  };
602
555
  }, []);
603
- }; // Internal hooks
556
+ };
604
557
 
558
+ // Internal hooks
605
559
  /**
606
560
  * @internal
607
561
  */
608
-
609
562
  const useChildColliderProps = (ref, options, ignoreMeshColliders = true) => {
610
563
  const [colliderProps, setColliderProps] = useState([]);
611
564
  useEffect(() => {
612
565
  const object = ref.current;
613
-
614
566
  if (object && options.colliders !== false) {
615
567
  setColliderProps(createColliderPropsFromChildren({
616
568
  object: ref.current,
@@ -656,33 +608,26 @@ const createSingletonProxy = createInstance => {
656
608
  if (!instance) {
657
609
  instance = createInstance();
658
610
  }
659
-
660
611
  return Reflect.get(instance, prop);
661
612
  },
662
-
663
613
  set(target, prop, value) {
664
614
  if (!instance) {
665
615
  instance = createInstance();
666
616
  }
667
-
668
617
  return Reflect.set(instance, prop, value);
669
618
  }
670
-
671
619
  };
672
620
  const proxy = new Proxy({}, handler);
673
-
674
621
  const reset = () => {
675
622
  instance = undefined;
676
623
  };
677
-
678
624
  const set = newInstance => {
679
625
  instance = newInstance;
680
626
  };
627
+
681
628
  /**
682
629
  * Return the proxy and a reset function
683
630
  */
684
-
685
-
686
631
  return {
687
632
  proxy,
688
633
  reset,
@@ -691,10 +636,8 @@ const createSingletonProxy = createInstance => {
691
636
  };
692
637
 
693
638
  const rapierContext = /*#__PURE__*/createContext(undefined);
694
-
695
639
  const getCollisionPayloadFromSource = (target, other) => {
696
640
  var _target$collider$stat, _target$rigidBody$sta, _other$collider$state, _other$rigidBody$stat, _other$collider$state2, _other$rigidBody$stat2;
697
-
698
641
  return {
699
642
  target: {
700
643
  rigidBody: target.rigidBody.object,
@@ -714,13 +657,11 @@ const getCollisionPayloadFromSource = (target, other) => {
714
657
  rigidBodyObject: (_other$rigidBody$stat2 = other.rigidBody.state) === null || _other$rigidBody$stat2 === void 0 ? void 0 : _other$rigidBody$stat2.object
715
658
  };
716
659
  };
717
-
718
660
  const importRapier = async () => {
719
661
  let r = await import('@dimforge/rapier3d-compat');
720
662
  await r.init();
721
663
  return r;
722
664
  };
723
-
724
665
  /**
725
666
  * The main physics component used to create a physics world.
726
667
  * @category Components
@@ -743,7 +684,7 @@ const Physics = props => {
743
684
  numInternalPgsIterations = 1,
744
685
  minIslandSize = 128,
745
686
  maxCcdSubsteps = 1,
746
- erp = 0.8,
687
+ contactNaturalFrequency = 30,
747
688
  lengthUnit = 1
748
689
  } = props;
749
690
  const rapier = suspend(importRapier, ["@react-thee/rapier", importRapier]);
@@ -757,12 +698,12 @@ const Physics = props => {
757
698
  const eventQueue = useConst(() => new EventQueue(false));
758
699
  const beforeStepCallbacks = useConst(() => new Set());
759
700
  const afterStepCallbacks = useConst(() => new Set());
701
+
760
702
  /**
761
703
  * Initiate the world
762
704
  * This creates a singleton proxy, so that the world is only created when
763
705
  * something within it is accessed.
764
706
  */
765
-
766
707
  const {
767
708
  proxy: worldProxy,
768
709
  reset: resetWorldProxy,
@@ -773,8 +714,9 @@ const Physics = props => {
773
714
  worldProxy.free();
774
715
  resetWorldProxy();
775
716
  };
776
- }, []); // Update mutable props
717
+ }, []);
777
718
 
719
+ // Update mutable props
778
720
  useEffect(() => {
779
721
  worldProxy.gravity = vector3ToRapierVector(gravity);
780
722
  worldProxy.integrationParameters.numSolverIterations = numSolverIterations;
@@ -784,12 +726,11 @@ const Physics = props => {
784
726
  worldProxy.integrationParameters.minIslandSize = minIslandSize;
785
727
  worldProxy.integrationParameters.maxCcdSubsteps = maxCcdSubsteps;
786
728
  worldProxy.integrationParameters.normalizedPredictionDistance = predictionDistance;
787
- worldProxy.integrationParameters.erp = erp;
788
729
  worldProxy.lengthUnit = lengthUnit;
789
- }, [worldProxy, ...gravity, numSolverIterations, numAdditionalFrictionIterations, numInternalPgsIterations, allowedLinearError, minIslandSize, maxCcdSubsteps, predictionDistance, erp, lengthUnit]);
730
+ worldProxy.integrationParameters.contact_natural_frequency = contactNaturalFrequency;
731
+ }, [worldProxy, ...gravity, numSolverIterations, numAdditionalFrictionIterations, numInternalPgsIterations, allowedLinearError, minIslandSize, maxCcdSubsteps, predictionDistance, lengthUnit, contactNaturalFrequency]);
790
732
  const getSourceFromColliderHandle = useCallback(handle => {
791
733
  var _collider$parent;
792
-
793
734
  const collider = worldProxy.getCollider(handle);
794
735
  const colEvents = colliderEvents.get(handle);
795
736
  const colliderState = colliderStates.get(handle);
@@ -817,37 +758,36 @@ const Physics = props => {
817
758
  });
818
759
  const step = useCallback(dt => {
819
760
  const world = worldProxy;
761
+
820
762
  /* Check if the timestep is supposed to be variable. We'll do this here
821
763
  once so we don't have to string-check every frame. */
822
-
823
764
  const timeStepVariable = timeStep === "vary";
765
+
824
766
  /**
825
767
  * Fixed timeStep simulation progression
826
768
  * @see https://gafferongames.com/post/fix_your_timestep/
827
769
  */
828
770
 
829
771
  const clampedDelta = MathUtils.clamp(dt, 0, 0.5);
830
-
831
772
  const stepWorld = delta => {
832
773
  // Trigger beforeStep callbacks
833
774
  beforeStepCallbacks.forEach(callback => {
834
775
  callback.current(world);
835
776
  });
836
777
  world.timestep = delta;
837
- world.step(eventQueue); // Trigger afterStep callbacks
778
+ world.step(eventQueue);
838
779
 
780
+ // Trigger afterStep callbacks
839
781
  afterStepCallbacks.forEach(callback => {
840
782
  callback.current(world);
841
783
  });
842
784
  };
843
-
844
785
  if (timeStepVariable) {
845
786
  stepWorld(clampedDelta);
846
787
  } else {
847
788
  // don't step time forwards if paused
848
789
  // Increase accumulator
849
790
  steppingState.accumulator += clampedDelta;
850
-
851
791
  while (steppingState.accumulator >= timeStep) {
852
792
  // Set up previous state
853
793
  // needed for accurate interpolations if the world steps more than once
@@ -860,57 +800,48 @@ const Physics = props => {
860
800
  };
861
801
  });
862
802
  }
863
-
864
803
  stepWorld(timeStep);
865
804
  steppingState.accumulator -= timeStep;
866
805
  }
867
806
  }
807
+ const interpolationAlpha = timeStepVariable || !interpolate || paused ? 1 : steppingState.accumulator / timeStep;
868
808
 
869
- const interpolationAlpha = timeStepVariable || !interpolate || paused ? 1 : steppingState.accumulator / timeStep; // Update meshes
870
-
809
+ // Update meshes
871
810
  rigidBodyStates.forEach((state, handle) => {
872
811
  const rigidBody = world.getRigidBody(handle);
873
812
  const events = rigidBodyEvents.get(handle);
874
-
875
813
  if (events !== null && events !== void 0 && events.onSleep || events !== null && events !== void 0 && events.onWake) {
876
814
  if (rigidBody.isSleeping() && !state.isSleeping) {
877
815
  var _events$onSleep;
878
-
879
816
  events === null || events === void 0 ? void 0 : (_events$onSleep = events.onSleep) === null || _events$onSleep === void 0 ? void 0 : _events$onSleep.call(events);
880
817
  }
881
-
882
818
  if (!rigidBody.isSleeping() && state.isSleeping) {
883
819
  var _events$onWake;
884
-
885
820
  events === null || events === void 0 ? void 0 : (_events$onWake = events.onWake) === null || _events$onWake === void 0 ? void 0 : _events$onWake.call(events);
886
821
  }
887
-
888
822
  state.isSleeping = rigidBody.isSleeping();
889
823
  }
890
-
891
824
  if (!rigidBody || rigidBody.isSleeping() && !("isInstancedMesh" in state.object) || !state.setMatrix) {
892
825
  return;
893
- } // New states
894
-
826
+ }
895
827
 
828
+ // New states
896
829
  let t = rigidBody.translation();
897
830
  let r = rigidBody.rotation();
898
831
  let previousState = steppingState.previousState[handle];
899
-
900
832
  if (previousState) {
901
833
  // Get previous simulated world position
902
- _matrix4.compose(previousState.position, rapierQuaternionToQuaternion(previousState.rotation), state.scale).premultiply(state.invertedWorldMatrix).decompose(_position, _rotation, _scale); // Apply previous tick position
903
-
834
+ _matrix4.compose(previousState.position, rapierQuaternionToQuaternion(previousState.rotation), state.scale).premultiply(state.invertedWorldMatrix).decompose(_position, _rotation, _scale);
904
835
 
836
+ // Apply previous tick position
905
837
  if (state.meshType == "mesh") {
906
838
  state.object.position.copy(_position);
907
839
  state.object.quaternion.copy(_rotation);
908
840
  }
909
- } // Get new position
910
-
841
+ }
911
842
 
843
+ // Get new position
912
844
  _matrix4.compose(t, rapierQuaternionToQuaternion(r), state.scale).premultiply(state.invertedWorldMatrix).decompose(_position, _rotation, _scale);
913
-
914
845
  if (state.meshType == "instancedMesh") {
915
846
  state.setMatrix(_matrix4);
916
847
  } else {
@@ -921,19 +852,17 @@ const Physics = props => {
921
852
  });
922
853
  eventQueue.drainCollisionEvents((handle1, handle2, started) => {
923
854
  const source1 = getSourceFromColliderHandle(handle1);
924
- const source2 = getSourceFromColliderHandle(handle2); // Collision Events
855
+ const source2 = getSourceFromColliderHandle(handle2);
925
856
 
857
+ // Collision Events
926
858
  if (!(source1 !== null && source1 !== void 0 && source1.collider.object) || !(source2 !== null && source2 !== void 0 && source2.collider.object)) {
927
859
  return;
928
860
  }
929
-
930
861
  const collisionPayload1 = getCollisionPayloadFromSource(source1, source2);
931
862
  const collisionPayload2 = getCollisionPayloadFromSource(source2, source1);
932
-
933
863
  if (started) {
934
864
  world.contactPair(source1.collider.object, source2.collider.object, (manifold, flipped) => {
935
865
  var _source1$rigidBody$ev, _source1$rigidBody$ev2, _source2$rigidBody$ev, _source2$rigidBody$ev2, _source1$collider$eve, _source1$collider$eve2, _source2$collider$eve, _source2$collider$eve2;
936
-
937
866
  /* RigidBody events */
938
867
  (_source1$rigidBody$ev = source1.rigidBody.events) === null || _source1$rigidBody$ev === void 0 ? void 0 : (_source1$rigidBody$ev2 = _source1$rigidBody$ev.onCollisionEnter) === null || _source1$rigidBody$ev2 === void 0 ? void 0 : _source1$rigidBody$ev2.call(_source1$rigidBody$ev, _objectSpread2(_objectSpread2({}, collisionPayload1), {}, {
939
868
  manifold,
@@ -943,8 +872,8 @@ const Physics = props => {
943
872
  manifold,
944
873
  flipped
945
874
  }));
946
- /* Collider events */
947
875
 
876
+ /* Collider events */
948
877
  (_source1$collider$eve = source1.collider.events) === null || _source1$collider$eve === void 0 ? void 0 : (_source1$collider$eve2 = _source1$collider$eve.onCollisionEnter) === null || _source1$collider$eve2 === void 0 ? void 0 : _source1$collider$eve2.call(_source1$collider$eve, _objectSpread2(_objectSpread2({}, collisionPayload1), {}, {
949
878
  manifold,
950
879
  flipped
@@ -956,18 +885,16 @@ const Physics = props => {
956
885
  });
957
886
  } else {
958
887
  var _source1$rigidBody$ev3, _source1$rigidBody$ev4, _source2$rigidBody$ev3, _source2$rigidBody$ev4, _source1$collider$eve3, _source1$collider$eve4, _source2$collider$eve3, _source2$collider$eve4;
959
-
960
888
  (_source1$rigidBody$ev3 = source1.rigidBody.events) === null || _source1$rigidBody$ev3 === void 0 ? void 0 : (_source1$rigidBody$ev4 = _source1$rigidBody$ev3.onCollisionExit) === null || _source1$rigidBody$ev4 === void 0 ? void 0 : _source1$rigidBody$ev4.call(_source1$rigidBody$ev3, collisionPayload1);
961
889
  (_source2$rigidBody$ev3 = source2.rigidBody.events) === null || _source2$rigidBody$ev3 === void 0 ? void 0 : (_source2$rigidBody$ev4 = _source2$rigidBody$ev3.onCollisionExit) === null || _source2$rigidBody$ev4 === void 0 ? void 0 : _source2$rigidBody$ev4.call(_source2$rigidBody$ev3, collisionPayload2);
962
890
  (_source1$collider$eve3 = source1.collider.events) === null || _source1$collider$eve3 === void 0 ? void 0 : (_source1$collider$eve4 = _source1$collider$eve3.onCollisionExit) === null || _source1$collider$eve4 === void 0 ? void 0 : _source1$collider$eve4.call(_source1$collider$eve3, collisionPayload1);
963
891
  (_source2$collider$eve3 = source2.collider.events) === null || _source2$collider$eve3 === void 0 ? void 0 : (_source2$collider$eve4 = _source2$collider$eve3.onCollisionExit) === null || _source2$collider$eve4 === void 0 ? void 0 : _source2$collider$eve4.call(_source2$collider$eve3, collisionPayload2);
964
- } // Sensor Intersections
965
-
892
+ }
966
893
 
894
+ // Sensor Intersections
967
895
  if (started) {
968
896
  if (world.intersectionPair(source1.collider.object, source2.collider.object)) {
969
897
  var _source1$rigidBody$ev5, _source1$rigidBody$ev6, _source2$rigidBody$ev5, _source2$rigidBody$ev6, _source1$collider$eve5, _source1$collider$eve6, _source2$collider$eve5, _source2$collider$eve6;
970
-
971
898
  (_source1$rigidBody$ev5 = source1.rigidBody.events) === null || _source1$rigidBody$ev5 === void 0 ? void 0 : (_source1$rigidBody$ev6 = _source1$rigidBody$ev5.onIntersectionEnter) === null || _source1$rigidBody$ev6 === void 0 ? void 0 : _source1$rigidBody$ev6.call(_source1$rigidBody$ev5, collisionPayload1);
972
899
  (_source2$rigidBody$ev5 = source2.rigidBody.events) === null || _source2$rigidBody$ev5 === void 0 ? void 0 : (_source2$rigidBody$ev6 = _source2$rigidBody$ev5.onIntersectionEnter) === null || _source2$rigidBody$ev6 === void 0 ? void 0 : _source2$rigidBody$ev6.call(_source2$rigidBody$ev5, collisionPayload2);
973
900
  (_source1$collider$eve5 = source1.collider.events) === null || _source1$collider$eve5 === void 0 ? void 0 : (_source1$collider$eve6 = _source1$collider$eve5.onIntersectionEnter) === null || _source1$collider$eve6 === void 0 ? void 0 : _source1$collider$eve6.call(_source1$collider$eve5, collisionPayload1);
@@ -975,7 +902,6 @@ const Physics = props => {
975
902
  }
976
903
  } else {
977
904
  var _source1$rigidBody$ev7, _source1$rigidBody$ev8, _source2$rigidBody$ev7, _source2$rigidBody$ev8, _source1$collider$eve7, _source1$collider$eve8, _source2$collider$eve7, _source2$collider$eve8;
978
-
979
905
  (_source1$rigidBody$ev7 = source1.rigidBody.events) === null || _source1$rigidBody$ev7 === void 0 ? void 0 : (_source1$rigidBody$ev8 = _source1$rigidBody$ev7.onIntersectionExit) === null || _source1$rigidBody$ev8 === void 0 ? void 0 : _source1$rigidBody$ev8.call(_source1$rigidBody$ev7, collisionPayload1);
980
906
  (_source2$rigidBody$ev7 = source2.rigidBody.events) === null || _source2$rigidBody$ev7 === void 0 ? void 0 : (_source2$rigidBody$ev8 = _source2$rigidBody$ev7.onIntersectionExit) === null || _source2$rigidBody$ev8 === void 0 ? void 0 : _source2$rigidBody$ev8.call(_source2$rigidBody$ev7, collisionPayload2);
981
907
  (_source1$collider$eve7 = source1.collider.events) === null || _source1$collider$eve7 === void 0 ? void 0 : (_source1$collider$eve8 = _source1$collider$eve7.onIntersectionExit) === null || _source1$collider$eve8 === void 0 ? void 0 : _source1$collider$eve8.call(_source1$collider$eve7, collisionPayload1);
@@ -984,14 +910,13 @@ const Physics = props => {
984
910
  });
985
911
  eventQueue.drainContactForceEvents(event => {
986
912
  var _source1$rigidBody$ev9, _source1$rigidBody$ev10, _source2$rigidBody$ev9, _source2$rigidBody$ev10, _source1$collider$eve9, _source1$collider$eve10, _source2$collider$eve9, _source2$collider$eve10;
987
-
988
913
  const source1 = getSourceFromColliderHandle(event.collider1());
989
- const source2 = getSourceFromColliderHandle(event.collider2()); // Collision Events
914
+ const source2 = getSourceFromColliderHandle(event.collider2());
990
915
 
916
+ // Collision Events
991
917
  if (!(source1 !== null && source1 !== void 0 && source1.collider.object) || !(source2 !== null && source2 !== void 0 && source2.collider.object)) {
992
918
  return;
993
919
  }
994
-
995
920
  const collisionPayload1 = getCollisionPayloadFromSource(source1, source2);
996
921
  const collisionPayload2 = getCollisionPayloadFromSource(source2, source1);
997
922
  (_source1$rigidBody$ev9 = source1.rigidBody.events) === null || _source1$rigidBody$ev9 === void 0 ? void 0 : (_source1$rigidBody$ev10 = _source1$rigidBody$ev9.onContactForce) === null || _source1$rigidBody$ev10 === void 0 ? void 0 : _source1$rigidBody$ev10.call(_source1$rigidBody$ev9, _objectSpread2(_objectSpread2({}, collisionPayload1), {}, {
@@ -1058,41 +983,44 @@ const Physics = props => {
1058
983
  };
1059
984
 
1060
985
  function _extends() {
1061
- _extends = Object.assign ? Object.assign.bind() : function (target) {
1062
- for (var i = 1; i < arguments.length; i++) {
1063
- var source = arguments[i];
1064
-
1065
- for (var key in source) {
1066
- if (Object.prototype.hasOwnProperty.call(source, key)) {
1067
- target[key] = source[key];
1068
- }
1069
- }
986
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
987
+ for (var e = 1; e < arguments.length; e++) {
988
+ var t = arguments[e];
989
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
1070
990
  }
1071
-
1072
- return target;
1073
- };
1074
- return _extends.apply(this, arguments);
991
+ return n;
992
+ }, _extends.apply(null, arguments);
1075
993
  }
1076
994
 
995
+ // Need to catch the case where forwardedRef is a function... how to do that?
996
+ const useForwardedRef = (forwardedRef, defaultValue = null) => {
997
+ const innerRef = useRef(defaultValue);
998
+
999
+ // Update the forwarded ref when the inner ref changes
1000
+ if (forwardedRef && typeof forwardedRef !== "function") {
1001
+ if (!forwardedRef.current) {
1002
+ forwardedRef.current = innerRef.current;
1003
+ }
1004
+ return forwardedRef;
1005
+ }
1006
+ return innerRef;
1007
+ };
1008
+
1077
1009
  /**
1078
1010
  * Initiate an instance and return a safe getter
1079
1011
  */
1080
-
1081
1012
  const useImperativeInstance = (createFn, destroyFn, dependencyList) => {
1082
- const ref = useRef();
1013
+ const ref = useRef(undefined);
1083
1014
  const getInstance = useCallback(() => {
1084
1015
  if (!ref.current) {
1085
1016
  ref.current = createFn();
1086
1017
  }
1087
-
1088
1018
  return ref.current;
1089
1019
  }, dependencyList);
1090
1020
  useEffect(() => {
1091
1021
  // Save the destroy function and instance
1092
1022
  const instance = getInstance();
1093
-
1094
1023
  const destroy = () => destroyFn(instance);
1095
-
1096
1024
  return () => {
1097
1025
  destroy();
1098
1026
  ref.current = undefined;
@@ -1101,102 +1029,238 @@ const useImperativeInstance = (createFn, destroyFn, dependencyList) => {
1101
1029
  return getInstance;
1102
1030
  };
1103
1031
 
1104
- /**
1105
- * Takes an object resembling a Vector3 and returs a Three.Vector3
1106
- * @category Math helpers
1107
- */
1108
-
1109
- const vec3 = ({
1110
- x,
1111
- y,
1112
- z
1113
- } = {
1114
- x: 0,
1115
- y: 0,
1116
- z: 0
1117
- }) => {
1118
- return new Vector3(x, y, z);
1119
- };
1120
- /**
1121
- * Takes an object resembling a Quaternion and returs a Three.Quaternion
1122
- * @category Math helpers
1123
- */
1032
+ const rigidBodyDescFromOptions = options => {
1033
+ var _options$canSleep;
1034
+ const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
1035
+ const desc = new RigidBodyDesc(type);
1124
1036
 
1125
- const quat = ({
1126
- x,
1127
- y,
1128
- z,
1129
- w
1130
- } = {
1131
- x: 0,
1132
- y: 0,
1133
- z: 0,
1134
- w: 1
1135
- }) => {
1136
- return new Quaternion(x, y, z, w);
1037
+ // Apply immutable options
1038
+ desc.canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
1039
+ return desc;
1137
1040
  };
1138
- /**
1139
- * Takes an object resembling an Euler and returs a Three.Euler
1140
- * @category Math helpers
1141
- */
1142
-
1143
- const euler = ({
1144
- x,
1145
- y,
1146
- z
1147
- } = {
1148
- x: 0,
1149
- y: 0,
1150
- z: 0
1041
+ const createRigidBodyState = ({
1042
+ rigidBody,
1043
+ object,
1044
+ setMatrix,
1045
+ getMatrix,
1046
+ worldScale,
1047
+ meshType: _meshType = "mesh"
1151
1048
  }) => {
1152
- return new Euler(x, y, z);
1153
- };
1154
-
1155
- const useForwardedRef = (forwardedRef, defaultValue = null) => {
1156
- const innerRef = useRef(defaultValue); // Update the forwarded ref when the inner ref changes
1157
-
1158
- if (forwardedRef && typeof forwardedRef !== "function") {
1159
- if (!forwardedRef.current) {
1160
- forwardedRef.current = innerRef.current;
1161
- }
1162
-
1163
- return forwardedRef;
1164
- }
1165
-
1166
- return innerRef;
1049
+ object.updateWorldMatrix(true, false);
1050
+ const invertedWorldMatrix = object.parent.matrixWorld.clone().invert();
1051
+ return {
1052
+ object,
1053
+ rigidBody,
1054
+ invertedWorldMatrix,
1055
+ setMatrix: setMatrix ? setMatrix : matrix => {
1056
+ object.matrix.copy(matrix);
1057
+ },
1058
+ getMatrix: getMatrix ? getMatrix : matrix => matrix.copy(object.matrix),
1059
+ scale: worldScale || object.getWorldScale(_scale).clone(),
1060
+ isSleeping: false,
1061
+ meshType: _meshType
1062
+ };
1167
1063
  };
1168
-
1169
- /**
1170
- * A collider is a shape that can be attached to a rigid body to define its physical properties.
1171
- * @internal
1172
- */
1173
- const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwardedRef) => {
1174
- const {
1175
- children,
1176
- position,
1177
- rotation,
1178
- quaternion,
1179
- scale,
1180
- name
1181
- } = props;
1182
- const {
1183
- world,
1184
- colliderEvents,
1185
- colliderStates
1186
- } = useRapier();
1187
- const rigidBodyContext = useRigidBodyContext();
1188
- const colliderRef = useForwardedRef(forwardedRef);
1189
- const objectRef = useRef(null); // We spread the props out here to make sure that the ref is updated when the props change.
1190
-
1191
- const immutablePropArray = immutableColliderOptions.flatMap(key => Array.isArray(props[key]) ? [...props[key]] : props[key]);
1192
- const getInstance = useImperativeInstance(() => {
1193
- const worldScale = objectRef.current.getWorldScale(vec3());
1194
- const collider = createColliderFromOptions(props, world, worldScale, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.getRigidBody);
1195
-
1196
- if (typeof forwardedRef == "function") {
1197
- forwardedRef(collider);
1198
- }
1199
-
1064
+ const immutableRigidBodyOptions = ["args", "colliders", "canSleep"];
1065
+ const mutableRigidBodyOptions = {
1066
+ gravityScale: (rb, value) => {
1067
+ rb.setGravityScale(value, true);
1068
+ },
1069
+ additionalSolverIterations(rb, value) {
1070
+ rb.setAdditionalSolverIterations(value);
1071
+ },
1072
+ linearDamping: (rb, value) => {
1073
+ rb.setLinearDamping(value);
1074
+ },
1075
+ angularDamping: (rb, value) => {
1076
+ rb.setAngularDamping(value);
1077
+ },
1078
+ dominanceGroup: (rb, value) => {
1079
+ rb.setDominanceGroup(value);
1080
+ },
1081
+ enabledRotations: (rb, [x, y, z]) => {
1082
+ rb.setEnabledRotations(x, y, z, true);
1083
+ },
1084
+ enabledTranslations: (rb, [x, y, z]) => {
1085
+ rb.setEnabledTranslations(x, y, z, true);
1086
+ },
1087
+ lockRotations: (rb, value) => {
1088
+ rb.lockRotations(value, true);
1089
+ },
1090
+ lockTranslations: (rb, value) => {
1091
+ rb.lockTranslations(value, true);
1092
+ },
1093
+ angularVelocity: (rb, [x, y, z]) => {
1094
+ rb.setAngvel({
1095
+ x,
1096
+ y,
1097
+ z
1098
+ }, true);
1099
+ },
1100
+ linearVelocity: (rb, [x, y, z]) => {
1101
+ rb.setLinvel({
1102
+ x,
1103
+ y,
1104
+ z
1105
+ }, true);
1106
+ },
1107
+ ccd: (rb, value) => {
1108
+ rb.enableCcd(value);
1109
+ },
1110
+ softCcdPrediction: (rb, value) => {
1111
+ rb.setSoftCcdPrediction(value);
1112
+ },
1113
+ userData: (rb, value) => {
1114
+ rb.userData = value;
1115
+ },
1116
+ type(rb, value) {
1117
+ rb.setBodyType(rigidBodyTypeFromString(value), true);
1118
+ },
1119
+ position: () => {},
1120
+ rotation: () => {},
1121
+ quaternion: () => {},
1122
+ scale: () => {}
1123
+ };
1124
+ const mutableRigidBodyOptionKeys = Object.keys(mutableRigidBodyOptions);
1125
+ const setRigidBodyOptions = (rigidBody, options, states, updateTranslations = true) => {
1126
+ if (!rigidBody) {
1127
+ return;
1128
+ }
1129
+ const state = states.get(rigidBody.handle);
1130
+ if (state) {
1131
+ if (updateTranslations) {
1132
+ state.object.updateWorldMatrix(true, false);
1133
+ _matrix4.copy(state.object.matrixWorld).decompose(_position, _rotation, _scale);
1134
+ rigidBody.setTranslation(_position, false);
1135
+ rigidBody.setRotation(_rotation, false);
1136
+ }
1137
+ mutableRigidBodyOptionKeys.forEach(key => {
1138
+ if (key in options) {
1139
+ mutableRigidBodyOptions[key](rigidBody, options[key]);
1140
+ }
1141
+ });
1142
+ }
1143
+ };
1144
+ const useUpdateRigidBodyOptions = (getRigidBody, props, states, updateTranslations = true) => {
1145
+ // TODO: Improve this, split each prop into its own effect
1146
+ const mutablePropsAsFlatArray = useMemo(() => mutableRigidBodyOptionKeys.flatMap(key => {
1147
+ return vectorToTuple(props[key]);
1148
+ }), [props]);
1149
+ useEffect(() => {
1150
+ const rigidBody = getRigidBody();
1151
+ setRigidBodyOptions(rigidBody, props, states, updateTranslations);
1152
+ }, mutablePropsAsFlatArray);
1153
+ };
1154
+ const useRigidBodyEvents = (getRigidBody, props, events) => {
1155
+ const {
1156
+ onWake,
1157
+ onSleep,
1158
+ onCollisionEnter,
1159
+ onCollisionExit,
1160
+ onIntersectionEnter,
1161
+ onIntersectionExit,
1162
+ onContactForce
1163
+ } = props;
1164
+ const eventHandlers = {
1165
+ onWake,
1166
+ onSleep,
1167
+ onCollisionEnter,
1168
+ onCollisionExit,
1169
+ onIntersectionEnter,
1170
+ onIntersectionExit,
1171
+ onContactForce
1172
+ };
1173
+ useEffect(() => {
1174
+ const rigidBody = getRigidBody();
1175
+ events.set(rigidBody.handle, eventHandlers);
1176
+ return () => {
1177
+ events.delete(rigidBody.handle);
1178
+ };
1179
+ }, [onWake, onSleep, onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit, onContactForce]);
1180
+ };
1181
+
1182
+ /**
1183
+ * Takes an object resembling a Vector3 and returs a Three.Vector3
1184
+ * @category Math helpers
1185
+ */
1186
+ const vec3 = ({
1187
+ x,
1188
+ y,
1189
+ z
1190
+ } = {
1191
+ x: 0,
1192
+ y: 0,
1193
+ z: 0
1194
+ }) => {
1195
+ return new Vector3(x, y, z);
1196
+ };
1197
+
1198
+ /**
1199
+ * Takes an object resembling a Quaternion and returs a Three.Quaternion
1200
+ * @category Math helpers
1201
+ */
1202
+ const quat = ({
1203
+ x,
1204
+ y,
1205
+ z,
1206
+ w
1207
+ } = {
1208
+ x: 0,
1209
+ y: 0,
1210
+ z: 0,
1211
+ w: 1
1212
+ }) => {
1213
+ return new Quaternion(x, y, z, w);
1214
+ };
1215
+
1216
+ /**
1217
+ * Takes an object resembling an Euler and returs a Three.Euler
1218
+ * @category Math helpers
1219
+ */
1220
+ const euler = ({
1221
+ x,
1222
+ y,
1223
+ z
1224
+ } = {
1225
+ x: 0,
1226
+ y: 0,
1227
+ z: 0
1228
+ }) => {
1229
+ return new Euler(x, y, z);
1230
+ };
1231
+
1232
+ /**
1233
+ * A collider is a shape that can be attached to a rigid body to define its physical properties.
1234
+ * @internal
1235
+ */
1236
+ const AnyCollider = /*#__PURE__*/memo(props => {
1237
+ const {
1238
+ children,
1239
+ position,
1240
+ rotation,
1241
+ quaternion,
1242
+ scale,
1243
+ name
1244
+ } = props;
1245
+ const {
1246
+ world,
1247
+ colliderEvents,
1248
+ colliderStates
1249
+ } = useRapier();
1250
+ const rigidBodyContext = useRigidBodyContext();
1251
+ const colliderRef = useForwardedRef(props.ref);
1252
+ const objectRef = useRef(null);
1253
+
1254
+ // We spread the props out here to make sure that the ref is updated when the props change.
1255
+ const immutablePropArray = immutableColliderOptions.flatMap(key =>
1256
+ // Array.isArray(props[key]) ? [...props[key]] : props[key]
1257
+ Array.isArray(props[key]) ? props[key] : [props[key]]);
1258
+ const getInstance = useImperativeInstance(() => {
1259
+ const worldScale = objectRef.current.getWorldScale(vec3());
1260
+ const collider = createColliderFromOptions(props, world, worldScale, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.getRigidBody);
1261
+ if (typeof props.ref == "function") {
1262
+ props.ref(collider);
1263
+ }
1200
1264
  colliderRef.current = collider;
1201
1265
  return collider;
1202
1266
  }, collider => {
@@ -1224,8 +1288,7 @@ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwarded
1224
1288
  ref: objectRef,
1225
1289
  name: name
1226
1290
  }, children);
1227
- }));
1228
-
1291
+ });
1229
1292
  /**
1230
1293
  * A cuboid collider shape
1231
1294
  * @category Colliders
@@ -1237,7 +1300,6 @@ const CuboidCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1237
1300
  }));
1238
1301
  });
1239
1302
  CuboidCollider.displayName = "CuboidCollider";
1240
-
1241
1303
  /**
1242
1304
  * A round cuboid collider shape
1243
1305
  * @category Colliders
@@ -1247,7 +1309,6 @@ const RoundCuboidCollider = /*#__PURE__*/React.forwardRef((props, ref) => /*#__P
1247
1309
  ref: ref
1248
1310
  })));
1249
1311
  RoundCuboidCollider.displayName = "RoundCuboidCollider";
1250
-
1251
1312
  /**
1252
1313
  * A ball collider shape
1253
1314
  * @category Colliders
@@ -1257,7 +1318,6 @@ const BallCollider = /*#__PURE__*/React.forwardRef((props, ref) => /*#__PURE__*/
1257
1318
  ref: ref
1258
1319
  })));
1259
1320
  BallCollider.displayName = "BallCollider";
1260
-
1261
1321
  /**
1262
1322
  * A capsule collider shape
1263
1323
  * @category Colliders
@@ -1267,7 +1327,6 @@ const CapsuleCollider = /*#__PURE__*/React.forwardRef((props, ref) => /*#__PURE_
1267
1327
  ref: ref
1268
1328
  })));
1269
1329
  CapsuleCollider.displayName = "CapsuleCollider";
1270
-
1271
1330
  /**
1272
1331
  * A heightfield collider shape
1273
1332
  * @category Colliders
@@ -1277,7 +1336,6 @@ const HeightfieldCollider = /*#__PURE__*/React.forwardRef((props, ref) => /*#__P
1277
1336
  ref: ref
1278
1337
  })));
1279
1338
  HeightfieldCollider.displayName = "HeightfieldCollider";
1280
-
1281
1339
  /**
1282
1340
  * A trimesh collider shape
1283
1341
  * @category Colliders
@@ -1287,7 +1345,6 @@ const TrimeshCollider = /*#__PURE__*/React.forwardRef((props, ref) => /*#__PURE_
1287
1345
  ref: ref
1288
1346
  })));
1289
1347
  TrimeshCollider.displayName = "TrimeshCollider";
1290
-
1291
1348
  /**
1292
1349
  * A cone collider shape
1293
1350
  * @category Colliders
@@ -1297,7 +1354,6 @@ const ConeCollider = /*#__PURE__*/React.forwardRef((props, ref) => /*#__PURE__*/
1297
1354
  ref: ref
1298
1355
  })));
1299
1356
  ConeCollider.displayName = "ConeCollider";
1300
-
1301
1357
  /**
1302
1358
  * A round cylinder collider shape
1303
1359
  * @category Colliders
@@ -1307,7 +1363,6 @@ const RoundConeCollider = /*#__PURE__*/React.forwardRef((props, ref) => /*#__PUR
1307
1363
  ref: ref
1308
1364
  })));
1309
1365
  RoundConeCollider.displayName = "RoundConeCollider";
1310
-
1311
1366
  /**
1312
1367
  * A cylinder collider shape
1313
1368
  * @category Colliders
@@ -1317,7 +1372,6 @@ const CylinderCollider = /*#__PURE__*/React.forwardRef((props, ref) => /*#__PURE
1317
1372
  ref: ref
1318
1373
  })));
1319
1374
  CylinderCollider.displayName = "CylinderCollider";
1320
-
1321
1375
  /**
1322
1376
  * A round cylinder collider shape
1323
1377
  * @category Colliders
@@ -1327,7 +1381,6 @@ const RoundCylinderCollider = /*#__PURE__*/React.forwardRef((props, ref) => /*#_
1327
1381
  ref: ref
1328
1382
  })));
1329
1383
  CylinderCollider.displayName = "RoundCylinderCollider";
1330
-
1331
1384
  /**
1332
1385
  * A convex hull collider shape
1333
1386
  * @category Colliders
@@ -1338,187 +1391,27 @@ const ConvexHullCollider = /*#__PURE__*/React.forwardRef((props, ref) => /*#__PU
1338
1391
  })));
1339
1392
  ConvexHullCollider.displayName = "ConvexHullCollider";
1340
1393
 
1341
- const rigidBodyDescFromOptions = options => {
1342
- var _options$canSleep;
1343
-
1344
- const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
1345
- const desc = new RigidBodyDesc(type); // Apply immutable options
1346
-
1347
- desc.canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
1348
- return desc;
1349
- };
1350
- const createRigidBodyState = ({
1351
- rigidBody,
1352
- object,
1353
- setMatrix,
1354
- getMatrix,
1355
- worldScale,
1356
- meshType: _meshType = "mesh"
1357
- }) => {
1358
- object.updateWorldMatrix(true, false);
1359
- const invertedWorldMatrix = object.parent.matrixWorld.clone().invert();
1360
- return {
1361
- object,
1362
- rigidBody,
1363
- invertedWorldMatrix,
1364
- setMatrix: setMatrix ? setMatrix : matrix => {
1365
- object.matrix.copy(matrix);
1366
- },
1367
- getMatrix: getMatrix ? getMatrix : matrix => matrix.copy(object.matrix),
1368
- scale: worldScale || object.getWorldScale(_scale).clone(),
1369
- isSleeping: false,
1370
- meshType: _meshType
1371
- };
1372
- };
1373
- const immutableRigidBodyOptions = ["args", "colliders", "canSleep"];
1374
- const mutableRigidBodyOptions = {
1375
- gravityScale: (rb, value) => {
1376
- rb.setGravityScale(value, true);
1377
- },
1378
-
1379
- additionalSolverIterations(rb, value) {
1380
- rb.setAdditionalSolverIterations(value);
1381
- },
1382
-
1383
- linearDamping: (rb, value) => {
1384
- rb.setLinearDamping(value);
1385
- },
1386
- angularDamping: (rb, value) => {
1387
- rb.setAngularDamping(value);
1388
- },
1389
- dominanceGroup: (rb, value) => {
1390
- rb.setDominanceGroup(value);
1391
- },
1392
- enabledRotations: (rb, [x, y, z]) => {
1393
- rb.setEnabledRotations(x, y, z, true);
1394
- },
1395
- enabledTranslations: (rb, [x, y, z]) => {
1396
- rb.setEnabledTranslations(x, y, z, true);
1397
- },
1398
- lockRotations: (rb, value) => {
1399
- rb.lockRotations(value, true);
1400
- },
1401
- lockTranslations: (rb, value) => {
1402
- rb.lockTranslations(value, true);
1403
- },
1404
- angularVelocity: (rb, [x, y, z]) => {
1405
- rb.setAngvel({
1406
- x,
1407
- y,
1408
- z
1409
- }, true);
1410
- },
1411
- linearVelocity: (rb, [x, y, z]) => {
1412
- rb.setLinvel({
1413
- x,
1414
- y,
1415
- z
1416
- }, true);
1417
- },
1418
- ccd: (rb, value) => {
1419
- rb.enableCcd(value);
1420
- },
1421
- softCcdPrediction: (rb, value) => {
1422
- rb.setSoftCcdPrediction(value);
1423
- },
1424
- userData: (rb, value) => {
1425
- rb.userData = value;
1426
- },
1427
-
1428
- type(rb, value) {
1429
- rb.setBodyType(rigidBodyTypeFromString(value), true);
1430
- },
1431
-
1432
- position: () => {},
1433
- rotation: () => {},
1434
- quaternion: () => {},
1435
- scale: () => {}
1436
- };
1437
- const mutableRigidBodyOptionKeys = Object.keys(mutableRigidBodyOptions);
1438
- const setRigidBodyOptions = (rigidBody, options, states, updateTranslations = true) => {
1439
- if (!rigidBody) {
1440
- return;
1441
- }
1442
-
1443
- const state = states.get(rigidBody.handle);
1444
-
1445
- if (state) {
1446
- if (updateTranslations) {
1447
- state.object.updateWorldMatrix(true, false);
1448
-
1449
- _matrix4.copy(state.object.matrixWorld).decompose(_position, _rotation, _scale);
1450
-
1451
- rigidBody.setTranslation(_position, false);
1452
- rigidBody.setRotation(_rotation, false);
1453
- }
1454
-
1455
- mutableRigidBodyOptionKeys.forEach(key => {
1456
- if (key in options) {
1457
- mutableRigidBodyOptions[key](rigidBody, options[key]);
1458
- }
1459
- });
1460
- }
1461
- };
1462
- const useUpdateRigidBodyOptions = (getRigidBody, props, states, updateTranslations = true) => {
1463
- // TODO: Improve this, split each prop into its own effect
1464
- const mutablePropsAsFlatArray = useMemo(() => mutableRigidBodyOptionKeys.flatMap(key => {
1465
- return vectorToTuple(props[key]);
1466
- }), [props]);
1467
- useEffect(() => {
1468
- const rigidBody = getRigidBody();
1469
- setRigidBodyOptions(rigidBody, props, states, updateTranslations);
1470
- }, mutablePropsAsFlatArray);
1471
- };
1472
- const useRigidBodyEvents = (getRigidBody, props, events) => {
1473
- const {
1474
- onWake,
1475
- onSleep,
1476
- onCollisionEnter,
1477
- onCollisionExit,
1478
- onIntersectionEnter,
1479
- onIntersectionExit,
1480
- onContactForce
1481
- } = props;
1482
- const eventHandlers = {
1483
- onWake,
1484
- onSleep,
1485
- onCollisionEnter,
1486
- onCollisionExit,
1487
- onIntersectionEnter,
1488
- onIntersectionExit,
1489
- onContactForce
1490
- };
1491
- useEffect(() => {
1492
- const rigidBody = getRigidBody();
1493
- events.set(rigidBody.handle, eventHandlers);
1494
- return () => {
1495
- events.delete(rigidBody.handle);
1496
- };
1497
- }, [onWake, onSleep, onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit, onContactForce]);
1498
- };
1499
-
1500
- const _excluded$1 = ["children", "type", "position", "rotation", "scale", "quaternion", "transformState"];
1394
+ const _excluded$1 = ["ref", "children", "type", "position", "rotation", "scale", "quaternion", "transformState"];
1501
1395
  const RigidBodyContext = /*#__PURE__*/createContext(undefined);
1502
1396
  const useRigidBodyContext = () => useContext(RigidBodyContext);
1503
-
1504
1397
  /**
1505
1398
  * A rigid body is a physical object that can be simulated by the physics engine.
1506
1399
  * @category Components
1507
1400
  */
1508
- const RigidBody = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwardedRef) => {
1401
+ const RigidBody = /*#__PURE__*/memo(props => {
1509
1402
  const {
1510
- children,
1511
- type,
1512
- position,
1513
- rotation,
1514
- scale,
1515
- quaternion,
1516
- transformState
1517
- } = props,
1518
- objectProps = _objectWithoutProperties(props, _excluded$1);
1519
-
1403
+ ref,
1404
+ children,
1405
+ type,
1406
+ position,
1407
+ rotation,
1408
+ scale,
1409
+ quaternion,
1410
+ transformState
1411
+ } = props,
1412
+ objectProps = _objectWithoutProperties(props, _excluded$1);
1520
1413
  const objectRef = useRef(null);
1521
- const rigidBodyRef = useForwardedRef(forwardedRef);
1414
+ const rigidBodyRef = useForwardedRef(ref);
1522
1415
  const {
1523
1416
  world,
1524
1417
  rigidBodyStates,
@@ -1533,24 +1426,24 @@ const RigidBody = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwardedRe
1533
1426
  const immutablePropArray = immutableRigidBodyOptions.flatMap(key => {
1534
1427
  return Array.isArray(mergedOptions[key]) ? [...mergedOptions[key]] : mergedOptions[key];
1535
1428
  });
1536
- const childColliderProps = useChildColliderProps(objectRef, mergedOptions); // Provide a way to eagerly create rigidbody
1429
+ const childColliderProps = useChildColliderProps(objectRef, mergedOptions);
1537
1430
 
1431
+ // Provide a way to eagerly create rigidbody
1538
1432
  const getRigidBody = useImperativeInstance(() => {
1539
1433
  const desc = rigidBodyDescFromOptions(mergedOptions);
1540
1434
  const rigidBody = world.createRigidBody(desc);
1541
-
1542
- if (typeof forwardedRef === "function") {
1543
- forwardedRef(rigidBody);
1435
+ if (typeof ref === "function") {
1436
+ ref(rigidBody);
1544
1437
  }
1545
-
1546
1438
  rigidBodyRef.current = rigidBody;
1547
1439
  return rigidBody;
1548
1440
  }, rigidBody => {
1549
1441
  if (world.getRigidBody(rigidBody.handle)) {
1550
1442
  world.removeRigidBody(rigidBody);
1551
1443
  }
1552
- }, immutablePropArray); // Only provide a object state after the ref has been set
1444
+ }, immutablePropArray);
1553
1445
 
1446
+ // Only provide a object state after the ref has been set
1554
1447
  useEffect(() => {
1555
1448
  const rigidBody = getRigidBody();
1556
1449
  const state = createRigidBodyState({
@@ -1583,7 +1476,7 @@ const RigidBody = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwardedRe
1583
1476
  }), children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React.createElement(AnyCollider, _extends({
1584
1477
  key: index
1585
1478
  }, colliderProps)))));
1586
- }));
1479
+ });
1587
1480
  RigidBody.displayName = "RigidBody";
1588
1481
 
1589
1482
  /**
@@ -1620,52 +1513,52 @@ const MeshCollider = /*#__PURE__*/memo(props => {
1620
1513
  });
1621
1514
  MeshCollider.displayName = "MeshCollider";
1622
1515
 
1623
- const _excluded = ["children", "instances", "colliderNodes", "position", "rotation", "quaternion", "scale"];
1624
- const InstancedRigidBodies = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwardedRef) => {
1625
- const rigidBodiesRef = useForwardedRef(forwardedRef, []);
1516
+ const _excluded = ["ref"],
1517
+ _excluded2 = ["children", "instances", "colliderNodes", "position", "rotation", "quaternion", "scale"];
1518
+ const InstancedRigidBodies = /*#__PURE__*/memo(_ref => {
1519
+ let {
1520
+ ref
1521
+ } = _ref,
1522
+ props = _objectWithoutProperties(_ref, _excluded);
1523
+ const rigidBodiesRef = useForwardedRef(ref, []);
1626
1524
  const objectRef = useRef(null);
1627
1525
  const instanceWrapperRef = useRef(null);
1628
-
1629
1526
  const {
1630
- // instanced props
1631
- children,
1632
- instances,
1633
- colliderNodes = [],
1634
- // wrapper object props
1635
- position,
1636
- rotation,
1637
- quaternion,
1638
- scale
1639
- } = props,
1640
- rigidBodyProps = _objectWithoutProperties(props, _excluded);
1641
-
1527
+ // instanced props
1528
+ children,
1529
+ instances,
1530
+ colliderNodes = [],
1531
+ // wrapper object props
1532
+ position,
1533
+ rotation,
1534
+ quaternion,
1535
+ scale
1536
+
1537
+ // rigid body specific props, and r3f-object props
1538
+ } = props,
1539
+ rigidBodyProps = _objectWithoutProperties(props, _excluded2);
1642
1540
  const childColliderProps = useChildColliderProps(objectRef, _objectSpread2(_objectSpread2({}, props), {}, {
1643
1541
  children: undefined
1644
1542
  }));
1645
-
1646
1543
  const getInstancedMesh = () => {
1647
1544
  const firstChild = instanceWrapperRef.current.children[0];
1648
-
1649
1545
  if (firstChild && "isInstancedMesh" in firstChild) {
1650
1546
  return firstChild;
1651
1547
  }
1652
-
1653
1548
  return undefined;
1654
1549
  };
1655
-
1656
1550
  useEffect(() => {
1657
1551
  const instancedMesh = getInstancedMesh();
1658
-
1659
1552
  if (instancedMesh) {
1660
1553
  instancedMesh.instanceMatrix.setUsage(DynamicDrawUsage);
1661
1554
  } else {
1662
1555
  console.warn("InstancedRigidBodies expects exactly one child, which must be an InstancedMesh");
1663
1556
  }
1664
- }, []); // Update the RigidBodyStates whenever the instances change
1557
+ }, []);
1665
1558
 
1559
+ // Update the RigidBodyStates whenever the instances change
1666
1560
  const applyInstancedState = (state, index) => {
1667
1561
  const instancedMesh = getInstancedMesh();
1668
-
1669
1562
  if (instancedMesh) {
1670
1563
  return _objectSpread2(_objectSpread2({}, state), {}, {
1671
1564
  getMatrix: matrix => {
@@ -1679,10 +1572,8 @@ const InstancedRigidBodies = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props,
1679
1572
  meshType: "instancedMesh"
1680
1573
  });
1681
1574
  }
1682
-
1683
1575
  return state;
1684
1576
  };
1685
-
1686
1577
  return /*#__PURE__*/React.createElement("object3D", _extends({
1687
1578
  ref: objectRef
1688
1579
  }, rigidBodyProps, {
@@ -1693,25 +1584,26 @@ const InstancedRigidBodies = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props,
1693
1584
  }), /*#__PURE__*/React.createElement("object3D", {
1694
1585
  ref: instanceWrapperRef
1695
1586
  }, children), instances === null || instances === void 0 ? void 0 : instances.map((instance, index) => /*#__PURE__*/React.createElement(RigidBody, _extends({}, rigidBodyProps, instance, {
1696
- ref: body => rigidBodiesRef.current[index] = body,
1587
+ ref: body => {
1588
+ rigidBodiesRef.current[index] = body;
1589
+ },
1697
1590
  transformState: state => applyInstancedState(state, index)
1698
1591
  }), /*#__PURE__*/React.createElement(React.Fragment, null, colliderNodes.map((node, index) => /*#__PURE__*/React.createElement(Fragment, {
1699
1592
  key: index
1700
1593
  }, node)), childColliderProps.map((colliderProps, colliderIndex) => /*#__PURE__*/React.createElement(AnyCollider, _extends({
1701
1594
  key: colliderIndex
1702
1595
  }, colliderProps)))))));
1703
- }));
1596
+ });
1704
1597
  InstancedRigidBodies.displayName = "InstancedRigidBodies";
1705
1598
 
1706
1599
  /**
1707
1600
  * @internal
1708
1601
  */
1709
-
1710
1602
  const useImpulseJoint = (body1, body2, params) => {
1711
1603
  const {
1712
1604
  world
1713
1605
  } = useRapier();
1714
- const jointRef = useRef();
1606
+ const jointRef = useRef(undefined);
1715
1607
  useImperativeInstance(() => {
1716
1608
  if (body1.current && body2.current) {
1717
1609
  const newJoint = world.createImpulseJoint(params, body1.current, body2.current, true);
@@ -1721,7 +1613,6 @@ const useImpulseJoint = (body1, body2, params) => {
1721
1613
  }, joint => {
1722
1614
  if (joint) {
1723
1615
  jointRef.current = undefined;
1724
-
1725
1616
  if (world.getImpulseJoint(joint.handle)) {
1726
1617
  world.removeImpulseJoint(joint, true);
1727
1618
  }
@@ -1729,6 +1620,7 @@ const useImpulseJoint = (body1, body2, params) => {
1729
1620
  }, []);
1730
1621
  return jointRef;
1731
1622
  };
1623
+
1732
1624
  /**
1733
1625
  * A fixed joint ensures that two rigid-bodies don't move relative to each other.
1734
1626
  * Fixed joints are characterized by one local frame (represented by an isometry) on each rigid-body.
@@ -1736,13 +1628,13 @@ const useImpulseJoint = (body1, body2, params) => {
1736
1628
  *
1737
1629
  * @category Hooks - Joints
1738
1630
  */
1739
-
1740
1631
  const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor, body2LocalFrame]) => {
1741
1632
  const {
1742
1633
  rapier
1743
1634
  } = useRapier();
1744
1635
  return useImpulseJoint(body1, body2, rapier.JointData.fixed(vector3ToRapierVector(body1Anchor), quaternionToRapierQuaternion(body1LocalFrame), vector3ToRapierVector(body2Anchor), quaternionToRapierQuaternion(body2LocalFrame)));
1745
1636
  };
1637
+
1746
1638
  /**
1747
1639
  * The spherical joint ensures that two points on the local-spaces of two rigid-bodies always coincide (it prevents any relative
1748
1640
  * translational motion at this points). This is typically used to simulate ragdolls arms, pendulums, etc.
@@ -1751,13 +1643,13 @@ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor,
1751
1643
  *
1752
1644
  * @category Hooks - Joints
1753
1645
  */
1754
-
1755
1646
  const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
1756
1647
  const {
1757
1648
  rapier
1758
1649
  } = useRapier();
1759
1650
  return useImpulseJoint(body1, body2, rapier.JointData.spherical(vector3ToRapierVector(body1Anchor), vector3ToRapierVector(body2Anchor)));
1760
1651
  };
1652
+
1761
1653
  /**
1762
1654
  * The revolute joint prevents any relative movement between two rigid-bodies, except for relative
1763
1655
  * rotations along one axis. This is typically used to simulate wheels, fans, etc.
@@ -1765,20 +1657,18 @@ const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
1765
1657
  *
1766
1658
  * @category Hooks - Joints
1767
1659
  */
1768
-
1769
1660
  const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis, limits]) => {
1770
1661
  const {
1771
1662
  rapier
1772
1663
  } = useRapier();
1773
1664
  const params = rapier.JointData.revolute(vector3ToRapierVector(body1Anchor), vector3ToRapierVector(body2Anchor), vector3ToRapierVector(axis));
1774
-
1775
1665
  if (limits) {
1776
1666
  params.limitsEnabled = true;
1777
1667
  params.limits = limits;
1778
1668
  }
1779
-
1780
1669
  return useImpulseJoint(body1, body2, params);
1781
1670
  };
1671
+
1782
1672
  /**
1783
1673
  * The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
1784
1674
  * It is characterized by one local anchor as well as one local axis on each rigid-body. In 3D, an optional
@@ -1786,25 +1676,22 @@ const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis, limits]
1786
1676
  *
1787
1677
  * @category Hooks - Joints
1788
1678
  */
1789
-
1790
1679
  const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis, limits]) => {
1791
1680
  const {
1792
1681
  rapier
1793
1682
  } = useRapier();
1794
1683
  const params = rapier.JointData.prismatic(vector3ToRapierVector(body1Anchor), vector3ToRapierVector(body2Anchor), vector3ToRapierVector(axis));
1795
-
1796
1684
  if (limits) {
1797
1685
  params.limitsEnabled = true;
1798
1686
  params.limits = limits;
1799
1687
  }
1800
-
1801
1688
  return useImpulseJoint(body1, body2, params);
1802
1689
  };
1690
+
1803
1691
  /**
1804
1692
  * The rope joint limits the max distance between two bodies.
1805
1693
  * @category Hooks - Joints
1806
1694
  */
1807
-
1808
1695
  const useRopeJoint = (body1, body2, [body1Anchor, body2Anchor, length]) => {
1809
1696
  const {
1810
1697
  rapier
@@ -1814,11 +1701,11 @@ const useRopeJoint = (body1, body2, [body1Anchor, body2Anchor, length]) => {
1814
1701
  const params = rapier.JointData.rope(length, vBody1Anchor, vBody2Anchor);
1815
1702
  return useImpulseJoint(body1, body2, params);
1816
1703
  };
1704
+
1817
1705
  /**
1818
1706
  * The spring joint applies a force proportional to the distance between two objects.
1819
1707
  * @category Hooks - Joints
1820
1708
  */
1821
-
1822
1709
  const useSpringJoint = (body1, body2, [body1Anchor, body2Anchor, restLength, stiffness, damping]) => {
1823
1710
  const {
1824
1711
  rapier
@@ -1862,7 +1749,6 @@ const useSpringJoint = (body1, body2, [body1Anchor, body2Anchor, restLength, sti
1862
1749
  * @returns An InteractionGroup bitmask.
1863
1750
  */
1864
1751
  const interactionGroups = (memberships, filters) => (bitmask(memberships) << 16) + (filters !== undefined ? bitmask(filters) : 0b1111111111111111);
1865
-
1866
1752
  const bitmask = groups => [groups].flat().reduce((acc, layer) => acc | 1 << layer, 0);
1867
1753
 
1868
1754
  export { AnyCollider, BallCollider, CapsuleCollider, ConeCollider, ConvexHullCollider, CuboidCollider, CylinderCollider, HeightfieldCollider, InstancedRigidBodies, MeshCollider, Physics, RigidBody, RoundConeCollider, RoundCuboidCollider, RoundCylinderCollider, TrimeshCollider, euler, interactionGroups, quat, useAfterPhysicsStep, useBeforePhysicsStep, useFixedJoint, useImpulseJoint, usePrismaticJoint, useRapier, useRevoluteJoint, useRopeJoint, useSphericalJoint, useSpringJoint, vec3 };