@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.
- package/dist/declarations/src/components/Physics.d.ts +4 -0
- package/dist/declarations/src/utils/singleton-proxy.d.ts +1 -0
- package/dist/react-three-rapier.cjs.dev.js +14 -3
- package/dist/react-three-rapier.cjs.prod.js +14 -3
- package/dist/react-three-rapier.esm.js +14 -3
- package/package.json +3 -3
- package/readme.md +37 -1
@@ -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
|
*/
|
@@ -571,7 +571,9 @@ const useMutableCallback = fn => {
|
|
571
571
|
|
572
572
|
|
573
573
|
const useRapier = () => {
|
574
|
-
|
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
|
-
|
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
|
-
|
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.
|
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.
|
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": "^
|
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.
|
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
|
+
```
|