@react-three/rapier 0.11.2 → 0.12.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/AnyCollider.d.ts +21 -22
- package/dist/declarations/src/Attractor.d.ts +3 -4
- package/dist/declarations/src/Debug.d.ts +2 -5
- package/dist/declarations/src/InstancedRigidBodies.d.ts +2 -2
- package/dist/declarations/src/MeshCollider.d.ts +3 -7
- package/dist/declarations/src/Physics.d.ts +37 -7
- package/dist/declarations/src/RigidBody.d.ts +6 -6
- package/dist/declarations/src/api.d.ts +16 -9
- package/dist/declarations/src/hooks.d.ts +7 -37
- package/dist/declarations/src/index.d.ts +7 -3
- package/dist/declarations/src/joints.d.ts +30 -0
- package/dist/declarations/src/types.d.ts +12 -10
- package/dist/declarations/src/utils.d.ts +1 -0
- package/dist/react-three-rapier.cjs.dev.js +216 -176
- package/dist/react-three-rapier.cjs.prod.js +216 -176
- package/dist/react-three-rapier.esm.js +190 -150
- package/package.json +1 -1
- package/readme.md +288 -62
package/readme.md
CHANGED
@@ -7,9 +7,19 @@
|
|
7
7
|
<a href="https://discord.gg/ZZjjNvJ"><img src="https://img.shields.io/discord/740090768164651008?style=for-the-badge&colorA=0099DA&colorB=ffffff&label=discord&logo=discord&logoColor=ffffff" /></a>
|
8
8
|
</p>
|
9
9
|
|
10
|
-
<p align="center"
|
10
|
+
<p align="center">
|
11
|
+
⚠️ This library is under development. All APIs are subject to change. ⚠️
|
12
|
+
<br />
|
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
|
+
<br/>
|
15
|
+
For available APIs, see <a href="https://pmndrs.github.io/react-three-rapier/>">🧩 API Docs</a>
|
16
|
+
</p>
|
17
|
+
|
18
|
+
---
|
11
19
|
|
12
|
-
|
20
|
+
`react-three/rapier` (or `r3/rapier`) is a wrapper library around the Rapier (https://rapier.rs/docs/user_guides/javascript) WASM-based physics engine, designed to slot seamlessly into a `react-three/fiber` pipeline.
|
21
|
+
|
22
|
+
The goal of this library to is to provide a fast physics engine with minimal friction and small, straight forward API.
|
13
23
|
|
14
24
|
## Basic Usage
|
15
25
|
|
@@ -27,7 +37,7 @@ const App = () => {
|
|
27
37
|
<Torus />
|
28
38
|
</RigidBody>
|
29
39
|
|
30
|
-
<CuboidCollider position={[0, -2, 0]} args={[20, .5, 20]}
|
40
|
+
<CuboidCollider position={[0, -2, 0]} args={[20, .5, 20]} />
|
31
41
|
|
32
42
|
<Debug />
|
33
43
|
</Physics>
|
@@ -39,54 +49,81 @@ const App = () => {
|
|
39
49
|
|
40
50
|
---
|
41
51
|
|
52
|
+
## 📝 Readme note
|
53
|
+
Below follows a guide on core concepts for `react-three/rapier`.
|
54
|
+
For full API outline and documentation, see 🧩 [API Docs](https://pmndrs.github.io/react-three-rapier/).
|
55
|
+
|
56
|
+
---
|
57
|
+
|
42
58
|
## Readme Topics
|
43
59
|
|
44
60
|
- [Basic Usage](#basic-usage)
|
61
|
+
- [📝 Readme note](#-readme-note)
|
45
62
|
- [Readme Topics](#readme-topics)
|
46
63
|
- [The Physics Component](#the-physics-component)
|
47
|
-
- [
|
48
|
-
|
64
|
+
- [The RigidBody Component](#the-rigidbody-component)
|
65
|
+
- [Automatic Colliders](#automatic-colliders)
|
66
|
+
- [Collider Components](#collider-components)
|
67
|
+
- [🖼 Collider Examples](#-collider-examples)
|
49
68
|
- [Instanced Meshes](#instanced-meshes)
|
50
69
|
- [Debug](#debug)
|
51
70
|
- [Collision Events](#collision-events)
|
52
71
|
- [Configuring collision and solver groups](#configuring-collision-and-solver-groups)
|
53
72
|
- [Contact force events](#contact-force-events)
|
54
73
|
- [Sensors](#sensors)
|
55
|
-
- [Sensors Example](
|
74
|
+
- [🖼 Sensors Example](#-sensors-example)
|
56
75
|
- [Attractors](#attractors)
|
57
|
-
- [Attractors Example](
|
76
|
+
- [🖼 Attractors Example](#-attractors-example)
|
58
77
|
- [Configuring Time Step Size](#configuring-time-step-size)
|
59
|
-
- [Manual stepping](#manual-stepping)
|
60
78
|
- [Joints](#joints)
|
61
|
-
- [
|
79
|
+
- [Fixed Joint](#fixed-joint)
|
80
|
+
- [Spherical Joint](#spherical-joint)
|
81
|
+
- [Revolute Joint](#revolute-joint)
|
82
|
+
- [Prismatic Joint](#prismatic-joint)
|
83
|
+
- [Joint APIs](#joint-apis)
|
84
|
+
- [🖼 Joints Example](#-joints-example)
|
85
|
+
- [Advanced hooks usage](#advanced-hooks-usage)
|
86
|
+
- [Manual stepping](#manual-stepping)
|
62
87
|
|
63
88
|
---
|
64
89
|
|
65
90
|
## The Physics Component
|
66
91
|
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
92
|
|
68
|
-
|
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"
|
93
|
+
🧩 See [PhysicsProps docs](https://pmndrs.github.io/react-three-rapier/interfaces/PhysicsProps.html) for available props.
|
74
94
|
|
75
|
-
|
76
|
-
|
95
|
+
```tsx
|
96
|
+
const Scene = () => {
|
97
|
+
return (
|
98
|
+
<Canvas>
|
99
|
+
<Suspense>
|
100
|
+
<Physics
|
101
|
+
gravity={[0,1,0]}
|
102
|
+
interpolation={false}
|
103
|
+
colliders={false}
|
104
|
+
>
|
105
|
+
...
|
106
|
+
</Physics>
|
107
|
+
</Suspense>
|
108
|
+
</Canvas>
|
109
|
+
);
|
110
|
+
}
|
111
|
+
```
|
77
112
|
|
78
|
-
|
79
|
-
|
113
|
+
## The RigidBody Component
|
114
|
+
The `<RigidBody />` component is used to add a `mesh` into the physics world. You use it by wrapping one or more `meshes` and setting desired props. By default, this will automatically generate `Colliders` based on the shape of the wrapped `meshes` (see [Automatic colliders](#automatic-colliders)).
|
80
115
|
|
81
|
-
|
82
|
-
updatePriority?: number;
|
116
|
+
🧩 See [RigidBodyProps docs](https://pmndrs.github.io/react-three-rapier/interfaces/RigidBodyProps.html) for available props.
|
83
117
|
|
84
|
-
|
85
|
-
|
86
|
-
|
118
|
+
```tsx
|
119
|
+
const RigidBodyMesh = () => (
|
120
|
+
<RigidBody>
|
121
|
+
<mesh />
|
122
|
+
</RigidBody>
|
123
|
+
);
|
87
124
|
```
|
88
125
|
|
89
|
-
## Automatic
|
126
|
+
## Automatic Colliders
|
90
127
|
|
91
128
|
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.
|
92
129
|
|
@@ -127,35 +164,47 @@ const Scene = () => (
|
|
127
164
|
<RigidBody position={[0, 10, 0]} colliders="ball">
|
128
165
|
<Sphere />
|
129
166
|
</RigidBody>
|
167
|
+
</Physics>
|
168
|
+
);
|
169
|
+
```
|
130
170
|
|
131
|
-
|
132
|
-
<RigidBody position={[0, 10, 0]}>
|
133
|
-
<Sphere />
|
134
|
-
<BallCollider args={[0.5]} />
|
135
|
-
<BallCollider args={[0.5]} position={[1, 0, 0]} />
|
136
|
-
</RigidBody>
|
137
|
-
|
138
|
-
{/* Make a compound shape with two custom BallColliders, an automatic BallCollider,
|
139
|
-
Two automatic MeshColliders, based on two different shape strategies */}
|
140
|
-
<RigidBody position={[0, 10, 0]} colliders='ball'>
|
141
|
-
<MeshCollider type="trimesh">
|
142
|
-
<mesh ... />
|
143
|
-
</MeshCollider>
|
171
|
+
## Collider Components
|
144
172
|
|
145
|
-
|
146
|
-
<mesh ... />
|
147
|
-
</MeshCollider>
|
173
|
+
You can also create `Colliders` by hand and add them to a `RigidBody` to create compound colliders. This is useful for creating more complex shapes, for creating simplified shapes for performance reasons, or for detecting collisions on specific parts of a mesh.
|
148
174
|
|
149
|
-
|
175
|
+
🧩 See [ColliderProps docs](https://pmndrs.github.io/react-three-rapier/interfaces/ColliderProps.html) for available props.
|
150
176
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
177
|
+
```tsx
|
178
|
+
const Scene = () => (<>
|
179
|
+
{/* Make a compound shape with two custom BallColliders */}
|
180
|
+
<RigidBody position={[0, 10, 0]}>
|
181
|
+
<Sphere />
|
182
|
+
<BallCollider args={[0.5]} />
|
183
|
+
<BallCollider args={[0.5]} position={[1, 0, 0]} />
|
184
|
+
</RigidBody>
|
185
|
+
|
186
|
+
{/* Make a compound shape with two custom BallColliders, an automatic BallCollider,
|
187
|
+
Two automatic MeshColliders, based on two different shape types */}
|
188
|
+
<RigidBody position={[0, 10, 0]} colliders='ball'>
|
189
|
+
<MeshCollider type="trimesh">
|
190
|
+
<mesh ... />
|
191
|
+
</MeshCollider>
|
192
|
+
|
193
|
+
<MeshCollider type="hull">
|
194
|
+
<mesh ... />
|
195
|
+
</MeshCollider>
|
196
|
+
|
197
|
+
<Sphere />
|
198
|
+
|
199
|
+
<BallCollider args={[0.5]} />
|
200
|
+
<BallCollider args={[0.5]} position={[1, 0, 0]} />
|
201
|
+
</RigidBody>
|
202
|
+
<>)
|
156
203
|
```
|
157
204
|
|
158
|
-
|
205
|
+
RigidBodies work inside other transformed objects as well. Simulation runs in world space and is transformed to the objects local space, so that things act as you'd expect.
|
206
|
+
|
207
|
+
> **Note** It's always best to create RigidBodies where the center of gravity is in the center of the object, otherwise you might get some unexpected behavior during simulation interpolation.
|
159
208
|
|
160
209
|
```tsx
|
161
210
|
import { Box } from "@react-three/drei";
|
@@ -181,7 +230,7 @@ If part of our meshes are invisible and you want to include them in the collider
|
|
181
230
|
</RigidBody>
|
182
231
|
```
|
183
232
|
|
184
|
-
### Collider Examples
|
233
|
+
### 🖼 Collider Examples
|
185
234
|
<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
235
|
<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
236
|
|
@@ -191,6 +240,8 @@ Instanced meshes can also be used and have automatic colliders generated from th
|
|
191
240
|
|
192
241
|
By wrapping the `InstancedMesh` in `<InstancedRigidBodies />`, each instance will be attached to an individual `RigidBody`.
|
193
242
|
|
243
|
+
🧩 See [InstancedRigidBodiesProps docs](https://pmndrs.github.io/react-three-rapier/interfaces/InstancedRigidBodiesProps.html) for available props.
|
244
|
+
|
194
245
|
```tsx
|
195
246
|
import { InstancedRigidBodies } from "@react-three/rapier";
|
196
247
|
|
@@ -200,11 +251,15 @@ const Scene = () => {
|
|
200
251
|
const instancedApi = useRef<InstancedRigidBodyApi>(null);
|
201
252
|
|
202
253
|
useEffect(() => {
|
254
|
+
if (!instancedApi.current) {
|
255
|
+
return
|
256
|
+
}
|
257
|
+
|
203
258
|
// You can access individual instanced by their index
|
204
|
-
instancedApi.at(40).applyImpulse({ x: 0, y: 10, z: 0 });
|
259
|
+
instancedApi.current.at(40).applyImpulse({ x: 0, y: 10, z: 0 });
|
205
260
|
|
206
261
|
// Or update all instances as if they were in an array
|
207
|
-
instancedApi.forEach((api) => {
|
262
|
+
instancedApi.current.forEach((api) => {
|
208
263
|
api.applyImpulse({ x: 0, y: 10, z: 0 });
|
209
264
|
});
|
210
265
|
}, []);
|
@@ -272,6 +327,8 @@ const Scene = () => {
|
|
272
327
|
|
273
328
|
You can subscribe to collision and state events on a RigidBody:
|
274
329
|
|
330
|
+
🧩 See [onCollisionEnter / onCollisionExit docs](https://pmndrs.github.io/react-three-rapier/interfaces/RigidBodyProps.html#onCollisionEnter) for more information.
|
331
|
+
|
275
332
|
```tsx
|
276
333
|
const RigidBottle = () => {
|
277
334
|
const [isAsleep, setIsAsleep] = useState(false);
|
@@ -379,7 +436,7 @@ Contact force events are triggered on `<RigidBody>` and any collider components
|
|
379
436
|
console.log(`The total force generated was: ${payload.totalForce}`);
|
380
437
|
}}>
|
381
438
|
<Sphere>
|
382
|
-
<meshPhysicalMaterial color={'grey'}
|
439
|
+
<meshPhysicalMaterial color={'grey'} />
|
383
440
|
</Sphere>
|
384
441
|
</RigidBody>
|
385
442
|
```
|
@@ -417,6 +474,10 @@ A Collider can be set to be a sensor, which means that it will not generate any
|
|
417
474
|
|
418
475
|
To detect when a collider enters or leaves another collider, you can use the `onIntersectionEnter` and `onIntersectionExit` events on the collider.
|
419
476
|
|
477
|
+
🧩 See [onIntersectionEnter / onIntersectionExit docs](https://pmndrs.github.io/react-three-rapier/interfaces/RigidBodyProps.html#onIntersectionEnter) for more information.
|
478
|
+
|
479
|
+
```tsx
|
480
|
+
|
420
481
|
```tsx
|
421
482
|
<RigidBody>
|
422
483
|
<GoalPosts />
|
@@ -429,7 +490,7 @@ To detect when a collider enters or leaves another collider, you can use the `on
|
|
429
490
|
</RigidBody>
|
430
491
|
```
|
431
492
|
|
432
|
-
### Sensors Example
|
493
|
+
### 🖼 Sensors Example
|
433
494
|
<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
495
|
|
435
496
|
## Attractors
|
@@ -439,6 +500,8 @@ Setting the `strength` to a negative value will cause the `RigidBody` to be _pus
|
|
439
500
|
|
440
501
|
The force applied to rigid-bodies within range is calculated differently depending on the `type`.
|
441
502
|
|
503
|
+
🧩 See [Attractor docs](https://pmndrs.github.io/react-three-rapier/interfaces/AttractorProps.html) for all available props.
|
504
|
+
|
442
505
|
```tsx
|
443
506
|
// Standard attractor
|
444
507
|
<Attractor range={10} strength={5} type="linear" position={[5, -5, 0]} />
|
@@ -466,7 +529,7 @@ Gravity types:
|
|
466
529
|
- `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.
|
467
530
|
- `distance` is the distance between the attractor and rigid-body at the time of calculation
|
468
531
|
|
469
|
-
### Attractors Example
|
532
|
+
### 🖼 Attractors Example
|
470
533
|
<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
534
|
|
472
535
|
## Configuring Time Step Size
|
@@ -485,19 +548,182 @@ The `timeStep` prop may also be set to `"vary"`, which will cause the simulation
|
|
485
548
|
|
486
549
|
> **Note** This is useful for games that run at variable frame rates, but may cause instability in the simulation. It also prevents the physics simulation from being fully deterministic. Please use with care!
|
487
550
|
|
488
|
-
##
|
551
|
+
## Joints
|
552
|
+
Joints can be made between two `RigidBodies` to provide a way to restrict a motion of a body in relation to another.
|
553
|
+
> Read more about joints in Rapier: https://rapier.rs/docs/user_guides/javascript/joints
|
554
|
+
|
555
|
+
Joints are available in `r3/rapier` as hooks.
|
489
556
|
|
490
|
-
|
557
|
+
There are 4 different joint types available:
|
558
|
+
- Fixed (two bodies are fixed together)
|
559
|
+
- Spherical (two bodies are connected by a ball and socket, for things like arms or chains)
|
560
|
+
- Revolute (two bodies are connected by a hinge, for things like doors or wheels)
|
561
|
+
- Prismatic (two bodies are connected by a sliding joint, for things like pistons or sliders)
|
562
|
+
|
563
|
+
### Fixed Joint
|
564
|
+
A fixed joint ensures that two rigid-bodies don't move relative to each other. Fixed joints are characterized by one local frame (represented by an isometry) on each rigid-body. The fixed-joint makes these frames coincide in world-space.
|
565
|
+
|
566
|
+
🧩 See [FixedJoint docs](https://pmndrs.github.io/react-three-rapier/functions/useFixedJoint.html) for available options.
|
491
567
|
|
492
568
|
```tsx
|
493
|
-
const
|
569
|
+
const JointedThing = () => {
|
570
|
+
const joint = useFixedJoint(
|
571
|
+
bodyA,
|
572
|
+
bodyB,
|
573
|
+
[
|
574
|
+
[0, 0, 0], // Position of the joint in bodyA's local space
|
575
|
+
[0, 0, 0, 1], // Orientation of the joint in bodyA's local space
|
576
|
+
[0, 0, 0], // Position of the joint in bodyB's local space
|
577
|
+
[0, 0, 0, 1], // Orientation of the joint in bodyB's local space
|
578
|
+
]);
|
494
579
|
|
495
|
-
|
580
|
+
return (
|
581
|
+
<group>
|
582
|
+
<RigidBody ref={bodyA}>
|
583
|
+
<mesh />
|
584
|
+
</RigidBody>
|
585
|
+
<RigidBody ref={bodyB}>
|
586
|
+
<mesh />
|
587
|
+
</RigidBody>
|
588
|
+
</group>
|
589
|
+
);
|
590
|
+
}
|
496
591
|
```
|
497
592
|
|
498
|
-
|
593
|
+
### Spherical Joint
|
594
|
+
The spherical joint ensures that two points on the local-spaces of two rigid-bodies always coincide (it prevents any relative translational motion at this points).
|
499
595
|
|
500
|
-
-
|
596
|
+
🧩 See [SphericalJoint docs](https://pmndrs.github.io/react-three-rapier/functions/useSphericalJoint.html) for available options.
|
501
597
|
|
502
|
-
|
503
|
-
|
598
|
+
```tsx
|
599
|
+
|
600
|
+
```tsx
|
601
|
+
const JointedThing = () => {
|
602
|
+
const joint = useSphericalJoint(
|
603
|
+
bodyA,
|
604
|
+
bodyB,
|
605
|
+
[
|
606
|
+
[0, 0, 0], // Position of the joint in bodyA's local space
|
607
|
+
[0, 0, 0], // Position of the joint in bodyB's local space
|
608
|
+
]);
|
609
|
+
|
610
|
+
return (
|
611
|
+
<group>
|
612
|
+
<RigidBody ref={bodyA}>
|
613
|
+
<mesh />
|
614
|
+
</RigidBody>
|
615
|
+
<RigidBody ref={bodyB}>
|
616
|
+
<mesh />
|
617
|
+
</RigidBody>
|
618
|
+
</group>
|
619
|
+
);
|
620
|
+
}
|
621
|
+
```
|
622
|
+
|
623
|
+
### Revolute Joint
|
624
|
+
The revolute joint prevents any relative movement between two rigid-bodies, except for relative rotations along one axis. This is typically used to simulate wheels, fans, etc.
|
625
|
+
|
626
|
+
🧩 See [RevoluteJoint docs](https://pmndrs.github.io/react-three-rapier/functions/useRevoluteJoint.html) for available options.
|
627
|
+
|
628
|
+
```tsx
|
629
|
+
const JointedThing = () => {
|
630
|
+
const joint = useRevoluteJoint(
|
631
|
+
bodyA,
|
632
|
+
bodyB,
|
633
|
+
[
|
634
|
+
[0, 0, 0], // Position of the joint in bodyA's local space
|
635
|
+
[0, 0, 0], // Position of the joint in bodyB's local space
|
636
|
+
[0, 0, 0], // Axis of the joint, expressed in the local-space of the rigid-bodies it is attached to.
|
637
|
+
]);
|
638
|
+
|
639
|
+
return (
|
640
|
+
<group>
|
641
|
+
<RigidBody ref={bodyA}>
|
642
|
+
<mesh />
|
643
|
+
</RigidBody>
|
644
|
+
<RigidBody ref={bodyB}>
|
645
|
+
<mesh />
|
646
|
+
</RigidBody>
|
647
|
+
</group>
|
648
|
+
);
|
649
|
+
}
|
650
|
+
```
|
651
|
+
|
652
|
+
### Prismatic Joint
|
653
|
+
The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
|
654
|
+
|
655
|
+
🧩 See [PrismaticJoint docs](https://pmndrs.github.io/react-three-rapier/functions/usePrismaticJoint.html) for available options.
|
656
|
+
|
657
|
+
```tsx
|
658
|
+
|
659
|
+
```tsx
|
660
|
+
const JointedThing = () => {
|
661
|
+
const joint = usePrismaticJoint(
|
662
|
+
bodyA,
|
663
|
+
bodyB,
|
664
|
+
[
|
665
|
+
[0, 0, 0], // Position of the joint in bodyA's local space
|
666
|
+
[0, 0, 0], // Position of the joint in bodyB's local space
|
667
|
+
[0, 0, 0], // Axis of the joint, expressed in the local-space of the rigid-bodies it is attached to.
|
668
|
+
]);
|
669
|
+
|
670
|
+
return (
|
671
|
+
<group>
|
672
|
+
<RigidBody ref={bodyA}>
|
673
|
+
<mesh />
|
674
|
+
</RigidBody>
|
675
|
+
<RigidBody ref={bodyB}>
|
676
|
+
<mesh />
|
677
|
+
</RigidBody>
|
678
|
+
</group>
|
679
|
+
);
|
680
|
+
}
|
681
|
+
```
|
682
|
+
|
683
|
+
### Joint APIs
|
684
|
+
Joints can be controlled imperatively similarily to how `RigidBody` components can be controlled.
|
685
|
+
|
686
|
+
🧩 See [Joint API docs](https://pmndrs.github.io/react-three-rapier/interfaces/JointApi.html) for more information.
|
687
|
+
|
688
|
+
```tsx
|
689
|
+
const JointedThing = () => {
|
690
|
+
const joint = useSphericalJoint(...)
|
691
|
+
|
692
|
+
useEffect(() => {
|
693
|
+
joint.configureMotorVelocity(1, 0)
|
694
|
+
|
695
|
+
// Disable contacts between the two joint bodies
|
696
|
+
joint.raw().setContactsEnabled(false)
|
697
|
+
}, [])
|
698
|
+
|
699
|
+
return ...
|
700
|
+
}
|
701
|
+
```
|
702
|
+
|
703
|
+
|
704
|
+
### 🖼 Joints Example
|
705
|
+
<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>
|
706
|
+
|
707
|
+
## Advanced hooks usage
|
708
|
+
|
709
|
+
Advanced users might need granular access to the physics loop and direct access to the `world` instance. This can be done by using the following hooks:
|
710
|
+
|
711
|
+
- `useRapier`
|
712
|
+
Gives you access to the `world`, direct access to `rapier`, and more.
|
713
|
+
🧩 See [useRapier docs](https://pmndrs.github.io/react-three-rapier/interfaces/RapierContext.html) for more information.
|
714
|
+
- `useBeforePhysicsStep`
|
715
|
+
Allows you to run code before the physics simulation is stepped.
|
716
|
+
🧩 See [useBeforePhysicsStep docs](https://pmndrs.github.io/react-three-rapier/functions/useBeforePhysicsStep.html) for more information.
|
717
|
+
- `useAfterPhysicsStep`
|
718
|
+
Allows you to run code after the physics simulation is stepped.
|
719
|
+
🧩 See [useAfterPhysicsStep docs](https://pmndrs.github.io/react-three-rapier/functions/useAfterPhysicsStep.html) for more information.
|
720
|
+
|
721
|
+
### Manual stepping
|
722
|
+
|
723
|
+
You can manually step the physics simulation by calling the `step` method from the `useRapier` hook.
|
724
|
+
|
725
|
+
```tsx
|
726
|
+
const { step } = useRapier();
|
727
|
+
|
728
|
+
step(1 / 60);
|
729
|
+
```
|