@react-three/rapier 0.8.2 → 0.10.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-three/rapier",
3
- "version": "0.8.2",
3
+ "version": "0.10.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",
package/readme.md CHANGED
@@ -11,12 +11,12 @@
11
11
 
12
12
  For contributions, please read the [contributing guide](https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/CONTRIBUTING.md).
13
13
 
14
- ## Usage
14
+ ## Basic Usage
15
15
 
16
16
  ```tsx
17
17
  import { Box, Torus } from "@react-three/drei";
18
18
  import { Canvas } from "@react-three/fiber";
19
- import { Physics, RigidBody } from "@react-three/rapier";
19
+ import { Physics, RigidBody, Debug } from "@react-three/rapier";
20
20
 
21
21
  const App = () => {
22
22
  return (
@@ -27,9 +27,9 @@ const App = () => {
27
27
  <Torus />
28
28
  </RigidBody>
29
29
 
30
- <RigidBody position={[0, -2, 0]} type="kinematicPosition">
31
- <Box args={[20, 0.5, 20]} />
32
- </RigidBody>
30
+ <CuboidCollider position={[0, -2, 0]} args={[20, .5, 20]}>
31
+
32
+ <Debug />
33
33
  </Physics>
34
34
  </Suspense>
35
35
  </Canvas>
@@ -37,6 +37,23 @@ const App = () => {
37
37
  };
38
38
  ```
39
39
 
