@react-three/rapier 0.14.0-rc.0 → 0.14.0-rc.2

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.
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var rapier3dCompat = require('@dimforge/rapier3d-compat');
6
6
  var fiber = require('@react-three/fiber');
7
- var React = require('react');
7
+ var React$1 = require('react');
8
8
  var three = require('three');
9
9
  var useAsset = require('use-asset');
10
10
  var threeStdlib = require('three-stdlib');
@@ -29,7 +29,7 @@ function _interopNamespace(e) {
29
29
  return Object.freeze(n);
30
30
  }
31
31
 
32
- var React__default = /*#__PURE__*/_interopDefault(React);
32
+ var React__default = /*#__PURE__*/_interopDefault(React$1);
33
33
 
34
34
  function _defineProperty(obj, key, value) {
35
35
  if (key in obj) {
@@ -167,7 +167,7 @@ const vectorToTuple = v => {
167
167
  return [v];
168
168
  };
169
169
  function useConst(initialValue) {
170
- const ref = React.useRef();
170
+ const ref = React$1.useRef();
171
171
 
172
172
  if (ref.current === undefined) {
173
173
  ref.current = {
@@ -178,27 +178,41 @@ function useConst(initialValue) {
178
178
  return ref.current.value;
179
179
  }
180
180
 
181
- const useRaf = callback => {
182
- const cb = React.useRef(callback);
183
- const raf = React.useRef(0);
184
- const lastFrame = React.useRef(0);
185
- React.useEffect(() => {
186
- cb.current = callback;
187
- }, [callback]);
188
- React.useEffect(() => {
189
- const loop = () => {
190
- const now = performance.now();
191
- const delta = now - lastFrame.current;
192
- raf.current = requestAnimationFrame(loop);
193
- cb.current(delta / 1000);
194
- lastFrame.current = now;
195
- };
181
+ function _objectWithoutPropertiesLoose(source, excluded) {
182
+ if (source == null) return {};
183
+ var target = {};
184
+ var sourceKeys = Object.keys(source);
185
+ var key, i;
196
186
 
197
- raf.current = requestAnimationFrame(loop);
198
- return () => cancelAnimationFrame(raf.current);
199
- }, []);
200
- };
187
+ for (i = 0; i < sourceKeys.length; i++) {
188
+ key = sourceKeys[i];
189
+ if (excluded.indexOf(key) >= 0) continue;
190
+ target[key] = source[key];
191
+ }
192
+
193
+ return target;
194
+ }
195
+
196
+ function _objectWithoutProperties(source, excluded) {
197
+ if (source == null) return {};
198
+ var target = _objectWithoutPropertiesLoose(source, excluded);
199
+ var key, i;
201
200
 
201
+ if (Object.getOwnPropertySymbols) {
202
+ var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
203
+
204
+ for (i = 0; i < sourceSymbolKeys.length; i++) {
205
+ key = sourceSymbolKeys[i];
206
+ if (excluded.indexOf(key) >= 0) continue;
207
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
208
+ target[key] = source[key];
209
+ }
210
+ }
211
+
212
+ return target;
213
+ }
214
+
215
+ const _excluded$2 = ["mass", "linearDamping", "angularDamping", "type", "onCollisionEnter", "onCollisionExit", "onIntersectionEnter", "onIntersectionExit", "onContactForce", "children", "canSleep", "ccd", "gravityScale"];
202
216
  const scaleColliderArgs = (shape, args, scale) => {
203
217
  const newArgs = args.slice(); // Heightfield uses a vector
204
218
 
@@ -330,10 +344,10 @@ const setColliderOptions = (collider, options, states) => {
330
344
  };
331
345
  const useUpdateColliderOptions = (getCollider, props, states) => {
332
346
  // TODO: Improve this, split each prop into its own effect
333
- const mutablePropsAsFlatArray = React.useMemo(() => mutableColliderOptionKeys.flatMap(key => {
347
+ const mutablePropsAsFlatArray = React$1.useMemo(() => mutableColliderOptionKeys.flatMap(key => {
334
348
  return vectorToTuple(props[key]);
335
349
  }), [props]);
336
- React.useEffect(() => {
350
+ React$1.useEffect(() => {
337
351
  const collider = getCollider();
338
352
  setColliderOptions(collider, props, states);
339
353
  }, mutablePropsAsFlatArray);
@@ -365,7 +379,7 @@ const createColliderPropsFromChildren = ({
365
379
  ignoreMeshColliders: _ignoreMeshColliders = true,
366
380
  options
367
381
  }) => {
368
- const colliderProps = [];
382
+ const childColliderProps = [];
369
383
  object.updateWorldMatrix(true, false);
370
384
  const invertedParentMatrixWorld = object.matrixWorld.clone().invert();
371
385
 
@@ -386,13 +400,16 @@ const createColliderPropsFromChildren = ({
386
400
  args,
387
401
  offset
388
402
  } = getColliderArgsFromGeometry(geometry, options.colliders || "cuboid");
389
- colliderProps.push(_objectSpread2(_objectSpread2({}, options), {}, {
403
+
404
+ const colliderProps = _objectSpread2(_objectSpread2({}, cleanRigidBodyPropsForCollider(options)), {}, {
390
405
  args: args,
391
406
  shape: shape,
392
407
  rotation: [rotationEuler.x, rotationEuler.y, rotationEuler.z],
393
408
  position: [_position.x + offset.x * worldScale.x, _position.y + offset.y * worldScale.y, _position.z + offset.z * worldScale.z],
394
409
  scale: [worldScale.x, worldScale.y, worldScale.z]
395
- }));
410
+ });
411
+
412
+ childColliderProps.push(colliderProps);
396
413
  }
397
414
  };
398
415
 
@@ -402,7 +419,7 @@ const createColliderPropsFromChildren = ({
402
419
  object.traverseVisible(colliderFromChild);
403
420
  }
404
421
 
405
- return colliderProps;
422
+ return childColliderProps;
406
423
  };
407
424
  const getColliderArgsFromGeometry = (geometry, colliders) => {
408
425
  switch (colliders) {
@@ -458,7 +475,17 @@ const getColliderArgsFromGeometry = (geometry, colliders) => {
458
475
  offset: new three.Vector3()
459
476
  };
460
477
  };
461
- const useColliderEvents = (getCollider, props, events) => {
478
+ const getActiveCollisionEventsFromProps = props => {
479
+ return {
480
+ collision: !!(props !== null && props !== void 0 && props.onCollisionEnter || props !== null && props !== void 0 && props.onCollisionExit || props !== null && props !== void 0 && props.onIntersectionEnter || props !== null && props !== void 0 && props.onIntersectionExit),
481
+ contactForce: !!(props !== null && props !== void 0 && props.onContactForce)
482
+ };
483
+ };
484
+ const useColliderEvents = (getCollider, props, events,
485
+ /**
486
+ * The RigidBody can pass down active events to the collider without attaching the event listners
487
+ */
488
+ activeEvents = {}) => {
462
489
  const {
463
490
  onCollisionEnter,
464
491
  onCollisionExit,
@@ -466,12 +493,16 @@ const useColliderEvents = (getCollider, props, events) => {
466
493
  onIntersectionExit,
467
494
  onContactForce
468
495
  } = props;
469
- React.useEffect(() => {
496
+ React$1.useEffect(() => {
470
497
  const collider = getCollider();
471
498
 
472
499
  if (collider) {
473
- const hasCollisionEvent = !!(onCollisionEnter || onCollisionExit || onIntersectionEnter || onIntersectionExit);
474
- const hasContactForceEvent = !!onContactForce;
500
+ const {
501
+ collision: collisionEventsActive,
502
+ contactForce: contactForceEventsActive
503
+ } = getActiveCollisionEventsFromProps(props);
504
+ const hasCollisionEvent = collisionEventsActive || activeEvents.collision;
505
+ const hasContactForceEvent = contactForceEventsActive || activeEvents.contactForce;
475
506
 
476
507
  if (hasCollisionEvent && hasContactForceEvent) {
477
508
  collider.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS | rapier3dCompat.ActiveEvents.CONTACT_FORCE_EVENTS);
@@ -495,12 +526,17 @@ const useColliderEvents = (getCollider, props, events) => {
495
526
  events.delete(collider.handle);
496
527
  }
497
528
  };
498
- }, [onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit, onContactForce]);
529
+ }, [onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit, onContactForce, activeEvents]);
530
+ };
531
+ const cleanRigidBodyPropsForCollider = (props = {}) => {
532
+ const rest = _objectWithoutProperties(props, _excluded$2);
533
+
534
+ return rest;
499
535
  };
500
536
 
501
537
  const useMutableCallback = fn => {
502
- const ref = React.useRef(fn);
503
- React.useEffect(() => {
538
+ const ref = React$1.useRef(fn);
539
+ React$1.useEffect(() => {
504
540
  ref.current = fn;
505
541
  }, [fn]);
506
542
  return ref;
@@ -513,7 +549,7 @@ const useMutableCallback = fn => {
513
549
 
514
550
 
515
551
  const useRapier = () => {
516
- return React.useContext(rapierContext);
552
+ return React$1.useContext(rapierContext);
517
553
  };
518
554
  /**
519
555
  * Registers a callback to be called before the physics step
@@ -525,7 +561,7 @@ const useBeforePhysicsStep = callback => {
525
561
  beforeStepCallbacks
526
562
  } = useRapier();
527
563
  const ref = useMutableCallback(callback);
528
- React.useEffect(() => {
564
+ React$1.useEffect(() => {
529
565
  beforeStepCallbacks.add(ref);
530
566
  return () => {
531
567
  beforeStepCallbacks.delete(ref);
@@ -542,7 +578,7 @@ const useAfterPhysicsStep = callback => {
542
578
  afterStepCallbacks
543
579
  } = useRapier();
544
580
  const ref = useMutableCallback(callback);
545
- React.useEffect(() => {
581
+ React$1.useEffect(() => {
546
582
  afterStepCallbacks.add(ref);
547
583
  return () => {
548
584
  afterStepCallbacks.delete(ref);
@@ -555,8 +591,8 @@ const useAfterPhysicsStep = callback => {
555
591
  */
556
592
 
557
593
  const useChildColliderProps = (ref, options, ignoreMeshColliders = true) => {
558
- const [colliderProps, setColliderProps] = React.useState([]);
559
- React.useEffect(() => {
594
+ const [colliderProps, setColliderProps] = React$1.useState([]);
595
+ React$1.useEffect(() => {
560
596
  const object = ref.current;
561
597
 
562
598
  if (object && options.colliders !== false) {
@@ -616,7 +652,7 @@ const applyAttractorForceOnRigidBody = (rigidBody, {
616
652
  }
617
653
  }
618
654
  };
619
- const Attractor = /*#__PURE__*/React.memo(props => {
655
+ const Attractor = /*#__PURE__*/React$1.memo(props => {
620
656
  const {
621
657
  position = [0, 0, 0],
622
658
  strength = 1,
@@ -628,8 +664,8 @@ const Attractor = /*#__PURE__*/React.memo(props => {
628
664
  const {
629
665
  attractorStates
630
666
  } = useRapier();
631
- const object = React.useRef(null);
632
- React.useEffect(() => {
667
+ const object = React$1.useRef(null);
668
+ React$1.useEffect(() => {
633
669
  var _object$current;
634
670
 
635
671
  let uuid = ((_object$current = object.current) === null || _object$current === void 0 ? void 0 : _object$current.uuid) || "_";
@@ -655,7 +691,62 @@ const Attractor = /*#__PURE__*/React.memo(props => {
655
691
  });
656
692
  });
657
693
 
658
- const rapierContext = /*#__PURE__*/React.createContext(undefined);
694
+ const useRaf = callback => {
695
+ const cb = React$1.useRef(callback);
696
+ const raf = React$1.useRef(0);
697
+ const lastFrame = React$1.useRef(0);
698
+ React$1.useEffect(() => {
699
+ cb.current = callback;
700
+ }, [callback]);
701
+ React$1.useEffect(() => {
702
+ const loop = () => {
703
+ const now = performance.now();
704
+ const delta = now - lastFrame.current;
705
+ raf.current = requestAnimationFrame(loop);
706
+ cb.current(delta / 1000);
707
+ lastFrame.current = now;
708
+ };
709
+
710
+ raf.current = requestAnimationFrame(loop);
711
+ return () => cancelAnimationFrame(raf.current);
712
+ }, []);
713
+ };
714
+
715
+ const UseFrameStepper = ({
716
+ onStep,
717
+ updatePriority
718
+ }) => {
719
+ fiber.useFrame((_, dt) => {
720
+ onStep(dt);
721
+ }, updatePriority);
722
+ return null;
723
+ };
724
+
725
+ const RafStepper = ({
726
+ onStep
727
+ }) => {
728
+ useRaf(dt => {
729
+ onStep(dt);
730
+ });
731
+ return null;
732
+ };
733
+
734
+ const FrameStepper = ({
735
+ onStep,
736
+ type,
737
+ updatePriority
738
+ }) => {
739
+ return type === "independent" ? /*#__PURE__*/React.createElement(RafStepper, {
740
+ onStep: onStep
741
+ }) : /*#__PURE__*/React.createElement(UseFrameStepper, {
742
+ onStep: onStep,
743
+ updatePriority: updatePriority
744
+ });
745
+ };
746
+
747
+ var FrameStepper$1 = /*#__PURE__*/React$1.memo(FrameStepper);
748
+
749
+ const rapierContext = /*#__PURE__*/React$1.createContext(undefined);
659
750
 
660
751
  const getCollisionPayloadFromSource = (target, other) => {
661
752
  var _target$collider$stat, _target$rigidBody$sta, _other$collider$state, _other$rigidBody$stat, _other$collider$state2, _other$rigidBody$stat2;
@@ -696,14 +787,16 @@ const Physics = ({
696
787
  children,
697
788
  timeStep: _timeStep = 1 / 60,
698
789
  paused: _paused = false,
699
- interpolate: _interpolate = true
790
+ interpolate: _interpolate = true,
791
+ updatePriority,
792
+ updateLoop: _updateLoop = "follow"
700
793
  }) => {
701
794
  const rapier = useAsset.useAsset(importRapier);
702
795
  const {
703
796
  invalidate
704
797
  } = fiber.useThree();
705
- const worldRef = React.useRef();
706
- const getWorldRef = React.useRef(() => {
798
+ const worldRef = React$1.useRef();
799
+ const getWorldRef = React$1.useRef(() => {
707
800
  if (!worldRef.current) {
708
801
  const world = new rapier.World(vectorArrayToVector3(_gravity));
709
802
  worldRef.current = world;
@@ -720,7 +813,7 @@ const Physics = ({
720
813
  const beforeStepCallbacks = useConst(() => new Set());
721
814
  const afterStepCallbacks = useConst(() => new Set()); // Init world
722
815
 
723
- React.useEffect(() => {
816
+ React$1.useEffect(() => {
724
817
  const world = getWorldRef.current();
725
818
  return () => {
726
819
  if (world) {
@@ -730,15 +823,15 @@ const Physics = ({
730
823
  };
731
824
  }, []); // Update gravity
732
825
 
733
- React.useEffect(() => {
826
+ React$1.useEffect(() => {
734
827
  const world = worldRef.current;
735
828
 
736
829
  if (world) {
737
830
  world.gravity = vectorArrayToVector3(_gravity);
738
831
  }
739
832
  }, [_gravity]);
740
- const api = React.useMemo(() => createWorldApi(getWorldRef), []);
741
- const getSourceFromColliderHandle = React.useCallback(handle => {
833
+ const api = React$1.useMemo(() => createWorldApi(getWorldRef), []);
834
+ const getSourceFromColliderHandle = React$1.useCallback(handle => {
742
835
  const world = worldRef.current;
743
836
 
744
837
  if (world) {
@@ -766,11 +859,11 @@ const Physics = ({
766
859
  return source;
767
860
  }
768
861
  }, []);
769
- const [steppingState] = React.useState({
862
+ const [steppingState] = React$1.useState({
770
863
  previousState: {},
771
864
  accumulator: 0
772
865
  });
773
- const step = React.useCallback(dt => {
866
+ const step = React$1.useCallback(dt => {
774
867
  const world = worldRef.current;
775
868
  if (!world) return;
776
869
  /* Check if the timestep is supposed to be variable. We'll do this here
@@ -982,14 +1075,11 @@ const Physics = ({
982
1075
  maxForceMagnitude: event.maxForceMagnitude()
983
1076
  }));
984
1077
  });
985
- world.forEachActiveRigidBody(body => {
1078
+ world.forEachActiveRigidBody(() => {
986
1079
  invalidate();
987
1080
  });
988
1081
  }, [_paused, _timeStep, _interpolate]);
989
- useRaf(dt => {
990
- if (!_paused) step(dt);
991
- });
992
- const context = React.useMemo(() => ({
1082
+ const context = React$1.useMemo(() => ({
993
1083
  rapier,
994
1084
  world: api,
995
1085
  physicsOptions: {
@@ -1006,9 +1096,18 @@ const Physics = ({
1006
1096
  isPaused: _paused,
1007
1097
  step
1008
1098
  }), [_paused, step]);
1099
+ const stepCallback = React$1.useCallback(delta => {
1100
+ if (!_paused) {
1101
+ step(delta);
1102
+ }
1103
+ }, [_paused, step]);
1009
1104
  return /*#__PURE__*/React__default["default"].createElement(rapierContext.Provider, {
1010
1105
  value: context
1011
- }, children);
1106
+ }, /*#__PURE__*/React__default["default"].createElement(FrameStepper$1, {
1107
+ onStep: stepCallback,
1108
+ type: _updateLoop,
1109
+ updatePriority: updatePriority
1110
+ }), children);
1012
1111
  };
1013
1112
 
1014
1113
  function _extends() {
@@ -1028,54 +1127,20 @@ function _extends() {
1028
1127
  return _extends.apply(this, arguments);
1029
1128
  }
1030
1129
 
1031
- function _objectWithoutPropertiesLoose(source, excluded) {
1032
- if (source == null) return {};
1033
- var target = {};
1034
- var sourceKeys = Object.keys(source);
1035
- var key, i;
1036
-
1037
- for (i = 0; i < sourceKeys.length; i++) {
1038
- key = sourceKeys[i];
1039
- if (excluded.indexOf(key) >= 0) continue;
1040
- target[key] = source[key];
1041
- }
1042
-
1043
- return target;
1044
- }
1045
-
1046
- function _objectWithoutProperties(source, excluded) {
1047
- if (source == null) return {};
1048
- var target = _objectWithoutPropertiesLoose(source, excluded);
1049
- var key, i;
1050
-
1051
- if (Object.getOwnPropertySymbols) {
1052
- var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
1053
-
1054
- for (i = 0; i < sourceSymbolKeys.length; i++) {
1055
- key = sourceSymbolKeys[i];
1056
- if (excluded.indexOf(key) >= 0) continue;
1057
- if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
1058
- target[key] = source[key];
1059
- }
1060
- }
1061
-
1062
- return target;
1063
- }
1064
-
1065
1130
  /**
1066
1131
  * Initiate an instance and return a safe getter
1067
1132
  */
1068
1133
 
1069
1134
  const useImperativeInstance = (createFn, destroyFn) => {
1070
- const ref = React.useRef();
1071
- const refGetter = React.useMemo(() => () => {
1135
+ const ref = React$1.useRef();
1136
+ const refGetter = React$1.useMemo(() => () => {
1072
1137
  if (!ref.current) {
1073
1138
  ref.current = createFn();
1074
1139
  }
1075
1140
 
1076
1141
  return ref.current;
1077
1142
  }, []);
1078
- React.useEffect(() => {
1143
+ React$1.useEffect(() => {
1079
1144
  const instance = refGetter();
1080
1145
  return () => {
1081
1146
  destroyFn(instance);
@@ -1142,7 +1207,7 @@ const euler = ({
1142
1207
  * A collider is a shape that can be attached to a rigid body to define its physical properties.
1143
1208
  * @internal
1144
1209
  */
1145
- const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props, forwardedRef) => {
1210
+ const AnyCollider = /*#__PURE__*/React$1.memo( /*#__PURE__*/React$1.forwardRef((props, forwardedRef) => {
1146
1211
  const {
1147
1212
  children,
1148
1213
  position,
@@ -1157,7 +1222,7 @@ const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((prop
1157
1222
  colliderStates
1158
1223
  } = useRapier();
1159
1224
  const rigidBodyContext = useRigidBodyContext();
1160
- const ref = React.useRef(null);
1225
+ const ref = React$1.useRef(null);
1161
1226
  const getInstance = useImperativeInstance(() => {
1162
1227
  const worldScale = ref.current.getWorldScale(vec3());
1163
1228
  const collider = createColliderFromOptions(props, world, worldScale, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.getRigidBody);
@@ -1165,19 +1230,19 @@ const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((prop
1165
1230
  }, collider => {
1166
1231
  world.removeCollider(collider);
1167
1232
  });
1168
- React.useEffect(() => {
1233
+ React$1.useEffect(() => {
1169
1234
  const collider = getInstance();
1170
1235
  colliderStates.set(collider.handle, createColliderState(collider, ref.current, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
1171
1236
  return () => {
1172
1237
  colliderStates.delete(collider.handle);
1173
1238
  };
1174
1239
  }, []);
1175
- React.useImperativeHandle(forwardedRef, () => getInstance());
1176
- const mergedProps = React.useMemo(() => {
1177
- return _objectSpread2(_objectSpread2({}, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options), props);
1240
+ React$1.useImperativeHandle(forwardedRef, () => getInstance());
1241
+ const mergedProps = React$1.useMemo(() => {
1242
+ return _objectSpread2(_objectSpread2({}, cleanRigidBodyPropsForCollider(rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options)), props);
1178
1243
  }, [props, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options]);
1179
1244
  useUpdateColliderOptions(getInstance, mergedProps, colliderStates);
1180
- useColliderEvents(getInstance, mergedProps, colliderEvents);
1245
+ useColliderEvents(getInstance, mergedProps, colliderEvents, getActiveCollisionEventsFromProps(rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options));
1181
1246
  return /*#__PURE__*/React__default["default"].createElement("object3D", {
1182
1247
  position: position,
1183
1248
  rotation: rotation,
@@ -1410,10 +1475,10 @@ const setRigidBodyOptions = (rigidBody, options, states, updateTranslations = tr
1410
1475
  };
1411
1476
  const useUpdateRigidBodyOptions = (getRigidBody, props, states, updateTranslations = true) => {
1412
1477
  // TODO: Improve this, split each prop into its own effect
1413
- const mutablePropsAsFlatArray = React.useMemo(() => mutableRigidBodyOptionKeys.flatMap(key => {
1478
+ const mutablePropsAsFlatArray = React$1.useMemo(() => mutableRigidBodyOptionKeys.flatMap(key => {
1414
1479
  return vectorToTuple(props[key]);
1415
1480
  }), [props]);
1416
- React.useEffect(() => {
1481
+ React$1.useEffect(() => {
1417
1482
  const rigidBody = getRigidBody();
1418
1483
  setRigidBodyOptions(rigidBody, props, states, updateTranslations);
1419
1484
  }, mutablePropsAsFlatArray);
@@ -1425,7 +1490,8 @@ const useRigidBodyEvents = (getRigidBody, props, events) => {
1425
1490
  onCollisionEnter,
1426
1491
  onCollisionExit,
1427
1492
  onIntersectionEnter,
1428
- onIntersectionExit
1493
+ onIntersectionExit,
1494
+ onContactForce
1429
1495
  } = props;
1430
1496
  const eventHandlers = {
1431
1497
  onWake,
@@ -1433,26 +1499,27 @@ const useRigidBodyEvents = (getRigidBody, props, events) => {
1433
1499
  onCollisionEnter,
1434
1500
  onCollisionExit,
1435
1501
  onIntersectionEnter,
1436
- onIntersectionExit
1502
+ onIntersectionExit,
1503
+ onContactForce
1437
1504
  };
1438
- React.useEffect(() => {
1505
+ React$1.useEffect(() => {
1439
1506
  const rigidBody = getRigidBody();
1440
1507
  events.set(rigidBody.handle, eventHandlers);
1441
1508
  return () => {
1442
1509
  events.delete(rigidBody.handle);
1443
1510
  };
1444
- }, [onWake, onSleep, onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit]);
1511
+ }, [onWake, onSleep, onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit, onContactForce]);
1445
1512
  };
1446
1513
 
1447
1514
  const _excluded$1 = ["children", "type", "position", "rotation", "scale", "quaternion", "transformState"];
1448
- const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
1449
- const useRigidBodyContext = () => React.useContext(RigidBodyContext);
1515
+ const RigidBodyContext = /*#__PURE__*/React$1.createContext(undefined);
1516
+ const useRigidBodyContext = () => React$1.useContext(RigidBodyContext);
1450
1517
 
1451
1518
  /**
1452
1519
  * A rigid body is a physical object that can be simulated by the physics engine.
1453
1520
  * @category Components
1454
1521
  */
1455
- const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props, forwardedRef) => {
1522
+ const RigidBody = /*#__PURE__*/React$1.memo( /*#__PURE__*/React$1.forwardRef((props, forwardedRef) => {
1456
1523
  const {
1457
1524
  children,
1458
1525
  type,
@@ -1464,14 +1531,14 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
1464
1531
  } = props,
1465
1532
  objectProps = _objectWithoutProperties(props, _excluded$1);
1466
1533
 
1467
- const ref = React.useRef(null);
1534
+ const ref = React$1.useRef(null);
1468
1535
  const {
1469
1536
  world,
1470
1537
  rigidBodyStates,
1471
1538
  physicsOptions,
1472
1539
  rigidBodyEvents
1473
1540
  } = useRapier();
1474
- const mergedOptions = React.useMemo(() => {
1541
+ const mergedOptions = React$1.useMemo(() => {
1475
1542
  return _objectSpread2(_objectSpread2(_objectSpread2({}, physicsOptions), props), {}, {
1476
1543
  children: undefined
1477
1544
  });
@@ -1486,7 +1553,7 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
1486
1553
  world.removeRigidBody(rigidBody);
1487
1554
  }); // Only provide a object state after the ref has been set
1488
1555
 
1489
- React.useEffect(() => {
1556
+ React$1.useEffect(() => {
1490
1557
  const rigidBody = getInstance();
1491
1558
  const state = createRigidBodyState({
1492
1559
  rigidBody,
@@ -1499,8 +1566,8 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
1499
1566
  }, []);
1500
1567
  useUpdateRigidBodyOptions(getInstance, mergedOptions, rigidBodyStates);
1501
1568
  useRigidBodyEvents(getInstance, mergedOptions, rigidBodyEvents);
1502
- React.useImperativeHandle(forwardedRef, () => getInstance());
1503
- const contextValue = React.useMemo(() => {
1569
+ React$1.useImperativeHandle(forwardedRef, () => getInstance());
1570
+ const contextValue = React$1.useMemo(() => {
1504
1571
  return {
1505
1572
  ref,
1506
1573
  getRigidBody: getInstance,
@@ -1526,7 +1593,7 @@ RigidBody.displayName = "RigidBody";
1526
1593
  * A mesh collider is a collider that is automatically generated from the geometry of the children.
1527
1594
  * @category Colliders
1528
1595
  */
1529
- const MeshCollider = /*#__PURE__*/React.memo(props => {
1596
+ const MeshCollider = /*#__PURE__*/React$1.memo(props => {
1530
1597
  const {
1531
1598
  children,
1532
1599
  type
@@ -1534,11 +1601,11 @@ const MeshCollider = /*#__PURE__*/React.memo(props => {
1534
1601
  const {
1535
1602
  physicsOptions
1536
1603
  } = useRapier();
1537
- const object = React.useRef(null);
1604
+ const object = React$1.useRef(null);
1538
1605
  const {
1539
1606
  options
1540
1607
  } = useRigidBodyContext();
1541
- const mergedOptions = React.useMemo(() => {
1608
+ const mergedOptions = React$1.useMemo(() => {
1542
1609
  return _objectSpread2(_objectSpread2(_objectSpread2({}, physicsOptions), options), {}, {
1543
1610
  children: undefined,
1544
1611
  colliders: type
@@ -1578,10 +1645,10 @@ const AttractorHelper = props => {
1578
1645
  const {
1579
1646
  scene
1580
1647
  } = fiber.useThree();
1581
- const ref = React.useRef(null);
1582
- const normalsHelper = React.useRef();
1648
+ const ref = React$1.useRef(null);
1649
+ const normalsHelper = React$1.useRef();
1583
1650
  const color = props.strength > 0 ? 0x0000ff : 0xff0000;
1584
- React.useEffect(() => {
1651
+ React$1.useEffect(() => {
1585
1652
  if (ref.current) {
1586
1653
  normalsHelper.current = new threeStdlib.VertexNormalsHelper(ref.current, props.range, color);
1587
1654
  normalsHelper.current.frustumCulled = false;
@@ -1615,14 +1682,14 @@ const AttractorHelper = props => {
1615
1682
  }));
1616
1683
  };
1617
1684
 
1618
- const Debug = /*#__PURE__*/React.memo(() => {
1685
+ const Debug = /*#__PURE__*/React$1.memo(() => {
1619
1686
  const {
1620
1687
  world,
1621
1688
  attractorStates
1622
1689
  } = useRapier();
1623
- const ref = React.useRef(null);
1624
- const [attractors, setAttractors] = React.useState([]);
1625
- const currMap = React.useRef(new Map());
1690
+ const ref = React$1.useRef(null);
1691
+ const [attractors, setAttractors] = React$1.useState([]);
1692
+ const currMap = React$1.useRef(new Map());
1626
1693
  fiber.useFrame(() => {
1627
1694
  const mesh = ref.current;
1628
1695
  if (!mesh) return;
@@ -1647,9 +1714,9 @@ const Debug = /*#__PURE__*/React.memo(() => {
1647
1714
  });
1648
1715
 
1649
1716
  const _excluded = ["children", "instances", "colliderNodes", "position", "rotation", "quaternion", "scale"];
1650
- const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props, ref) => {
1651
- const object = React.useRef(null);
1652
- const instancedWrapper = React.useRef(null);
1717
+ const InstancedRigidBodies = /*#__PURE__*/React$1.memo( /*#__PURE__*/React$1.forwardRef((props, ref) => {
1718
+ const object = React$1.useRef(null);
1719
+ const instancedWrapper = React$1.useRef(null);
1653
1720
 
1654
1721
  const {
1655
1722
  // instanced props
@@ -1664,8 +1731,8 @@ const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forward
1664
1731
  } = props,
1665
1732
  rigidBodyProps = _objectWithoutProperties(props, _excluded);
1666
1733
 
1667
- const rigidBodyApis = React.useRef([]);
1668
- React.useImperativeHandle(ref, () => rigidBodyApis.current, [instances]);
1734
+ const rigidBodyApis = React$1.useRef([]);
1735
+ React$1.useImperativeHandle(ref, () => rigidBodyApis.current, [instances]);
1669
1736
  const childColliderProps = useChildColliderProps(object, _objectSpread2(_objectSpread2({}, props), {}, {
1670
1737
  children: undefined
1671
1738
  }));
@@ -1680,7 +1747,7 @@ const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forward
1680
1747
  return undefined;
1681
1748
  };
1682
1749
 
1683
- React.useEffect(() => {
1750
+ React$1.useEffect(() => {
1684
1751
  const instancedMesh = getInstancedMesh();
1685
1752
 
1686
1753
  if (instancedMesh) {
@@ -1722,7 +1789,7 @@ const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forward
1722
1789
  }, children), instances === null || instances === void 0 ? void 0 : instances.map((instance, index) => /*#__PURE__*/React__default["default"].createElement(RigidBody, _extends({}, rigidBodyProps, instance, {
1723
1790
  ref: body => rigidBodyApis.current[index] = body,
1724
1791
  transformState: state => applyInstancedState(state, index)
1725
- }), /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, colliderNodes.map((node, index) => /*#__PURE__*/React__default["default"].createElement(React.Fragment, {
1792
+ }), /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, colliderNodes.map((node, index) => /*#__PURE__*/React__default["default"].createElement(React$1.Fragment, {
1726
1793
  key: index
1727
1794
  }, node)), childColliderProps.map((colliderProps, colliderIndex) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({
1728
1795
  key: colliderIndex
@@ -1738,7 +1805,7 @@ const useImpulseJoint = (body1, body2, params) => {
1738
1805
  const {
1739
1806
  world
1740
1807
  } = useRapier();
1741
- const jointRef = React.useRef();
1808
+ const jointRef = React$1.useRef();
1742
1809
  useImperativeInstance(() => {
1743
1810
  if (body1.current && body2.current) {
1744
1811
  const newJoint = world.createImpulseJoint(params, body1.current, body2.current);