@react-three/rapier 0.13.0 → 0.13.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.
@@ -20,7 +20,9 @@ export interface RigidBodyState {
20
20
  }
21
21
  export declare type RigidBodyStateMap = Map<RigidBody["handle"], RigidBodyState>;
22
22
  export declare type WorldStepCallback = (worldApi: WorldApi) => void;
23
- export declare type WorldStepCallbackSet = Set<WorldStepCallback>;
23
+ export declare type WorldStepCallbackSet = Set<{
24
+ current: WorldStepCallback;
25
+ }>;
24
26
  export interface ColliderState {
25
27
  collider: Collider;
26
28
  object: Object3D;
@@ -477,11 +477,20 @@ const useColliderEvents = (getCollider, props, events) => {
477
477
  }, [onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit, onContactForce]);
478
478
  };
479
479
 
480
+ const useMutableCallback = fn => {
481
+ const ref = React.useRef(fn);
482
+ React.useEffect(() => {
483
+ ref.current = fn;
484
+ }, [fn]);
485
+ return ref;
486
+ }; // External hooks
487
+
480
488
  /**
481
489
  * Exposes the Rapier context, and world
482
490
  * @category Hooks
483
491
  */
484
492
 
493
+
485
494
  const useRapier = () => {
486
495
  return React.useContext(rapierContext);
487
496
  };
@@ -494,10 +503,11 @@ const useBeforePhysicsStep = callback => {
494
503
  const {
495
504
  beforeStepCallbacks
496
505
  } = useRapier();
506
+ const ref = useMutableCallback(callback);
497
507
  React.useEffect(() => {
498
- beforeStepCallbacks.add(callback);
508
+ beforeStepCallbacks.add(ref);
499
509
  return () => {
500
- beforeStepCallbacks.delete(callback);
510
+ beforeStepCallbacks.delete(ref);
501
511
  };
502
512
  }, []);
503
513
  };
@@ -510,10 +520,11 @@ const useAfterPhysicsStep = callback => {
510
520
  const {
511
521
  afterStepCallbacks
512
522
  } = useRapier();
523
+ const ref = useMutableCallback(callback);
513
524
  React.useEffect(() => {
514
- afterStepCallbacks.add(callback);
525
+ afterStepCallbacks.add(ref);
515
526
  return () => {
516
- afterStepCallbacks.delete(callback);
527
+ afterStepCallbacks.delete(ref);
517
528
  };
518
529
  }, []);
519
530
  }; // Internal hooks
@@ -759,12 +770,12 @@ const Physics = ({
759
770
  }); // Trigger beforeStep callbacks
760
771
 
761
772
  beforeStepCallbacks.forEach(callback => {
762
- callback(api);
773
+ callback.current(api);
763
774
  });
764
775
  world.step(eventQueue); // Trigger afterStep callbacks
765
776
 
766
777
  afterStepCallbacks.forEach(callback => {
767
- callback(api);
778
+ callback.current(api);
768
779
  });
769
780
  };
770
781
 
