@react-three/rapier 1.1.1 → 1.2.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.
@@ -77,6 +77,10 @@ export interface RapierContext {
77
77
  * The Rapier physics world
78
78
  */
79
79
  world: World;
80
+ /**
81
+ * overwriting the Rapier physics world with a restored snapshot
82
+ */
83
+ setWorld: (world: World) => void;
80
84
  /**
81
85
  * If the physics simulation is paused
82
86
  */
@@ -7,4 +7,5 @@
7
7
  export declare const createSingletonProxy: <SingletonClass extends object, CreationFn extends () => SingletonClass = () => SingletonClass>(createInstance: CreationFn) => {
8
8
  proxy: SingletonClass;
9
9
  reset: () => void;
10
+ set: (newInstance: SingletonClass) => void;
10
11
  };
@@ -571,7 +571,9 @@ const useMutableCallback = fn => {
571
571
 
572
572
 
573
573
  const useRapier = () => {
574
- return React.useContext(rapierContext);
574
+ const rapier = React.useContext(rapierContext);
575
+ if (!rapier) throw new Error("react-three-rapier: useRapier must be used within <Physics />!");
576
+ return rapier;
575
577
  };
576
578
  /**
577
579
  * Registers a callback to be called before the physics step
@@ -680,6 +682,10 @@ const createSingletonProxy = createInstance => {
680
682
  const reset = () => {
681
683
  instance = undefined;
682
684
  };
685
+
686
+ const set = newInstance => {
687
+ instance = newInstance;
688
+ };
683
689
  /**
684
690
  * Return the proxy and a reset function
685
691
  */
@@ -687,7 +693,8 @@ const createSingletonProxy = createInstance => {
687
693
 
688
694
  return {
689
695
  proxy,
690
- reset
696
+ reset,
697
+ set
691
698
  };
692
699
  };
693
700
 
@@ -762,7 +769,8 @@ const Physics = props => {
762
769
 
763
770
  const {
764
771
  proxy: worldProxy,
765
- reset: resetWorldProxy
772
+ reset: resetWorldProxy,
773
+ set: setWorldProxy
766
774
  } = useConst(() => createSingletonProxy(() => new rapier.World(vectorArrayToVector3(gravity))));
767
775
  React.useEffect(() => {
768
776
  return () => {
@@ -1018,6 +1026,9 @@ const Physics = props => {
1018
1026
  const context = React.useMemo(() => ({
1019
1027
  rapier,
1020
1028
  world: worldProxy,
1029
+ setWorld: world => {
1030
+ setWorldProxy(world);
1031
+ },
1021
1032
  physicsOptions: {
1022
1033
  colliders,
1023
1034
  gravity
@@ -571,7 +571,9 @@ const useMutableCallback = fn => {
571
571
 
572
572
 
573
573
  const useRapier = () => {
574
- return React.useContext(rapierContext);
574
+ const rapier = React.useContext(rapierContext);
575
+ if (!rapier) throw new Error("react-three-rapier: useRapier must be used within <Physics />!");
576
+ return rapier;
575
577
  };
576
578
  /**
577
579
  * Registers a callback to be called before the physics step
@@ -680,6 +682,10 @@ const createSingletonProxy = createInstance => {
680
682
  const reset = () => {
681
683
  instance = undefined;
682
684
  };
685
+
686
+ const set = newInstance => {
687
+ instance = newInstance;
688
+ };
683
689
  /**
684
690
  * Return the proxy and a reset function
685
691
  */
@@ -687,7 +693,8 @@ const createSingletonProxy = createInstance => {
687
693
 
688
694
  return {
689
695
  proxy,
690
- reset
696
+ reset,
697
+ set
691
698
  };
692
699
  };
693
700
 
@@ -762,7 +769,8 @@ const Physics = props => {
762
769
 
763
770
  const {
764
771
  proxy: worldProxy,
765
- reset: resetWorldProxy
772
+ reset: resetWorldProxy,
773
+ set: setWorldProxy
766
774
  } = useConst(() => createSingletonProxy(() => new rapier.World(vectorArrayToVector3(gravity))));
767
775
  React.useEffect(() => {
768
776
  return () => {
@@ -1018,6 +1026,9 @@ const Physics = props => {
1018
1026
  const context = React.useMemo(() => ({
1019
1027
  rapier,
1020
1028
  world: worldProxy,
1029
+ setWorld: world => {
1030
+ setWorldProxy(world);
1031
+ },
1021
1032
  physicsOptions: {
1022
1033
  colliders,
1023
1034
  gravity
@@ -546,7 +546,9 @@ const useMutableCallback = fn => {
546
546
 
547
547
 
548
548
  const useRapier = () => {
549
- return useContext(rapierContext);
549
+ const rapier = useContext(rapierContext);
550
+ if (!rapier) throw new Error("react-three-rapier: useRapier must be used within <Physics />!");
551
+ return rapier;
550
552
  };
551
553
  /**
552
554
  * Registers a callback to be called before the physics step
@@ -655,6 +657,10 @@ const createSingletonProxy = createInstance => {
655
657
  const reset = () => {
656
658
  instance = undefined;
657
659
  };
660
+
661
+ const set = newInstance => {
662
+ instance = newInstance;
663
+ };
658
664
  /**
659
665
  * Return the proxy and a reset function
660
666
  */
@@ -662,7 +668,8 @@ const createSingletonProxy = createInstance => {
662
668
 
663
669
  return {
664
670
  proxy,
665
- reset
671
+ reset,
672
+ set
666
673
  };
667
674
  };
668
675
 
@@ -737,7 +744,8 @@ const Physics = props => {
737
744
 
738
745
  const {
739
746
  proxy: worldProxy,
740
- reset: resetWorldProxy
747
+ reset: resetWorldProxy,
748
+ set: setWorldProxy
741
749
  } = useConst(() => createSingletonProxy(() => new rapier.World(vectorArrayToVector3(gravity))));
742
750
  useEffect(() => {
743
751
  return () => {
@@ -993,6 +1001,9 @@ const Physics = props => {
993
1001
  const context = useMemo(() => ({
994
1002
  rapier,
995
1003
  world: worldProxy,
1004
+ setWorld: world => {
1005
+ setWorldProxy(world);
1006
+ },
996
1007
  physicsOptions: {
997
1008
  colliders,
998
1009
  gravity
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-three/rapier",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "source": "src/index.ts",
5
5
  "main": "dist/react-three-rapier.cjs.js",
6
6
  "module": "dist/react-three-rapier.esm.js",
@@ -12,10 +12,10 @@
12
12
  "devDependencies": {
13
13
  "@react-three/drei": "9.74.14",
14
14
  "@react-three/fiber": "8.9.1",
15
- "@react-three/test-renderer": "8.0.17",
15
+ "@react-three/test-renderer": "8.1.5",
16
16
  "@types/react-dom": "18.0.2",
17
17
  "@types/three": "^0.152.1",
18
- "@vitejs/plugin-react": "^2.1.0",
18
+ "@vitejs/plugin-react": "^4.0.3",
19
19
  "@vitest/ui": "0.32.0",
20
20
  "happy-dom": "9.19.2",
21
21
  "react": "18.2.0",
package/readme.md CHANGED
@@ -413,7 +413,7 @@ const Scene = () => {
413
413
  // While Rapier's return types need conversion, setting values can be done directly with Three.js types
414
414
  rigidBody.current.setTranslation(position, true);
415
415
  rigidBody.current.setRotation(quaternion, true);
416
- rigidBody.current.setAngVel({ x: 0, y: 2, z: 0 }, true);
416
+ rigidBody.current.setAngvel({ x: 0, y: 2, z: 0 }, true);
417
417
  }
418
418
  }, []);
419
419
 
@@ -812,3 +812,39 @@ Setting `<Physics updateLoop="independent" />` will make the physics simulation
812
812
  <Physics updateLoop="independent">...</Physics>
813
813
  </Canvas>
814
814
  ```
815
+
816
+ ### Snapshots
817
+ The `world` can be serialized as a `Uint8Array` using `world.takeSnapshot()`, see Rapier's docs on [Serialization](https://rapier.rs/docs/user_guides/javascript/serialization/) for more info.
818
+
819
+ The snapshot can be used to construct a new world. In `r3/rapier`, you need to replace the world with this snapshot.
820
+
821
+ > [!NOTE]
822
+ > This only works if the snapshotted world is identical to the restored one. If objects, or the order of creation of objects vary, expect RigidBodies to scramble.
823
+
824
+ ```tsx
825
+ import { useRapier } from '@react-three/rapier';
826
+
827
+ const SnapshottingComponent = () => {
828
+ const { world, setWorld, rapier } = useRapier();
829
+ const worldSnapshot = useRef<Uint8Array>();
830
+
831
+ // Store the snapshot
832
+ const takeSnapshot = () => {
833
+ const snapshot = world.takeSnapshot()
834
+ worldSnapshot.current = snapshot
835
+ }
836
+
837
+ // Create a new World from the snapshot, and replace the current one
838
+ const restoreSnapshot = () => {
839
+ setWorld(rapier.World.restoreSnapshot(worldSnapshot.current))
840
+ }
841
+
842
+ return <>
843
+ <Rigidbody>...</RigidBody>
844
+ <Rigidbody>...</RigidBody>
845
+ <Rigidbody>...</RigidBody>
846
+ <Rigidbody>...</RigidBody>
847
+ <Rigidbody>...</RigidBody>
848
+ </>
849
+ }
850
+ ```