@react-three/rapier 0.10.0 → 0.11.1
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.
@@ -109,6 +109,7 @@ interface RapierWorldProps {
|
|
109
109
|
/**
|
110
110
|
* The update priority at which the physics simulation should run.
|
111
111
|
*
|
112
|
+
* @see https://docs.pmnd.rs/react-three-fiber/api/hooks#taking-over-the-render-loop
|
112
113
|
* @defaultValue undefined
|
113
114
|
*/
|
114
115
|
updatePriority?: number;
|
@@ -8,3 +8,4 @@ export declare const rapierQuaternionToQuaternion: ({ x, y, z, w }: RapierQuater
|
|
8
8
|
export declare const rigidBodyTypeFromString: (type: RigidBodyTypeString) => number;
|
9
9
|
export declare const scaleVertices: (vertices: ArrayLike<number>, scale: Vector3) => number[];
|
10
10
|
export declare const vectorToTuple: (v: Vector3 | Quaternion | any[] | undefined | number | Euler) => any[];
|
11
|
+
export declare function useConst<T>(initialValue: T | (() => T)): T;
|
@@ -131,6 +131,17 @@ const vectorToTuple = v => {
|
|
131
131
|
|
132
132
|
return [v];
|
133
133
|
};
|
134
|
+
function useConst(initialValue) {
|
135
|
+
const ref = React.useRef();
|
136
|
+
|
137
|
+
if (ref.current === undefined) {
|
138
|
+
ref.current = {
|
139
|
+
value: typeof initialValue === "function" ? initialValue() : initialValue
|
140
|
+
};
|
141
|
+
}
|
142
|
+
|
143
|
+
return ref.current.value;
|
144
|
+
}
|
134
145
|
|
135
146
|
const createRigidBodyApi = ref => {
|
136
147
|
return {
|
@@ -580,7 +591,9 @@ const useColliderEvents = (collidersRef, props, events) => {
|
|
580
591
|
|
581
592
|
const rigidBodyDescFromOptions = options => {
|
582
593
|
const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
|
583
|
-
const desc = new rapier3dCompat.RigidBodyDesc(type);
|
594
|
+
const desc = new rapier3dCompat.RigidBodyDesc(type); // Apply immutable options
|
595
|
+
|
596
|
+
desc.canSleep = (options === null || options === void 0 ? void 0 : options.canSleep) || true;
|
584
597
|
return desc;
|
585
598
|
};
|
586
599
|
const createRigidBodyState = ({
|
@@ -620,6 +633,12 @@ const mutableRigidBodyOptions = {
|
|
620
633
|
enabledTranslations: (rb, [x, y, z]) => {
|
621
634
|
rb.setEnabledTranslations(x, y, z, true);
|
622
635
|
},
|
636
|
+
lockRotations: (rb, value) => {
|
637
|
+
rb.lockRotations(value, true);
|
638
|
+
},
|
639
|
+
lockTranslations: (rb, value) => {
|
640
|
+
rb.lockTranslations(value, true);
|
641
|
+
},
|
623
642
|
angularVelocity: (rb, [x, y, z]) => {
|
624
643
|
rb.setAngvel({
|
625
644
|
x,
|
@@ -640,6 +659,11 @@ const mutableRigidBodyOptions = {
|
|
640
659
|
userData: (rb, value) => {
|
641
660
|
rb.userData = value;
|
642
661
|
},
|
662
|
+
|
663
|
+
type(rb, value) {
|
664
|
+
rb.setBodyType(rigidBodyTypeFromString(value));
|
665
|
+
},
|
666
|
+
|
643
667
|
position: () => {},
|
644
668
|
rotation: () => {},
|
645
669
|
quaternion: () => {},
|
@@ -1013,12 +1037,12 @@ const Physics = ({
|
|
1013
1037
|
|
1014
1038
|
return worldRef.current;
|
1015
1039
|
});
|
1016
|
-
const
|
1017
|
-
const
|
1018
|
-
const
|
1019
|
-
const
|
1020
|
-
const
|
1021
|
-
const
|
1040
|
+
const rigidBodyStates = useConst(() => new Map());
|
1041
|
+
const colliderStates = useConst(() => new Map());
|
1042
|
+
const rigidBodyEvents = useConst(() => new Map());
|
1043
|
+
const colliderEvents = useConst(() => new Map());
|
1044
|
+
const eventQueue = useConst(() => new rapier3dCompat.EventQueue(false));
|
1045
|
+
const attractorStates = useConst(() => new Map()); // Init world
|
1022
1046
|
|
1023
1047
|
React.useEffect(() => {
|
1024
1048
|
const world = getWorldRef.current();
|
@@ -131,6 +131,17 @@ const vectorToTuple = v => {
|
|
131
131
|
|
132
132
|
return [v];
|
133
133
|
};
|
134
|
+
function useConst(initialValue) {
|
135
|
+
const ref = React.useRef();
|
136
|
+
|
137
|
+
if (ref.current === undefined) {
|
138
|
+
ref.current = {
|
139
|
+
value: typeof initialValue === "function" ? initialValue() : initialValue
|
140
|
+
};
|
141
|
+
}
|
142
|
+
|
143
|
+
return ref.current.value;
|
144
|
+
}
|
134
145
|
|
135
146
|
const createRigidBodyApi = ref => {
|
136
147
|
return {
|
@@ -580,7 +591,9 @@ const useColliderEvents = (collidersRef, props, events) => {
|
|
580
591
|
|
581
592
|
const rigidBodyDescFromOptions = options => {
|
582
593
|
const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
|
583
|
-
const desc = new rapier3dCompat.RigidBodyDesc(type);
|
594
|
+
const desc = new rapier3dCompat.RigidBodyDesc(type); // Apply immutable options
|
595
|
+
|
596
|
+
desc.canSleep = (options === null || options === void 0 ? void 0 : options.canSleep) || true;
|
584
597
|
return desc;
|
585
598
|
};
|
586
599
|
const createRigidBodyState = ({
|
@@ -620,6 +633,12 @@ const mutableRigidBodyOptions = {
|
|
620
633
|
enabledTranslations: (rb, [x, y, z]) => {
|
621
634
|
rb.setEnabledTranslations(x, y, z, true);
|
622
635
|
},
|
636
|
+
lockRotations: (rb, value) => {
|
637
|
+
rb.lockRotations(value, true);
|
638
|
+
},
|
639
|
+
lockTranslations: (rb, value) => {
|
640
|
+
rb.lockTranslations(value, true);
|
641
|
+
},
|
623
642
|
angularVelocity: (rb, [x, y, z]) => {
|
624
643
|
rb.setAngvel({
|
625
644
|
x,
|
@@ -640,6 +659,11 @@ const mutableRigidBodyOptions = {
|
|
640
659
|
userData: (rb, value) => {
|
641
660
|
rb.userData = value;
|
642
661
|
},
|
662
|
+
|
663
|
+
type(rb, value) {
|
664
|
+
rb.setBodyType(rigidBodyTypeFromString(value));
|
665
|
+
},
|
666
|
+
|
643
667
|
position: () => {},
|
644
668
|
rotation: () => {},
|
645
669
|
quaternion: () => {},
|
@@ -1013,12 +1037,12 @@ const Physics = ({
|
|
1013
1037
|
|
1014
1038
|
return worldRef.current;
|
1015
1039
|
});
|
1016
|
-
const
|
1017
|
-
const
|
1018
|
-
const
|
1019
|
-
const
|
1020
|
-
const
|
1021
|
-
const
|
1040
|
+
const rigidBodyStates = useConst(() => new Map());
|
1041
|
+
const colliderStates = useConst(() => new Map());
|
1042
|
+
const rigidBodyEvents = useConst(() => new Map());
|
1043
|
+
const colliderEvents = useConst(() => new Map());
|
1044
|
+
const eventQueue = useConst(() => new rapier3dCompat.EventQueue(false));
|
1045
|
+
const attractorStates = useConst(() => new Map()); // Init world
|
1022
1046
|
|
1023
1047
|
React.useEffect(() => {
|
1024
1048
|
const world = getWorldRef.current();
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { ColliderDesc, ActiveEvents, RigidBodyDesc, EventQueue } 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, { useMemo, useEffect, useContext, useState,
|
4
|
+
import React, { useRef, useMemo, useEffect, useContext, useState, memo, createContext, useCallback, forwardRef, useImperativeHandle, useLayoutEffect } from 'react';
|
5
5
|
import { Quaternion, Euler, Vector3, Object3D, Matrix4, MathUtils, InstancedMesh, BufferAttribute, DynamicDrawUsage } from 'three';
|
6
6
|
import { useAsset } from 'use-asset';
|
7
7
|
import { mergeVertices, VertexNormalsHelper } from 'three-stdlib';
|
@@ -106,6 +106,17 @@ const vectorToTuple = v => {
|
|
106
106
|
|
107
107
|
return [v];
|
108
108
|
};
|
109
|
+
function useConst(initialValue) {
|
110
|
+
const ref = useRef();
|
111
|
+
|
112
|
+
if (ref.current === undefined) {
|
113
|
+
ref.current = {
|
114
|
+
value: typeof initialValue === "function" ? initialValue() : initialValue
|
115
|
+
};
|
116
|
+
}
|
117
|
+
|
118
|
+
return ref.current.value;
|
119
|
+
}
|
109
120
|
|
110
121
|
const createRigidBodyApi = ref => {
|
111
122
|
return {
|
@@ -555,7 +566,9 @@ const useColliderEvents = (collidersRef, props, events) => {
|
|
555
566
|
|
556
567
|
const rigidBodyDescFromOptions = options => {
|
557
568
|
const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
|
558
|
-
const desc = new RigidBodyDesc(type);
|
569
|
+
const desc = new RigidBodyDesc(type); // Apply immutable options
|
570
|
+
|
571
|
+
desc.canSleep = (options === null || options === void 0 ? void 0 : options.canSleep) || true;
|
559
572
|
return desc;
|
560
573
|
};
|
561
574
|
const createRigidBodyState = ({
|
@@ -595,6 +608,12 @@ const mutableRigidBodyOptions = {
|
|
595
608
|
enabledTranslations: (rb, [x, y, z]) => {
|
596
609
|
rb.setEnabledTranslations(x, y, z, true);
|
597
610
|
},
|
611
|
+
lockRotations: (rb, value) => {
|
612
|
+
rb.lockRotations(value, true);
|
613
|
+
},
|
614
|
+
lockTranslations: (rb, value) => {
|
615
|
+
rb.lockTranslations(value, true);
|
616
|
+
},
|
598
617
|
angularVelocity: (rb, [x, y, z]) => {
|
599
618
|
rb.setAngvel({
|
600
619
|
x,
|
@@ -615,6 +634,11 @@ const mutableRigidBodyOptions = {
|
|
615
634
|
userData: (rb, value) => {
|
616
635
|
rb.userData = value;
|
617
636
|
},
|
637
|
+
|
638
|
+
type(rb, value) {
|
639
|
+
rb.setBodyType(rigidBodyTypeFromString(value));
|
640
|
+
},
|
641
|
+
|
618
642
|
position: () => {},
|
619
643
|
rotation: () => {},
|
620
644
|
quaternion: () => {},
|
@@ -988,12 +1012,12 @@ const Physics = ({
|
|
988
1012
|
|
989
1013
|
return worldRef.current;
|
990
1014
|
});
|
991
|
-
const
|
992
|
-
const
|
993
|
-
const
|
994
|
-
const
|
995
|
-
const
|
996
|
-
const
|
1015
|
+
const rigidBodyStates = useConst(() => new Map());
|
1016
|
+
const colliderStates = useConst(() => new Map());
|
1017
|
+
const rigidBodyEvents = useConst(() => new Map());
|
1018
|
+
const colliderEvents = useConst(() => new Map());
|
1019
|
+
const eventQueue = useConst(() => new EventQueue(false));
|
1020
|
+
const attractorStates = useConst(() => new Map()); // Init world
|
997
1021
|
|
998
1022
|
useEffect(() => {
|
999
1023
|
const world = getWorldRef.current();
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@react-three/rapier",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.11.1",
|
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,18 +12,18 @@
|
|
12
12
|
"ts": "tsc -w"
|
13
13
|
},
|
14
14
|
"devDependencies": {
|
15
|
-
"@react-three/drei": "
|
16
|
-
"@react-three/fiber": "
|
15
|
+
"@react-three/drei": "9.45.0",
|
16
|
+
"@react-three/fiber": "8.9.1",
|
17
17
|
"@react-three/test-renderer": "^8.0.17",
|
18
18
|
"@types/react-dom": "^18.0.2",
|
19
19
|
"@types/three": "^0.139.0",
|
20
20
|
"@vitejs/plugin-react": "^2.1.0",
|
21
|
-
"@vitest/ui": "^0.
|
21
|
+
"@vitest/ui": "^0.25.2",
|
22
22
|
"happy-dom": "^7.5.5",
|
23
|
-
"react": "
|
24
|
-
"react-dom": "
|
25
|
-
"three": "
|
26
|
-
"vitest": "^0.
|
23
|
+
"react": "18.2.0",
|
24
|
+
"react-dom": "18.2.0",
|
25
|
+
"three": "0.146.0",
|
26
|
+
"vitest": "^0.25.2"
|
27
27
|
},
|
28
28
|
"peerDependencies": {
|
29
29
|
"@react-three/fiber": "^8.0.12",
|
@@ -31,7 +31,7 @@
|
|
31
31
|
"three": ">=0.139.2"
|
32
32
|
},
|
33
33
|
"dependencies": {
|
34
|
-
"@dimforge/rapier3d-compat": "0.
|
34
|
+
"@dimforge/rapier3d-compat": "0.10.0",
|
35
35
|
"three-stdlib": "^2.15.0",
|
36
36
|
"use-asset": "^1.0.4"
|
37
37
|
},
|
package/readme.md
CHANGED
@@ -41,19 +41,51 @@ const App = () => {
|
|
41
41
|
|
42
42
|
## Readme Topics
|
43
43
|
|
44
|
-
- [
|
44
|
+
- [Basic Usage](#basic-usage)
|
45
|
+
- [Readme Topics](#readme-topics)
|
46
|
+
- [The Physics Component](#the-physics-component)
|
47
|
+
- [Automatic colliders](#automatic-colliders)
|
48
|
+
- [Collider Examples](#collider-examples)
|
45
49
|
- [Instanced Meshes](#instanced-meshes)
|
46
50
|
- [Debug](#debug)
|
47
51
|
- [Collision Events](#collision-events)
|
48
|
-
- [
|
49
|
-
- [Contact
|
52
|
+
- [Configuring collision and solver groups](#configuring-collision-and-solver-groups)
|
53
|
+
- [Contact force events](#contact-force-events)
|
50
54
|
- [Sensors](#sensors)
|
55
|
+
- [Sensors Example](#sensors-example)
|
51
56
|
- [Attractors](#attractors)
|
52
|
-
- [
|
57
|
+
- [Attractors Example](#attractors-example)
|
58
|
+
- [Configuring Time Step Size](#configuring-time-step-size)
|
53
59
|
- [Manual stepping](#manual-stepping)
|
60
|
+
- [Joints](#joints)
|
61
|
+
- [Joints Example](#joints-example)
|
54
62
|
|
55
63
|
---
|
56
64
|
|
65
|
+
## The Physics Component
|
66
|
+
The `<Physics />` component is the root component of your physics world. It is responsible for creating the physics world and managing the simulation. It relies on lazily initiating `Rapier` and needs to be wrapped in `<Suspense />`.
|
67
|
+
|
68
|
+
```tsx
|
69
|
+
// The gravity of the physics workd
|
70
|
+
gravity?: Vector3Array; // default [0, -9.81, 0]
|
71
|
+
|
72
|
+
// Which collider shape to generate for meshes by default
|
73
|
+
colliders?: RigidBodyAutoCollider; // default "cuboid"
|
74
|
+
|
75
|
+
// The number of physics steps per second
|
76
|
+
timeStep?: number | "vary"; // default 1/60
|
77
|
+
|
78
|
+
// Pause the physic simulation
|
79
|
+
paused?: boolean; // default false
|
80
|
+
|
81
|
+
// Which order to run the physics simulation
|
82
|
+
updatePriority?: number;
|
83
|
+
|
84
|
+
// If the physics updates slower than the monitor refreshes,
|
85
|
+
// interpolation will smooth out the steps between frames
|
86
|
+
interpolate?: boolean; // default true
|
87
|
+
```
|
88
|
+
|
57
89
|
## Automatic colliders
|
58
90
|
|
59
91
|
RigidBodies generate automatic colliders by default for all meshes that it contains. You can control the default collider by setting the `colliders` prop on a `<RigidBody />`, or change it globally by setting `colliders` on `<Physics />`. Setting `colliders={false}` disables auto-generation.
|
@@ -149,6 +181,10 @@ If part of our meshes are invisible and you want to include them in the collider
|
|
149
181
|
</RigidBody>
|
150
182
|
```
|
151
183
|
|
184
|
+
### Collider Examples
|
185
|
+
<a href="https://codesandbox.io/s/react-three-rapier-auto-colliders-b4coz1"><img src="https://raw.githubusercontent.com/pmndrs/react-three-rapier/HEAD/packages/react-three-rapier/misc/example-auto-colliders.jpg" width="240" /></a>
|
186
|
+
<a href="https://codesandbox.io/s/react-three-rapier-compound-colliders-ol5ybn"><img src="https://raw.githubusercontent.com/pmndrs/react-three-rapier/HEAD/packages/react-three-rapier/misc/example-compound-shapes.jpg" width="240" /></a>
|
187
|
+
|
152
188
|
## Instanced Meshes
|
153
189
|
|
154
190
|
Instanced meshes can also be used and have automatic colliders generated from their mesh.
|
@@ -393,6 +429,9 @@ To detect when a collider enters or leaves another collider, you can use the `on
|
|
393
429
|
</RigidBody>
|
394
430
|
```
|
395
431
|
|
432
|
+
### Sensors Example
|
433
|
+
<a href="https://codesandbox.io/s/react-three-rapier-sensors-byjmsk"><img src="https://raw.githubusercontent.com/pmndrs/react-three-rapier/HEAD/packages/react-three-rapier/misc/example-sensors.jpg" width="240" /></a>
|
434
|
+
|
396
435
|
## Attractors
|
397
436
|
|
398
437
|
An attractor simulates a source of gravity. Any `RigidBody` within range will be _pulled_ (attracted) toward the attractor.
|
@@ -427,6 +466,9 @@ Gravity types:
|
|
427
466
|
- `mass2` is the mass of the rigid-body at the time of calculation. Note that rigid-bodies with colliders will use the mass provided to the collider. This is not a value you can control from the attractor, only from wherever you're creating rigid-body components in the scene.
|
428
467
|
- `distance` is the distance between the attractor and rigid-body at the time of calculation
|
429
468
|
|
469
|
+
### Attractors Example
|
470
|
+
<a href="https://codesandbox.io/s/react-three-rapier-attractors-oyj640"><img src="https://raw.githubusercontent.com/pmndrs/react-three-rapier/HEAD/packages/react-three-rapier/misc/example-attractors.jpg" width="240" /></a>
|
471
|
+
|
430
472
|
## Configuring Time Step Size
|
431
473
|
|
432
474
|
By default, `<Physics>` will simulate the physics world at a fixed rate of 60 frames per second. This can be changed by setting the `timeStep` prop on `<Physics>`:
|
@@ -455,4 +497,7 @@ step(1 / 60);
|
|
455
497
|
|
456
498
|
## Joints
|
457
499
|
|
458
|
-
WIP
|
500
|
+
- WIP
|
501
|
+
|
502
|
+
### Joints Example
|
503
|
+
<a href="https://codesandbox.io/s/react-three-rapier-sensors-byjmsk"><img src="https://raw.githubusercontent.com/pmndrs/react-three-rapier/HEAD/packages/react-three-rapier/misc/example-joints.jpg" width="240" /></a>
|