@@ -1124,12 +1135,17 @@ const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((prop
1124
1135
  const getInstance = useImperativeInstance(() => {
1125
1136
  const worldScale = ref.current.getWorldScale(vec3());
1126
1137
  const collider = createColliderFromOptions(props, world, worldScale, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.getRigidBody);
1127
- colliderStates.set(collider.handle, createColliderState(collider, ref.current, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
1128
1138
  return collider;
1129
1139
  }, collider => {
1130
- colliderStates.delete(collider.handle);
1131
1140
  world.removeCollider(collider);
1132
1141
  });
1142
+ React.useEffect(() => {
1143
+ const collider = getInstance();
1144
+ colliderStates.set(collider.handle, createColliderState(collider, ref.current, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
1145
+ return () => {
1146
+ colliderStates.delete(collider.handle);
1147
+ };
1148
+ }, []);
1133
1149
  React.useImperativeHandle(forwardedRef, () => getInstance());
1134
1150
  const mergedProps = React.useMemo(() => {
1135
1151
  return _objectSpread2(_objectSpread2({}, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options), props);
@@ -1431,21 +1447,27 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
1431
1447
  children: undefined
1432
1448
  });
1433
1449
  }, [physicsOptions, props]);
1434
- const childColliderProps = useChildColliderProps(ref, mergedOptions); // Create rigidbody
1450
+ const childColliderProps = useChildColliderProps(ref, mergedOptions); // Provide a way to eagerly create rigidbody
1435
1451
 
1436
1452
  const getInstance = useImperativeInstance(() => {
1437
1453
  const desc = rigidBodyDescFromOptions(mergedOptions);
1438
1454
  const rigidBody = world.createRigidBody(desc);
1455
+ return rigidBody;
1456
+ }, rigidBody => {
1457
+ world.removeRigidBody(rigidBody);
1458
+ }); // Only provide a object state after the ref has been set
1459
+
1460
+ React.useEffect(() => {
1461
+ const rigidBody = getInstance();
1439
1462
  const state = createRigidBodyState({
1440
1463
  rigidBody,
1441
1464
  object: ref.current
1442
1465
  });
1443
1466
  rigidBodyStates.set(rigidBody.handle, props.transformState ? props.transformState(state) : state);
1444
- return rigidBody;
1445
- }, rigidBody => {
1446
- world.removeRigidBody(rigidBody);
1447
- rigidBodyStates.delete(rigidBody.handle);
1448
- });
1467
+ return () => {
1468
+ rigidBodyStates.delete(rigidBody.handle);
1469
+ };
1470
+ }, []);
1449
1471
  useUpdateRigidBodyOptions(getInstance, mergedOptions, rigidBodyStates);
1450
1472
  useRigidBodyEvents(getInstance, mergedOptions, rigidBodyEvents);
1451
1473
  React.useImperativeHandle(forwardedRef, () => getInstance());
@@ -477,11 +477,20 @@ const useColliderEvents = (getCollider, props, events) => {
477
477
  }, [onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit, onContactForce]);
478
478
  };
479
479
 
480
+ const useMutableCallback = fn => {
481
+ const ref = React.useRef(fn);
482
+ React.useEffect(() => {
483
+ ref.current = fn;
484
+ }, [fn]);
485
+ return ref;
486
+ }; // External hooks
487
+
480
488
  /**
481
489
  * Exposes the Rapier context, and world
482
490
  * @category Hooks
483
491
  */
484
492
 
493
+
485
494
  const useRapier = () => {
486
495
  return React.useContext(rapierContext);
487
496
  };
@@ -494,10 +503,11 @@ const useBeforePhysicsStep = callback => {
494
503
  const {
495
504
  beforeStepCallbacks
496
505
  } = useRapier();
506
+ const ref = useMutableCallback(callback);
497
507
  React.useEffect(() => {
498
- beforeStepCallbacks.add(callback);
508
+ beforeStepCallbacks.add(ref);
499
509
  return () => {
500
- beforeStepCallbacks.delete(callback);
510
+ beforeStepCallbacks.delete(ref);
501
511
  };
502
512
  }, []);
503
513
  };
@@ -510,10 +520,11 @@ const useAfterPhysicsStep = callback => {
510
520
  const {
511
521
  afterStepCallbacks
512
522
  } = useRapier();
523
+ const ref = useMutableCallback(callback);
513
524
  React.useEffect(() => {
514
- afterStepCallbacks.add(callback);
525
+ afterStepCallbacks.add(ref);
515
526
  return () => {
516
- afterStepCallbacks.delete(callback);
527
+ afterStepCallbacks.delete(ref);
517
528
  };
518
529
  }, []);
519
530
  }; // Internal hooks
@@ -759,12 +770,12 @@ const Physics = ({
759
770
  }); // Trigger beforeStep callbacks
760
771
 
761
772
  beforeStepCallbacks.forEach(callback => {
762
- callback(api);
773
+ callback.current(api);
763
774
  });
764
775
  world.step(eventQueue); // Trigger afterStep callbacks
765
776
 
766
777
  afterStepCallbacks.forEach(callback => {
767
- callback(api);
778
+ callback.current(api);
768
779
  });
769
780
  };
770
781
 
