@react-three/rapier 0.11.2 → 0.11.3

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.
@@ -72,6 +72,7 @@ export declare type UseBodyOptions = Omit<UseRigidBodyOptions, "shape">;
72
72
  export declare type RigidBodyTypeString = "fixed" | "dynamic" | "kinematicPosition" | "kinematicVelocity";
73
73
  export declare type ColliderShape = "cuboid" | "trimesh" | "ball" | "capsule" | "convexHull" | "heightfield" | "polyline" | "roundCuboid" | "cylinder" | "roundCylinder" | "cone" | "roundCone" | "convexMesh" | "roundConvexHull" | "roundConvexMesh";
74
74
  export declare type Vector3Array = [x: number, y: number, z: number];
75
+ export declare type Vector4Array = [x: number, y: number, z: number, w: number];
75
76
  export declare type Boolean3Array = [x: boolean, y: boolean, z: boolean];
76
77
  export interface UseColliderOptions<ColliderArgs extends Array<unknown>> {
77
78
  /**
@@ -324,9 +325,9 @@ export declare type SphericalJointParams = [
324
325
  ];
325
326
  export declare type FixedJointParams = [
326
327
  body1Anchor: Vector3Array,
327
- body1LocalFrame: Vector3Array,
328
+ body1LocalFrame: Vector4Array,
328
329
  body2Anchor: Vector3Array,
329
- body2LocalFrame: Vector3Array
330
+ body2LocalFrame: Vector4Array
330
331
  ];
331
332
  export declare type PrismaticJointParams = [
332
333
  body1Anchor: Vector3Array,
@@ -2,6 +2,7 @@ import { Quaternion as RapierQuaternion, Vector3 as RapierVector3 } from "@dimfo
2
2
  import { Euler, Quaternion, Vector3 } from "three";
3
3
  import { RigidBodyTypeString, Vector3Array } from "./types";
4
4
  export declare const vectorArrayToVector3: (arr: Vector3Array) => Vector3;
5
+ export declare const tupleToObject: <T extends readonly any[], K extends readonly string[]>(tuple: T, keys: K) => { [Key in K[number]]: T[number]; };
5
6
  export declare const vector3ToQuaternion: (v: Vector3) => Quaternion;
6
7
  export declare const rapierVector3ToVector3: ({ x, y, z }: RapierVector3) => Vector3;
7
8
  export declare const rapierQuaternionToQuaternion: ({ x, y, z, w }: RapierQuaternion) => Quaternion;
@@ -85,6 +85,12 @@ const vectorArrayToVector3 = arr => {
85
85
  const [x, y, z] = arr;
86
86
  return new three.Vector3(x, y, z);
87
87
  };
88
+ const tupleToObject = (tuple, keys) => {
89
+ return keys.reduce((obj, key, i) => {
90
+ obj[key] = tuple[i];
91
+ return obj;
92
+ }, {});
93
+ };
88
94
  const rapierVector3ToVector3 = ({
89
95
  x,
90
96
  y,
@@ -860,11 +866,7 @@ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor,
860
866
  const {
861
867
  rapier
862
868
  } = useRapier();
863
- return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToVector3(body1Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body1LocalFrame)), {}, {
864
- w: 1
865
- }), vectorArrayToVector3(body2Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body2LocalFrame)), {}, {
866
- w: 1
867
- })));
869
+ return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToVector3(body1Anchor), tupleToObject(body1LocalFrame, ["x", "y", "z", "w"]), vectorArrayToVector3(body2Anchor), tupleToObject(body2LocalFrame, ["x", "y", "z", "w"])));
868
870
  };
869
871
  /**
870
872
  * The spherical joint ensures that two points on the local-spaces of two rigid-bodies always coincide (it prevents any relative
@@ -85,6 +85,12 @@ const vectorArrayToVector3 = arr => {
85
85
  const [x, y, z] = arr;
86
86
  return new three.Vector3(x, y, z);
87
87
  };
88
+ const tupleToObject = (tuple, keys) => {
89
+ return keys.reduce((obj, key, i) => {
90
+ obj[key] = tuple[i];
91
+ return obj;
92
+ }, {});
93
+ };
88
94
  const rapierVector3ToVector3 = ({
89
95
  x,
90
96
  y,
@@ -860,11 +866,7 @@ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor,
860
866
  const {
861
867
  rapier
862
868
  } = useRapier();
863
- return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToVector3(body1Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body1LocalFrame)), {}, {
864
- w: 1
865
- }), vectorArrayToVector3(body2Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body2LocalFrame)), {}, {
866
- w: 1
867
- })));
869
+ return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToVector3(body1Anchor), tupleToObject(body1LocalFrame, ["x", "y", "z", "w"]), vectorArrayToVector3(body2Anchor), tupleToObject(body2LocalFrame, ["x", "y", "z", "w"])));
868
870
  };
869
871
  /**
870
872
  * The spherical joint ensures that two points on the local-spaces of two rigid-bodies always coincide (it prevents any relative
@@ -60,6 +60,12 @@ const vectorArrayToVector3 = arr => {
60
60
  const [x, y, z] = arr;
61
61
  return new Vector3(x, y, z);
62
62
  };
63
+ const tupleToObject = (tuple, keys) => {
64
+ return keys.reduce((obj, key, i) => {
65
+ obj[key] = tuple[i];
66
+ return obj;
67
+ }, {});
68
+ };
63
69
  const rapierVector3ToVector3 = ({
64
70
  x,
65
71
  y,
@@ -835,11 +841,7 @@ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor,
835
841
  const {
836
842
  rapier
837
843
  } = useRapier();
838
- return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToVector3(body1Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body1LocalFrame)), {}, {
839
- w: 1
840
- }), vectorArrayToVector3(body2Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body2LocalFrame)), {}, {
841
- w: 1
842
- })));
844
+ return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToVector3(body1Anchor), tupleToObject(body1LocalFrame, ["x", "y", "z", "w"]), vectorArrayToVector3(body2Anchor), tupleToObject(body2LocalFrame, ["x", "y", "z", "w"])));
843
845
  };
844
846
  /**
845
847
  * The spherical joint ensures that two points on the local-spaces of two rigid-bodies always coincide (it prevents any relative
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-three/rapier",
3
- "version": "0.11.2",
3
+ "version": "0.11.3",
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
@@ -7,9 +7,17 @@
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">⚠️ Under heavy development. All APIs are subject to change. ⚠️</p>
10
+ <p align="center">⚠️ Under heavy development. All APIs are subject to change. ⚠️
11
+ <br />
12
+ 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>.
13
+ </p>
14
+
15
+ ---
16
+
17
+ `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.
18
+
19
+ The goal of this library to is to provide a fast physics engine with minimal friction and small, straight forward API.
11
20
 
12
- For contributions, please read the [contributing guide](https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/CONTRIBUTING.md).
13
21
 
14
22
  ## Basic Usage
15
23
 
@@ -27,7 +35,7 @@ const App = () => {
27
35
  <Torus />
28
36
  </RigidBody>
29
37
 
30
- <CuboidCollider position={[0, -2, 0]} args={[20, .5, 20]}>
38
+ <CuboidCollider position={[0, -2, 0]} args={[20, .5, 20]} />
31
39
 
32
40
  <Debug />
33
41
  </Physics>
@@ -58,6 +66,11 @@ const App = () => {
58
66
  - [Configuring Time Step Size](#configuring-time-step-size)
59
67
  - [Manual stepping](#manual-stepping)
60
68
  - [Joints](#joints)
69
+ - [Fixed Joint](#fixed-joint)
70
+ - [Spherical Joint](#spherical-joint)
71
+ - [Revolute Joint](#revolute-joint)
72
+ - [Prismatic Joint](#prismatic-joint)
73
+ - [Joint APIs](#joint-apis)
61
74
  - [Joints Example](#joints-example)
62
75
 
63
76
  ---
@@ -200,11 +213,15 @@ const Scene = () => {
200
213
  const instancedApi = useRef<InstancedRigidBodyApi>(null);
201
214
 
202
215
  useEffect(() => {
216
+ if (!instancedApi.current) {
217
+ return
218
+ }
219
+
203
220
  // You can access individual instanced by their index
204
- instancedApi.at(40).applyImpulse({ x: 0, y: 10, z: 0 });
221
+ instancedApi.current.at(40).applyImpulse({ x: 0, y: 10, z: 0 });
205
222
 
206
223
  // Or update all instances as if they were in an array
207
- instancedApi.forEach((api) => {
224
+ instancedApi.current.forEach((api) => {
208
225
  api.applyImpulse({ x: 0, y: 10, z: 0 });
209
226
  });
210
227
  }, []);
@@ -379,7 +396,7 @@ Contact force events are triggered on `<RigidBody>` and any collider components
379
396
  console.log(`The total force generated was: ${payload.totalForce}`);
380
397
  }}>
381
398
  <Sphere>
382
- <meshPhysicalMaterial color={'grey'}>
399
+ <meshPhysicalMaterial color={'grey'} />
383
400
  </Sphere>
384
401
  </RigidBody>
385
402
  ```
@@ -496,8 +513,143 @@ step(1 / 60);
496
513
  ```
497
514
 
498
515
  ## Joints
516
+ Joints can be made between two `RigidBodies` to provide a way to restrict a motion of a body in relation to another.
517
+ > Read more about joints in Rapier: https://rapier.rs/docs/user_guides/javascript/joints
518
+
519
+ Joints are available in `r3/rapier` as hooks.
520
+
521
+ There are 4 different joint types available:
522
+ - Fixed (two bodies are fixed together)
523
+ - Spherical (two bodies are connected by a ball and socket, for things like arms or chains)
524
+ - Revolute (two bodies are connected by a hinge, for things like doors or wheels)
525
+ - Prismatic (two bodies are connected by a sliding joint, for things like pistons or sliders)
526
+
527
+ ### Fixed Joint
528
+ 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.
529
+
530
+ ```tsx
531
+ const JointedThing = () => {
532
+ const joint = useFixedJoint(
533
+ bodyA,
534
+ bodyB,
535
+ [
536
+ [0, 0, 0], // Position of the joint in bodyA's local space
537
+ [0, 0, 0, 1], // Orientation of the joint in bodyA's local space
538
+ [0, 0, 0], // Position of the joint in bodyB's local space
539
+ [0, 0, 0, 1], // Orientation of the joint in bodyB's local space
540
+ ]);
541
+
542
+ return (
543
+ <group>
544
+ <RigidBody ref={bodyA}>
545
+ <mesh />
546
+ </RigidBody>
547
+ <RigidBody ref={bodyB}>
548
+ <mesh />
549
+ </RigidBody>
550
+ </group>
551
+ );
552
+ }
553
+ ```
554
+
555
+ ### Spherical Joint
556
+ 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).
557
+
558
+ ```tsx
559
+ const JointedThing = () => {
560
+ const joint = useSphericalJoint(
561
+ bodyA,
562
+ bodyB,
563
+ [
564
+ [0, 0, 0], // Position of the joint in bodyA's local space
565
+ [0, 0, 0], // Position of the joint in bodyB's local space
566
+ ]);
567
+
568
+ return (
569
+ <group>
570
+ <RigidBody ref={bodyA}>
571
+ <mesh />
572
+ </RigidBody>
573
+ <RigidBody ref={bodyB}>
574
+ <mesh />
575
+ </RigidBody>
576
+ </group>
577
+ );
578
+ }
579
+ ```
580
+
581
+ ### Revolute Joint
582
+ 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.
583
+
584
+ ```tsx
585
+ const JointedThing = () => {
586
+ const joint = useRevoluteJoint(
587
+ bodyA,
588
+ bodyB,
589
+ [
590
+ [0, 0, 0], // Position of the joint in bodyA's local space
591
+ [0, 0, 0], // Position of the joint in bodyB's local space
592
+ [0, 0, 0], // Axis of the joint, expressed in the local-space of the rigid-bodies it is attached to.
593
+ ]);
594
+
595
+ return (
596
+ <group>
597
+ <RigidBody ref={bodyA}>
598
+ <mesh />
599
+ </RigidBody>
600
+ <RigidBody ref={bodyB}>
601
+ <mesh />
602
+ </RigidBody>
603
+ </group>
604
+ );
605
+ }
606
+ ```
607
+
608
+ ### Prismatic Joint
609
+ The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
610
+
611
+ ```tsx
612
+ const JointedThing = () => {
613
+ const joint = usePrismaticJoint(
614
+ bodyA,
615
+ bodyB,
616
+ [
617
+ [0, 0, 0], // Position of the joint in bodyA's local space
618
+ [0, 0, 0], // Position of the joint in bodyB's local space
619
+ [0, 0, 0], // Axis of the joint, expressed in the local-space of the rigid-bodies it is attached to.
620
+ ]);
621
+
622
+ return (
623
+ <group>
624
+ <RigidBody ref={bodyA}>
625
+ <mesh />
626
+ </RigidBody>
627
+ <RigidBody ref={bodyB}>
628
+ <mesh />
629
+ </RigidBody>
630
+ </group>
631
+ );
632
+ }
633
+ ```
634
+
635
+ ### Joint APIs
636
+ Joints can be controlled imperatively similarily to how `RigidBody` components can be controlled.
637
+
638
+ ```tsx
639
+ const JointedThing = () => {
640
+ const joint = useSphericalJoint(...)
641
+
642
+ useEffect(() => {
643
+ joint.configureMotorVelocity(1, 0)
644
+
645
+ // Disable contacts between the two joint bodies
646
+ joint.raw().setContactsEnabled(false)
647
+ }, [])
648
+
649
+ return ...
650
+ }
651
+ ```
499
652
 
500
- - WIP
501
653
 
502
654
  ### Joints Example
503
655
  <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>