40
+ ---
41
+
42
+ ## Readme Topics
43
+
44
+ - [Automatic Colliders](#automatic-colliders)
45
+ - [Instanced Meshes](#instanced-meshes)
46
+ - [Debug](#debug)
47
+ - [Collision Events](#collision-events)
48
+ - [Collision Groups](#configuring-collision-and-solver-groups)
49
+ - [Contact Force Events](#contact-force-events)
50
+ - [Sensors](#sensors)
51
+ - [Attractors](#attractors)
52
+ - [The timeStep](#configuring-time-step-size)
53
+ - [Manual stepping](#manual-stepping)
54
+
55
+ ---
56
+
40
57
  ## Automatic colliders
41
58
 
42
59
  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.
@@ -138,8 +155,6 @@ Instanced meshes can also be used and have automatic colliders generated from th
138
155
 
139
156
  By wrapping the `InstancedMesh` in `<InstancedRigidBodies />`, each instance will be attached to an individual `RigidBody`.
140
157
 
141
- > Note: Custom colliders (compound shapes) for InstancedMesh is currently not supported
142
-
143
158
  ```tsx
144
159
  import { InstancedRigidBodies } from "@react-three/rapier";
145
160
 
@@ -225,21 +240,35 @@ You can subscribe to collision and state events on a RigidBody:
225
240
  const RigidBottle = () => {
226
241
  const [isAsleep, setIsAsleep] = useState(false);
227
242
 
228
- return (
243
+ return (
229
244
  <RigidBody
230
245
  colliders="hull"
231
246
  onSleep={() => setIsAsleep(true)}
232
247
  onWake={() => setIsAsleep(false)}
233
- onCollisionEnter={({manifold}) => {
234
- console.log('Collision at world position ', manifold.solverContactPoint(0))
248
+ name="Bally McBallFace"
249
+ onCollisionEnter={({ manifold, target, other }) => {
250
+ console.log(
251
+ "Collision at world position ",
252
+ manifold.solverContactPoint(0)
253
+ );
254
+
255
+ if (other.rigidBodyObject) {
256
+ console.log(
257
+ // this rigid body's Object3D
258
+ target.rigidBodyObject.name,
259
+ " collided with ",
260
+ // the other rigid body's Object3D
261
+ other.rigidBodyObject.name
262
+ );
263
+ }
235
264
  }}
236
265
  >
237
266
  <Sphere>
238
- <meshPhysicalMaterial color={isAsleep ? 'white' : 'blue'}>
267
+ <meshPhysicalMaterial color={isAsleep ? "white" : "blue"} />
239
268
  </Sphere>
240
269
  </RigidBody>
241
- )
242
- }
270
+ );
271
+ };
243
272
  ```
244
273
 
245
274
  You may also subscribe to collision events on individual Colliders:
@@ -258,14 +287,21 @@ You may also subscribe to collision events on individual Colliders:
258
287
  The `payload` object for all collision callbacks contains the following properties:
259
288
 
260
289
  - `target`
261
- The other rigidbody that was involved in the collision event.
262
- - `collider`
263
- The other collider that was involved in the collision event.
264
- - `manifold` (enter only)
290
+ `CollisionTarget` of the object firing the event.
291
+ - `other`
292
+ `CollisionTarget` of the other object involved in the event.
293
+ - `manifold` (onCollisionEnter only)
265
294
  The [contact manifold](https://rapier.rs/javascript3d/classes/TempContactManifold.html) generated by the collision event.
266
- - `flipped` (enter only)
295
+ - `flipped` (onCollisionEnter only)
267
296
  `true` if the data in the `manifold` [is flipped](https://rapier.rs/javascript3d/classes/World.html#contactPair).
268
297
 
298
+ A `CollisionTarget` is an object containing references to objects involved in a collision event. It has the following properties:
299
+
300
+ - `rigidBody` (if exists): `Rapier.RigidBody`
301
+ - `rigidBodyObject` (if exists): `Three.Object3D`
302
+ - `collider`: `Rapier.Collider`
303
+ - `colliderObject`: `Three.Object3D`
304
+
269
305
  ### Configuring collision and solver groups
270
306
 
271
307
  Both `<RigidBody>` as well as all collider components allow you to configure `collisionsGroups` and `solverGroups` properties that configures which groups the colliders are in, and what other groups they should interact with in potential collision and solving events (you will find more details on this in the [Rapier documentation](https://rapier.rs/docs/user_guides/javascript/colliders/#collision-groups-and-solver-groups).)
@@ -296,10 +332,55 @@ When the second argument is omitted, the collider will interact with all groups:
296
332
 
297
333
  > **Note** By default, colliders are members of all groups, and will interact with all other groups.
298
334
 
335
+ ## Contact force events
336
+
337
+ Contact force events are triggered on `<RigidBody>` and any collider components when two objects collider.
338
+
339
+ ```tsx
340
+ <RigidBody
341
+ colliders="ball"
342
+ onContactForce={(payload) => {
343
+ console.log(`The total force generated was: ${payload.totalForce}`);
344
+ }}>
345
+ <Sphere>
346
+ <meshPhysicalMaterial color={'grey'}>
347
+ </Sphere>
348
+ </RigidBody>
349
+ ```
350
+
351
+ The payload for the contact force event contains the following properties:
352
+
353
+ - `target`
354
+ `CollisionTarget` of the object firing the event
355
+ - `other`
356
+ `CollisionTarget` of the other object involved in the event
357
+ - `totalForce`
358
+ The sum of all the forces between the two colliders
359
+ - `totalForceMagnitude`
360
+ The sum of the magnitudes of each force between the two colliders
361
+ - `maxForceDirection`
362
+ The magnitude of the largest force at a contact point of this contact pair
363
+ - `maxForceMagnitude`
364
+ The world-space (unit) direction of the force with strongest magnitude
365
+
366
+ More information about each property can be found in the rapier [TempContactForceEvent API documentation](https://rapier.rs/javascript3d/classes/TempContactForceEvent.html).
367
+
368
+ You can also add the `onContactForce` event to any collider.
369
+
370
+ ```tsx
371
+ <CapsuleCollider
372
+ onContactForce={(payload) => {
373
+ /* ... */
374
+ }}
375
+ />
376
+ ```
377
+
299
378
  ## Sensors
300
379
 
301
380
  A Collider can be set to be a sensor, which means that it will not generate any contact points, and will not be affected by forces. This is useful for detecting when a collider enters or leaves another collider, without affecting the other collider.
302
381
 
382
+ To detect when a collider enters or leaves another collider, you can use the `onIntersectionEnter` and `onIntersectionExit` events on the collider.
383
+
303
384
  ```tsx
304
385
  <RigidBody>
305
386
  <GoalPosts />
@@ -312,9 +393,39 @@ A Collider can be set to be a sensor, which means that it will not generate any
312
393
  </RigidBody>
313
394
  ```
314
395
 
315
- ## Joints
396
+ ## Attractors
316
397
 
317
- WIP
398
+ An attractor simulates a source of gravity. Any `RigidBody` within range will be _pulled_ (attracted) toward the attractor.
399
+ Setting the `strength` to a negative value will cause the `RigidBody` to be _pushed_ (repelled) away from the attractor.
400
+
401
+ The force applied to rigid-bodies within range is calculated differently depending on the `type`.
402
+
403
+ ```tsx
404
+ // Standard attractor
405
+ <Attractor range={10} strength={5} type="linear" position={[5, -5, 0]} />
406
+
407
+ // An attractor with negative strength, repels RigidBodies
408
+ <Attractor range={10} strength={-5} position={[5, -5, 0]} />
409
+
410
+ // You can also assign InteractionGroups.
411
+ // An attractor belonging to group 0 only affecting bodies in group 2, and 3
412
+ <Attractor range={10} strength={10} position={[5, -5, 0]} collisionGroups={interactionGroups(0, [2,3])} />
413
+ ```
414
+
415
+ Gravity types:
416
+
417
+ - "static" (Default)
418
+ Static gravity means that the same force (`strength`) is applied on all rigid-bodies within range, regardless of distance.
419
+
420
+ - "linear"
421
+ Linear gravity means that force is calculated as `strength * distance / range`. That means the force applied decreases the farther a rigid-body is from the attractor position.
422
+
423
+ - "newtonian"
424
+ Newtonian gravity uses the traditional method of calculating gravitational force (`F = GMm/r^2`) and as such force is calculated as `gravitationalConstant * mass1 * mass2 / Math.pow(distance, 2)`.
425
+ - `gravitationalConstant` defaults to 6.673e-11 but you can provide your own
426
+ - `mass1` here is the "mass" of the Attractor, which is just the `strength` property
427
+ - `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
+ - `distance` is the distance between the attractor and rigid-body at the time of calculation
318
429
 
319
430
  ## Configuring Time Step Size
320
431
 
@@ -332,23 +443,16 @@ The `timeStep` prop may also be set to `"vary"`, which will cause the simulation
332
443
 
333
444
  > **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!
334
445
 
335
- ---
446
+ ## Manual stepping
447
+
448
+ You can also manually step the physics simulation by calling the `step` method from the `useRapier` hook.
449
+
450
+ ```tsx
451
+ const { step } = useRapier();
452
+
453
+ step(1 / 60);
454
+ ```
336
455
 
337
- ## Roadmap
338
-
339
- In order, but also not necessarily:
340
-
341
- - [x] RigidBodies, Colliders
342
- - [x] Joints
343
- - [x] Nested objects retain world transforms
344
- - [x] Nested objects retain correct collider scale
345
- - [x] Automatic colliders based on rigidbody children
346
- - [x] Translation and rotational constraints
347
- - [x] Collision events
348
- - [x] Colliders outside RigidBodies
349
- - [x] InstancedMesh support
350
- - [x] Timestep improvements for determinism
351
- - [x] Normalize and improve collision events (add events to single Colliders)
352
- - [x] Add collision events to InstancedRigidBodies
353
- - [ ] Docs
354
- - [ ] CodeSandbox examples
456
+ ## Joints
457
+
458
+ WIP