@@ -1124,12 +1135,17 @@ const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((prop
1124
1135
  const getInstance = useImperativeInstance(() => {
1125
1136
  const worldScale = ref.current.getWorldScale(vec3());
1126
1137
  const collider = createColliderFromOptions(props, world, worldScale, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.getRigidBody);
1127
- colliderStates.set(collider.handle, createColliderState(collider, ref.current, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
1128
1138
  return collider;
1129
1139
  }, collider => {
1130
- colliderStates.delete(collider.handle);
1131
1140
  world.removeCollider(collider);
1132
1141
  });
1142
+ React.useEffect(() => {
1143
+ const collider = getInstance();
1144
+ colliderStates.set(collider.handle, createColliderState(collider, ref.current, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
1145
+ return () => {
1146
+ colliderStates.delete(collider.handle);
1147
+ };
1148
+ }, []);
1133
1149
  React.useImperativeHandle(forwardedRef, () => getInstance());
1134
1150
  const mergedProps = React.useMemo(() => {
1135
1151
  return _objectSpread2(_objectSpread2({}, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options), props);
@@ -1431,21 +1447,27 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
1431
1447
  children: undefined
1432
1448
  });
1433
1449
  }, [physicsOptions, props]);
1434
- const childColliderProps = useChildColliderProps(ref, mergedOptions); // Create rigidbody
1450
+ const childColliderProps = useChildColliderProps(ref, mergedOptions); // Provide a way to eagerly create rigidbody
1435
1451
 
1436
1452
  const getInstance = useImperativeInstance(() => {
1437
1453
  const desc = rigidBodyDescFromOptions(mergedOptions);
1438
1454
  const rigidBody = world.createRigidBody(desc);
1455
+ return rigidBody;
1456
+ }, rigidBody => {
1457
+ world.removeRigidBody(rigidBody);
1458
+ }); // Only provide a object state after the ref has been set
1459
+
1460
+ React.useEffect(() => {
1461
+ const rigidBody = getInstance();
1439
1462
  const state = createRigidBodyState({
1440
1463
  rigidBody,
1441
1464
  object: ref.current
1442
1465
  });
1443
1466
  rigidBodyStates.set(rigidBody.handle, props.transformState ? props.transformState(state) : state);
1444
- return rigidBody;
1445
- }, rigidBody => {
1446
- world.removeRigidBody(rigidBody);
1447
- rigidBodyStates.delete(rigidBody.handle);
1448
- });
1467
+ return () => {
1468
+ rigidBodyStates.delete(rigidBody.handle);
1469
+ };
1470
+ }, []);
1449
1471
  useUpdateRigidBodyOptions(getInstance, mergedOptions, rigidBodyStates);
1450
1472
  useRigidBodyEvents(getInstance, mergedOptions, rigidBodyEvents);
1451
1473
  React.useImperativeHandle(forwardedRef, () => getInstance());
@@ -452,11 +452,20 @@ const useColliderEvents = (getCollider, props, events) => {
452
452
  }, [onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit, onContactForce]);
453
453
  };
454
454
 
455
+ const useMutableCallback = fn => {
456
+ const ref = useRef(fn);
457
+ useEffect(() => {
458
+ ref.current = fn;
459
+ }, [fn]);
460
+ return ref;
461
+ }; // External hooks
462
+
455
463
  /**
456
464
  * Exposes the Rapier context, and world
457
465
  * @category Hooks
458
466
  */
459
467
 
468
+
460
469
  const useRapier = () => {
461
470
  return useContext(rapierContext);
462
471
  };
@@ -469,10 +478,11 @@ const useBeforePhysicsStep = callback => {
469
478
  const {
470
479
  beforeStepCallbacks
471
480
  } = useRapier();
481
+ const ref = useMutableCallback(callback);
472
482
  useEffect(() => {
473
- beforeStepCallbacks.add(callback);
483
+ beforeStepCallbacks.add(ref);
474
484
  return () => {
475
- beforeStepCallbacks.delete(callback);
485
+ beforeStepCallbacks.delete(ref);
476
486
  };
477
487
  }, []);
478
488
  };
@@ -485,10 +495,11 @@ const useAfterPhysicsStep = callback => {
485
495
  const {
486
496
  afterStepCallbacks
487
497
  } = useRapier();
498
+ const ref = useMutableCallback(callback);
488
499
  useEffect(() => {
489
- afterStepCallbacks.add(callback);
500
+ afterStepCallbacks.add(ref);
490
501
  return () => {
491
- afterStepCallbacks.delete(callback);
502
+ afterStepCallbacks.delete(ref);
492
503
  };
493
504
  }, []);
494
505
  }; // Internal hooks
@@ -734,12 +745,12 @@ const Physics = ({
734
745
  }); // Trigger beforeStep callbacks
735
746
 
736
747
  beforeStepCallbacks.forEach(callback => {
737
- callback(api);
748
+ callback.current(api);
738
749
  });
739
750
  world.step(eventQueue); // Trigger afterStep callbacks
740
751
 
741
752
  afterStepCallbacks.forEach(callback => {
742
- callback(api);
753
+ callback.current(api);
743
754
  });
744
755
  };
745
756
 
@@ -1099,12 +1110,17 @@ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwarded
1099
1110
  const getInstance = useImperativeInstance(() => {
1100
1111
  const worldScale = ref.current.getWorldScale(vec3());
1101
1112
  const collider = createColliderFromOptions(props, world, worldScale, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.getRigidBody);
1102
- colliderStates.set(collider.handle, createColliderState(collider, ref.current, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
1103
1113
  return collider;
1104
1114
  }, collider => {
1105
- colliderStates.delete(collider.handle);
1106
1115
  world.removeCollider(collider);
1107
1116
  });
1117
+ useEffect(() => {
1118
+ const collider = getInstance();
1119
+ colliderStates.set(collider.handle, createColliderState(collider, ref.current, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
1120
+ return () => {
1121
+ colliderStates.delete(collider.handle);
1122
+ };
1123
+ }, []);
1108
1124
  useImperativeHandle(forwardedRef, () => getInstance());
1109
1125
  const mergedProps = useMemo(() => {
1110
1126
  return _objectSpread2(_objectSpread2({}, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options), props);
@@ -1406,21 +1422,27 @@ const RigidBody = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwardedRe
1406
1422
  children: undefined
1407
1423
  });
1408
1424
  }, [physicsOptions, props]);
1409
- const childColliderProps = useChildColliderProps(ref, mergedOptions); // Create rigidbody
1425
+ const childColliderProps = useChildColliderProps(ref, mergedOptions); // Provide a way to eagerly create rigidbody
1410
1426
 
1411
1427
  const getInstance = useImperativeInstance(() => {
1412
1428
  const desc = rigidBodyDescFromOptions(mergedOptions);
1413
1429
  const rigidBody = world.createRigidBody(desc);
1430
+ return rigidBody;
1431
+ }, rigidBody => {
1432
+ world.removeRigidBody(rigidBody);
1433
+ }); // Only provide a object state after the ref has been set
1434
+
1435
+ useEffect(() => {
1436
+ const rigidBody = getInstance();
1414
1437
  const state = createRigidBodyState({
1415
1438
  rigidBody,
1416
1439
  object: ref.current
1417
1440
  });
1418
1441
  rigidBodyStates.set(rigidBody.handle, props.transformState ? props.transformState(state) : state);
1419
- return rigidBody;
1420
- }, rigidBody => {
1421
- world.removeRigidBody(rigidBody);
1422
- rigidBodyStates.delete(rigidBody.handle);
1423
- });
1442
+ return () => {
1443
+ rigidBodyStates.delete(rigidBody.handle);
1444
+ };
1445
+ }, []);
1424
1446
  useUpdateRigidBodyOptions(getInstance, mergedOptions, rigidBodyStates);
1425
1447
  useRigidBodyEvents(getInstance, mergedOptions, rigidBodyEvents);
1426
1448
  useImperativeHandle(forwardedRef, () => getInstance());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-three/rapier",
3
- "version": "0.13.0",
3
+ "version": "0.13.2",
4
4
  "source": "src/index.ts",
5
5
  "main": "dist/react-three-rapier.cjs.js",
6
6
  "module": "dist/react-three-rapier.esm.js",
package/readme.md CHANGED
@@ -12,7 +12,7 @@
12
12
  <br />
13
13
  For contributions, please read the <a href="https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/CONTRIBUTING.md">🪧 Contribution Guide</a>.
14
14
  <br/>
15
- For available APIs, see <a href="https://pmndrs.github.io/react-three-rapier/>">🧩 API Docs</a>
15
+ For available APIs, see <a href="https://pmndrs.github.io/react-three-rapier/">🧩 API Docs</a>
16
16
  </p>
17
17
 
18
18
  ---
@@ -66,6 +66,7 @@ For full API outline and documentation, see 🧩 [API Docs](https://pmndrs.githu
66
66
  - [Collider Components](#collider-components)
67
67
  - [🖼 Collider Examples](#-collider-examples)
68
68
  - [Instanced Meshes](#instanced-meshes)
69
+ - [Debug](#debug)
69
70
  - [Moving things around, and applying forces](#moving-things-around-and-applying-forces)
70
71
  - [Collision Events](#collision-events)
71
72
  - [Configuring collision and solver groups](#configuring-collision-and-solver-groups)
@@ -80,7 +81,6 @@ For full API outline and documentation, see 🧩 [API Docs](https://pmndrs.githu
80
81
  - [Spherical Joint](#spherical-joint)
81
82
  - [Revolute Joint](#revolute-joint)
82
83
  - [Prismatic Joint](#prismatic-joint)
83
- - [Joint APIs](#joint-apis)
84
84
  - [🖼 Joints Example](#-joints-example)
85
85
  - [Advanced hooks usage](#advanced-hooks-usage)
86
86
  - [Manual stepping](#manual-stepping)
@@ -256,11 +256,12 @@ const Scene = () => {
256
256
  }
257
257
 
258
258
  // You can access individual instanced by their index
259
- rigidBodies.current.at(40).applyImpulse({ x: 0, y: 10, z: 0 });
259
+ rigidBodies.current[40].applyImpulse({ x: 0, y: 10, z: 0 }, true);
260
+ rigidBodies.at(100).applyImpulse({ x: 0, y: 10, z: 0 }, true);
260
261
 
261
262
  // Or update all instances
262
263
  rigidBodies.current.forEach((api) => {
263
- api.applyImpulse({ x: 0, y: 10, z: 0 });
264
+ api.applyImpulse({ x: 0, y: 10, z: 0 }, true);
264
265
  });
265
266
  }, []);
266
267
 
@@ -329,8 +330,6 @@ const Scene = () => {
329
330
  );
330
331
  };
331
332
  ```
332
- }
333
- ```
334
333
 
335
334
  ## Debug
336
335
 
@@ -590,8 +589,6 @@ To detect when a collider enters or leaves another collider, you can use the `on
590
589
 
591
590
  🧩 See [onIntersectionEnter / onIntersectionExit docs](https://pmndrs.github.io/react-three-rapier/interfaces/RigidBodyProps.html#onIntersectionEnter) for more information.
592
591
 
593
- ```tsx
594
-
595
592
  ```tsx
596
593
  <RigidBody>
597
594
  <GoalPosts />
@@ -674,7 +671,8 @@ There are 4 different joint types available:
674
671
  - Revolute (two bodies are connected by a hinge, for things like doors or wheels)
675
672
  - Prismatic (two bodies are connected by a sliding joint, for things like pistons or sliders)
676
673
 
677
- Each joint hook returns a RefObject containing the raw reference to the hook instance.
674
+ Each joint hook returns a RefObject containing the raw reference to the joint instance.
675
+
678
676
  ```tsx
679
677
  const WheelJoint = ({bodyA, bodyB}) => {
680
678
  const joint = useRevoluteJoint(bodyA, bodyB, [[0,0,0],[0,0,0],[0,0,0]])
@@ -724,8 +722,6 @@ The spherical joint ensures that two points on the local-spaces of two rigid-bod
724
722
 
725
723
  🧩 See [SphericalJoint docs](https://pmndrs.github.io/react-three-rapier/functions/useSphericalJoint.html) for available options.
726
724
 
727
- ```tsx
728
-
729
725
  ```tsx
730
726
  const JointedThing = () => {
731
727
  const joint = useSphericalJoint(
@@ -789,8 +785,6 @@ The prismatic joint prevents any relative movement between two rigid-bodies, exc
789
785
 
790
786
  🧩 See [PrismaticJoint docs](https://pmndrs.github.io/react-three-rapier/functions/usePrismaticJoint.html) for available options.
791
787
 
792
- ```tsx
793
-
794
788
  ```tsx
795
789
  const JointedThing = () => {
796
790
  const joint = usePrismaticJoint(
@@ -815,27 +809,6 @@ const JointedThing = () => {
815
809
  }
816
810
  ```
817
811
 
818
- ### Joint APIs
819
- Joints can be controlled imperatively similarily to how `RigidBody` components can be controlled.
820
-
821
- 🧩 See [Joint API docs](https://pmndrs.github.io/react-three-rapier/interfaces/JointApi.html) for more information.
822
-
823
- ```tsx
824
- const JointedThing = () => {
825
- const joint = useSphericalJoint(...)
826
-
827
- useEffect(() => {
828
- joint.configureMotorVelocity(1, 0)
829
-
830
- // Disable contacts between the two joint bodies
831
- joint.setContactsEnabled(false)
832
- }, [])
833
-
834
- return ...
835
- }
836
- ```
837
-
838
-
839
812
  ### 🖼 Joints Example
840
813
  <a href="https://codesandbox.io/s/react-three-rapier-joints-mhhbd4"><img src="https://raw.githubusercontent.com/pmndrs/react-three-rapier/HEAD/packages/react-three-rapier/misc/example-joints.jpg" width="240" /></a>
841
814