@react-three/rapier 0.7.4 → 0.7.5

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.
@@ -1,9 +1,10 @@
1
+ import { Collider } from "@dimforge/rapier3d-compat";
1
2
  import React, { ReactNode } from "react";
2
3
  import { UseColliderOptions, CuboidArgs, RoundCuboidArgs, BallArgs, CapsuleArgs, HeightfieldArgs, TrimeshArgs, ConeArgs, CylinderArgs, ConvexHullArgs } from "./types";
3
4
  export interface ColliderProps extends UseColliderOptions<any> {
4
5
  children?: ReactNode;
5
6
  }
6
- export declare const AnyCollider: React.MemoExoticComponent<(props: ColliderProps) => JSX.Element>;
7
+ export declare const AnyCollider: React.MemoExoticComponent<React.ForwardRefExoticComponent<ColliderProps & React.RefAttributes<Collider[]>>>;
7
8
  declare type UseColliderOptionsRequiredArgs<T extends unknown[]> = Omit<UseColliderOptions<T>, "args"> & {
8
9
  args: T;
9
10
  children?: ReactNode;
@@ -17,13 +18,40 @@ export declare type TrimeshColliderProps = UseColliderOptionsRequiredArgs<Trimes
17
18
  export declare type ConeColliderProps = UseColliderOptionsRequiredArgs<ConeArgs>;
18
19
  export declare type CylinderColliderProps = UseColliderOptionsRequiredArgs<CylinderArgs>;
19
20
  export declare type ConvexHullColliderProps = UseColliderOptionsRequiredArgs<ConvexHullArgs>;
20
- export declare const CuboidCollider: (props: CuboidColliderProps) => JSX.Element;
21
- export declare const RoundCuboidCollider: (props: RoundCuboidColliderProps) => JSX.Element;
22
- export declare const BallCollider: (props: BallColliderProps) => JSX.Element;
23
- export declare const CapsuleCollider: (props: CapsuleColliderProps) => JSX.Element;
24
- export declare const HeightfieldCollider: (props: HeightfieldColliderProps) => JSX.Element;
25
- export declare const TrimeshCollider: (props: TrimeshColliderProps) => JSX.Element;
26
- export declare const ConeCollider: (props: ConeColliderProps) => JSX.Element;
27
- export declare const CylinderCollider: (props: CylinderColliderProps) => JSX.Element;
28
- export declare const ConvexHullCollider: (props: ConvexHullColliderProps) => JSX.Element;
21
+ export declare const CuboidCollider: React.ForwardRefExoticComponent<Omit<UseColliderOptions<CuboidArgs>, "args"> & {
22
+ args: CuboidArgs;
23
+ children?: ReactNode;
24
+ } & React.RefAttributes<Collider[]>>;
25
+ export declare const RoundCuboidCollider: React.ForwardRefExoticComponent<Omit<UseColliderOptions<RoundCuboidArgs>, "args"> & {
26
+ args: RoundCuboidArgs;
27
+ children?: ReactNode;
28
+ } & React.RefAttributes<Collider[]>>;
29
+ export declare const BallCollider: React.ForwardRefExoticComponent<Omit<UseColliderOptions<BallArgs>, "args"> & {
30
+ args: BallArgs;
31
+ children?: ReactNode;
32
+ } & React.RefAttributes<Collider[]>>;
33
+ export declare const CapsuleCollider: React.ForwardRefExoticComponent<Omit<UseColliderOptions<CapsuleArgs>, "args"> & {
34
+ args: CapsuleArgs;
35
+ children?: ReactNode;
36
+ } & React.RefAttributes<Collider[]>>;
37
+ export declare const HeightfieldCollider: React.ForwardRefExoticComponent<Omit<UseColliderOptions<HeightfieldArgs>, "args"> & {
38
+ args: HeightfieldArgs;
39
+ children?: ReactNode;
40
+ } & React.RefAttributes<Collider[]>>;
41
+ export declare const TrimeshCollider: React.ForwardRefExoticComponent<Omit<UseColliderOptions<TrimeshArgs>, "args"> & {
42
+ args: TrimeshArgs;
43
+ children?: ReactNode;
44
+ } & React.RefAttributes<Collider[]>>;
45
+ export declare const ConeCollider: React.ForwardRefExoticComponent<Omit<UseColliderOptions<ConeArgs>, "args"> & {
46
+ args: ConeArgs;
47
+ children?: ReactNode;
48
+ } & React.RefAttributes<Collider[]>>;
49
+ export declare const CylinderCollider: React.ForwardRefExoticComponent<Omit<UseColliderOptions<CylinderArgs>, "args"> & {
50
+ args: CylinderArgs;
51
+ children?: ReactNode;
52
+ } & React.RefAttributes<Collider[]>>;
53
+ export declare const ConvexHullCollider: React.ForwardRefExoticComponent<Omit<UseColliderOptions<ConvexHullArgs>, "args"> & {
54
+ args: ConvexHullArgs;
55
+ children?: ReactNode;
56
+ } & React.RefAttributes<Collider[]>>;
29
57
  export {};
@@ -22,27 +22,27 @@ export interface RigidBodyApi {
22
22
  /**
23
23
  * Applies an impulse at the center-of-mass of this rigid-body.
24
24
  */
25
- applyImpulse(impulseVector: Vector3Object): void;
25
+ applyImpulse(impulseVector: Vector3Object, wakeUp: boolean): void;
26
26
  /**
27
27
  * Applies an impulsive torque at the center-of-mass of this rigid-body.
28
28
  */
29
- applyTorqueImpulse(torqueVector: Vector3Object): void;
29
+ applyTorqueImpulse(torqueVector: Vector3Object, wakeUp: boolean): void;
30
30
  /**
31
31
  * Applies an impulse at the given world-space point of this rigid-body.
32
32
  */
33
- applyImpulseAtPoint(impulseVector: Vector3Object, impulsePoint: Vector3Object): void;
33
+ applyImpulseAtPoint(impulseVector: Vector3Object, impulsePoint: Vector3Object, wakeUp: boolean): void;
34
34
  /**
35
35
  * Adds a force at the center-of-mass of this rigid-body.
36
36
  */
37
- addForce(force: Vector3Object): void;
37
+ addForce(force: Vector3Object, wakeUp: boolean): void;
38
38
  /**
39
39
  * Adds a force at the given world-space point of this rigid-body.
40
40
  */
41
- addForceAtPoint(force: Vector3Object, point: Vector3Object): void;
41
+ addForceAtPoint(force: Vector3Object, point: Vector3Object, wakeUp: boolean): void;
42
42
  /**
43
43
  * Adds a torque at the center-of-mass of this rigid-body.
44
44
  */
45
- addTorque(torque: Vector3Object): void;
45
+ addTorque(torque: Vector3Object, wakeUp: boolean): void;
46
46
  /**
47
47
  * The world-space translation of this rigid-body.
48
48
  */
@@ -50,7 +50,7 @@ export interface RigidBodyApi {
50
50
  /**
51
51
  * Sets the translation of this rigid-body.
52
52
  */
53
- setTranslation(translation: Vector3Object): void;
53
+ setTranslation(translation: Vector3Object, wakeUp: boolean): void;
54
54
  /**
55
55
  * The world-space orientation of this rigid-body.
56
56
  */
@@ -58,7 +58,7 @@ export interface RigidBodyApi {
58
58
  /**
59
59
  * Sets the rotation quaternion of this rigid-body.
60
60
  */
61
- setRotation(rotation: Quaternion): void;
61
+ setRotation(rotation: Quaternion, wakeUp: boolean): void;
62
62
  /**
63
63
  * The linear velocity of this rigid-body.
64
64
  */
@@ -66,7 +66,7 @@ export interface RigidBodyApi {
66
66
  /**
67
67
  * Sets the linear velocity of this rigid-body.
68
68
  */
69
- setLinvel(velocity: Vector3Object): void;
69
+ setLinvel(velocity: Vector3Object, wakeUp: boolean): void;
70
70
  /**
71
71
  * The angular velocity of this rigid-body.
72
72
  */
@@ -74,7 +74,7 @@ export interface RigidBodyApi {
74
74
  /**
75
75
  * Sets the angular velocity of this rigid-body.
76
76
  */
77
- setAngvel(velocity: Vector3Object): void;
77
+ setAngvel(velocity: Vector3Object, wakeUp: boolean): void;
78
78
  /**
79
79
  * The linear damping of this rigid-body.
80
80
  */
@@ -112,27 +112,27 @@ export interface RigidBodyApi {
112
112
  /**
113
113
  * Resets to zero the user forces (but not torques) applied to this rigid-body.
114
114
  */
115
- resetForces(): void;
115
+ resetForces(wakeUp: boolean): void;
116
116
  /**
117
117
  * Resets to zero the user torques applied to this rigid-body.
118
118
  */
119
- resetTorques(): void;
119
+ resetTorques(wakeUp: boolean): void;
120
120
  /**
121
121
  * Locks or unlocks the ability of this rigid-body to rotate.
122
122
  */
123
- lockRotations(locked: boolean): void;
123
+ lockRotations(locked: boolean, wakeUp: boolean): void;
124
124
  /**
125
125
  * Locks or unlocks the ability of this rigid-body to translate.
126
126
  */
127
- lockTranslations(locked: boolean): void;
127
+ lockTranslations(locked: boolean, wakeUp: boolean): void;
128
128
  /**
129
129
  * Locks or unlocks the ability of this rigid-body to rotate along individual coordinate axes.
130
130
  */
131
- setEnabledRotations(x: boolean, y: boolean, z: boolean): void;
131
+ setEnabledRotations(x: boolean, y: boolean, z: boolean, wakeUp: boolean): void;
132
132
  /**
133
133
  * Locks or unlocks the ability of this rigid-body to translate along individual coordinate axes.
134
134
  */
135
- setEnabledTranslations(x: boolean, y: boolean, z: boolean): void;
135
+ setEnabledTranslations(x: boolean, y: boolean, z: boolean, wakeUp: boolean): void;
136
136
  }
137
137
  export declare const createRigidBodyApi: (ref: RefGetter<RigidBody>) => RigidBodyApi;
138
138
  export interface InstancedRigidBodyApi {
@@ -155,9 +155,9 @@ export interface WorldApi {
155
155
  createRigidBody(desc: RigidBodyDesc): RigidBody;
156
156
  createCollider(desc: ColliderDesc, parent?: RigidBody): Collider;
157
157
  removeRigidBody(rigidBody: RigidBody): void;
158
- removeCollider(collider: Collider): void;
159
- createImpulseJoint(params: JointData, rigidBodyA: RigidBody, rigidBodyB: RigidBody): ImpulseJoint;
160
- removeImpulseJoint(joint: ImpulseJoint): void;
158
+ removeCollider(collider: Collider, wakeUp: boolean): void;
159
+ createImpulseJoint(params: JointData, rigidBodyA: RigidBody, rigidBodyB: RigidBody, wakeUp: boolean): ImpulseJoint;
160
+ removeImpulseJoint(joint: ImpulseJoint, wakeUp: boolean): void;
161
161
  forEachCollider(callback: (collider: Collider) => void): void;
162
162
  setGravity(gravity: Vector3): void;
163
163
  }
@@ -6,6 +6,7 @@ import { Object3DProps } from "@react-three/fiber";
6
6
  import { Object3D } from "three";
7
7
  export { CoefficientCombineRule as CoefficientCombineRule } from "@dimforge/rapier3d-compat";
8
8
  export { RapierRigidBody, RapierCollider };
9
+ import { Rotation, Vector } from "@dimforge/rapier3d-compat/math";
9
10
  export declare type RefGetter<T> = MutableRefObject<() => T | undefined>;
10
11
  export declare type RigidBodyAutoCollider = "ball" | "cuboid" | "hull" | "trimesh" | false;
11
12
  export interface UseRigidBodyAPI {
@@ -81,18 +82,6 @@ export interface UseColliderOptions<ColliderArgs extends Array<unknown>> {
81
82
  * Arguments to pass to the collider
82
83
  */
83
84
  args?: ColliderArgs;
84
- /**
85
- * The mass of this collider.
86
- * The mass and density is automatically calculated based on the shape of the collider.
87
- * Generally, it's not recommended to adjust the mass properties as it could lead to
88
- * unexpected behaviors.
89
- * More info https://rapier.rs/docs/user_guides/javascript/colliders#mass-properties
90
- */
91
- mass?: number;
92
- /**
93
- * The center of mass of this rigid body
94
- */
95
- centerOfMass?: Vector3Array;
96
85
  /**
97
86
  * Principal angular inertia of this rigid body
98
87
  */
@@ -157,8 +146,30 @@ export interface UseColliderOptions<ColliderArgs extends Array<unknown>> {
157
146
  solverGroups?: InteractionGroups;
158
147
  /**
159
148
  * Sets the uniform density of this collider.
149
+ * If this is set, other mass-properties like the angular inertia tensor are computed
150
+ * automatically from the collider's shape.
151
+ * Cannot be used at the same time as the mass or massProperties values.
152
+ * More info https://rapier.rs/docs/user_guides/javascript/colliders#mass-properties
160
153
  */
161
154
  density?: number;
155
+ /**
156
+ * The mass of this collider.
157
+ * Generally, it's not recommended to adjust the mass properties as it could lead to
158
+ * unexpected behaviors.
159
+ * Cannot be used at the same time as the density or massProperties values.
160
+ * More info https://rapier.rs/docs/user_guides/javascript/colliders#mass-properties
161
+ */
162
+ mass?: number;
163
+ /**
164
+ * The mass properties of this rigid body.
165
+ * Cannot be used at the same time as the density or mass values.
166
+ */
167
+ massProperties?: {
168
+ mass: number;
169
+ centerOfMass: Vector;
170
+ principalAngularInertia: Vector;
171
+ angularInertiaLocalFrame: Rotation;
172
+ };
162
173
  /**
163
174
  * Sets whether or not this collider is a sensor.
164
175
  */
@@ -84,24 +84,24 @@ const createRigidBodyApi = ref => {
84
84
 
85
85
  mass: () => ref.current().mass(),
86
86
 
87
- applyImpulse(impulseVector) {
88
- ref.current().applyImpulse(impulseVector, true);
87
+ applyImpulse(impulseVector, wakeUp = true) {
88
+ ref.current().applyImpulse(impulseVector, wakeUp);
89
89
  },
90
90
 
91
- applyTorqueImpulse(torqueVector) {
92
- ref.current().applyTorqueImpulse(torqueVector, true);
91
+ applyTorqueImpulse(torqueVector, wakeUp = true) {
92
+ ref.current().applyTorqueImpulse(torqueVector, wakeUp);
93
93
  },
94
94
 
95
- applyImpulseAtPoint: (impulseVector, impulsePoint) => ref.current().applyImpulseAtPoint(impulseVector, impulsePoint, true),
96
- addForce: force => ref.current().addForce(force, true),
97
- addForceAtPoint: (force, point) => ref.current().addForceAtPoint(force, point, true),
98
- addTorque: torque => ref.current().addTorque(torque, true),
95
+ applyImpulseAtPoint: (impulseVector, impulsePoint, wakeUp = true) => ref.current().applyImpulseAtPoint(impulseVector, impulsePoint, wakeUp),
96
+ addForce: (force, wakeUp = true) => ref.current().addForce(force, wakeUp),
97
+ addForceAtPoint: (force, point, wakeUp = true) => ref.current().addForceAtPoint(force, point, wakeUp),
98
+ addTorque: (torque, wakeUp = true) => ref.current().addTorque(torque, wakeUp),
99
99
 
100
100
  translation() {
101
101
  return rapierVector3ToVector3(ref.current().translation());
102
102
  },
103
103
 
104
- setTranslation: translation => ref.current().setTranslation(translation, true),
104
+ setTranslation: (translation, wakeUp = true) => ref.current().setTranslation(translation, wakeUp),
105
105
 
106
106
  rotation() {
107
107
  const {
@@ -113,8 +113,8 @@ const createRigidBodyApi = ref => {
113
113
  return new three.Quaternion(x, y, z, w);
114
114
  },
115
115
 
116
- setRotation: rotation => {
117
- ref.current().setRotation(rotation, true);
116
+ setRotation: (rotation, wakeUp = true) => {
117
+ ref.current().setRotation(rotation, wakeUp);
118
118
  },
119
119
 
120
120
  linvel() {
@@ -126,7 +126,7 @@ const createRigidBodyApi = ref => {
126
126
  return new three.Vector3(x, y, z);
127
127
  },
128
128
 
129
- setLinvel: velocity => ref.current().setLinvel(velocity, true),
129
+ setLinvel: (velocity, wakeUp = true) => ref.current().setLinvel(velocity, wakeUp),
130
130
 
131
131
  angvel() {
132
132
  const {
@@ -137,7 +137,7 @@ const createRigidBodyApi = ref => {
137
137
  return new three.Vector3(x, y, z);
138
138
  },
139
139
 
140
- setAngvel: velocity => ref.current().setAngvel(velocity, true),
140
+ setAngvel: (velocity, wakeUp = true) => ref.current().setAngvel(velocity, wakeUp),
141
141
 
142
142
  linearDamping() {
143
143
  return ref.current().linearDamping();
@@ -154,12 +154,12 @@ const createRigidBodyApi = ref => {
154
154
  ref.current().setNextKinematicRotation(rotation);
155
155
  },
156
156
  setNextKinematicTranslation: translation => ref.current().setNextKinematicTranslation(translation),
157
- resetForces: () => ref.current().resetForces(true),
158
- resetTorques: () => ref.current().resetTorques(true),
159
- lockRotations: locked => ref.current().lockRotations(locked, true),
160
- lockTranslations: locked => ref.current().lockTranslations(locked, true),
161
- setEnabledRotations: (x, y, z) => ref.current().setEnabledRotations(x, y, z, true),
162
- setEnabledTranslations: (x, y, z) => ref.current().setEnabledTranslations(x, y, z, true)
157
+ resetForces: (wakeUp = true) => ref.current().resetForces(wakeUp),
158
+ resetTorques: (wakeUp = true) => ref.current().resetTorques(wakeUp),
159
+ lockRotations: (locked, wakeUp = true) => ref.current().lockRotations(locked, wakeUp),
160
+ lockTranslations: (locked, wakeUp = true) => ref.current().lockTranslations(locked, wakeUp),
161
+ setEnabledRotations: (x, y, z, wakeUp = true) => ref.current().setEnabledRotations(x, y, z, wakeUp),
162
+ setEnabledTranslations: (x, y, z, wakeUp = true) => ref.current().setEnabledTranslations(x, y, z, wakeUp)
163
163
  };
164
164
  };
165
165
  const createInstancedRigidBodiesApi = bodiesGetter => ({
@@ -182,9 +182,9 @@ const createWorldApi = ref => {
182
182
  createRigidBody: desc => ref.current().createRigidBody(desc),
183
183
  createCollider: (desc, rigidBody) => ref.current().createCollider(desc, rigidBody),
184
184
  removeRigidBody: rigidBody => ref.current().removeRigidBody(rigidBody),
185
- removeCollider: collider => ref.current().removeCollider(collider, true),
186
- createImpulseJoint: (params, rigidBodyA, rigidBodyB) => ref.current().createImpulseJoint(params, rigidBodyA, rigidBodyB, true),
187
- removeImpulseJoint: joint => ref.current().removeImpulseJoint(joint, true),
185
+ removeCollider: (collider, wakeUp = true) => ref.current().removeCollider(collider, wakeUp),
186
+ createImpulseJoint: (params, rigidBodyA, rigidBodyB, wakeUp = true) => ref.current().createImpulseJoint(params, rigidBodyA, rigidBodyB, wakeUp),
187
+ removeImpulseJoint: (joint, wakeUp = true) => ref.current().removeImpulseJoint(joint, wakeUp),
188
188
  forEachCollider: callback => ref.current().forEachCollider(callback),
189
189
  setGravity: ({
190
190
  x,
@@ -746,6 +746,32 @@ const createColliderFromOptions = (options, world, scale, rigidBody) => {
746
746
  const desc = rapier3dCompat.ColliderDesc[options.shape](...scaledArgs);
747
747
  return world.createCollider(desc, rigidBody);
748
748
  };
749
+ const massPropertiesConflictError = "Please pick ONLY ONE of the `density`, `mass` and `massProperties` options.";
750
+
751
+ const setColliderMassOptions = (collider, options) => {
752
+ if (options.density !== undefined) {
753
+ if (options.mass !== undefined || options.massProperties !== undefined) {
754
+ throw new Error(massPropertiesConflictError);
755
+ }
756
+
757
+ collider.setDensity(options.density);
758
+ return;
759
+ }
760
+
761
+ if (options.mass !== undefined) {
762
+ if (options.massProperties !== undefined) {
763
+ throw new Error(massPropertiesConflictError);
764
+ }
765
+
766
+ collider.setMass(options.mass);
767
+ return;
768
+ }
769
+
770
+ if (options.massProperties !== undefined) {
771
+ collider.setMassProperties(options.massProperties.mass, options.massProperties.centerOfMass, options.massProperties.principalAngularInertia, options.massProperties.angularInertiaLocalFrame);
772
+ }
773
+ };
774
+
749
775
  const mutableColliderOptions = {
750
776
  sensor: (collider, value) => {
751
777
  collider.setSensor(value);
@@ -759,14 +785,14 @@ const mutableColliderOptions = {
759
785
  friction: (collider, value) => {
760
786
  collider.setFriction(value);
761
787
  },
788
+ frictionCombineRule: (collider, value) => {
789
+ collider.setFrictionCombineRule(value);
790
+ },
762
791
  restitution: (collider, value) => {
763
792
  collider.setRestitution(value);
764
793
  },
765
- density: (collider, value) => {
766
- collider.setDensity(value);
767
- },
768
- mass: (collider, value) => {
769
- collider.setMass(value);
794
+ restitutionCombineRule: (collider, value) => {
795
+ collider.setRestitutionCombineRule(value);
770
796
  }
771
797
  };
772
798
  const mutableColliderOptionKeys = Object.keys(mutableColliderOptions);
@@ -798,9 +824,14 @@ const setColliderOptions = (collider, options, states) => {
798
824
 
799
825
  mutableColliderOptionKeys.forEach(key => {
800
826
  if (key in options) {
801
- mutableColliderOptions[key](collider, options[key]);
827
+ const option = options[key];
828
+ mutableColliderOptions[key](collider, // @ts-ignore Option does not want to fit into the function, but it will
829
+ option, options);
802
830
  }
803
- });
831
+ }); // handle mass separately, because the assignments
832
+ // are exclusive.
833
+
834
+ setColliderMassOptions(collider, options);
804
835
  }
805
836
  };
806
837
  const useUpdateColliderOptions = (collidersRef, props, states) => {
@@ -1109,7 +1140,7 @@ const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
1109
1140
  };
1110
1141
 
1111
1142
  // Colliders
1112
- const AnyCollider = /*#__PURE__*/React.memo(props => {
1143
+ const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React__default["default"].forwardRef((props, forwardedRef) => {
1113
1144
  const {
1114
1145
  children,
1115
1146
  position,
@@ -1124,7 +1155,15 @@ const AnyCollider = /*#__PURE__*/React.memo(props => {
1124
1155
  } = useRapier();
1125
1156
  const rigidBodyContext = useRigidBodyContext();
1126
1157
  const ref = React.useRef(null);
1127
- const collidersRef = React.useRef([]);
1158
+ const collidersRef = React.useMemo(() => {
1159
+ if (forwardedRef !== null) {
1160
+ return forwardedRef;
1161
+ }
1162
+
1163
+ const result = /*#__PURE__*/React__default["default"].createRef();
1164
+ result.current = [];
1165
+ return result;
1166
+ }, []);
1128
1167
  React.useEffect(() => {
1129
1168
  const object = ref.current;
1130
1169
  const worldScale = object.getWorldScale(new three.Vector3());
@@ -1169,52 +1208,61 @@ const AnyCollider = /*#__PURE__*/React.memo(props => {
1169
1208
  scale: scale,
1170
1209
  ref: ref
1171
1210
  }, children);
1172
- });
1173
- const CuboidCollider = props => {
1211
+ }));
1212
+ const CuboidCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1174
1213
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1175
- shape: "cuboid"
1214
+ shape: "cuboid",
1215
+ ref: ref
1176
1216
  }));
1177
- };
1178
- const RoundCuboidCollider = props => {
1217
+ });
1218
+ const RoundCuboidCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1179
1219
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1180
- shape: "roundCuboid"
1220
+ shape: "roundCuboid",
1221
+ ref: ref
1181
1222
  }));
1182
- };
1183
- const BallCollider = props => {
1223
+ });
1224
+ const BallCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1184
1225
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1185
- shape: "ball"
1226
+ shape: "ball",
1227
+ ref: ref
1186
1228
  }));
1187
- };
1188
- const CapsuleCollider = props => {
1229
+ });
1230
+ const CapsuleCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1189
1231
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1190
- shape: "capsule"
1232
+ shape: "capsule",
1233
+ ref: ref
1191
1234
  }));
1192
- };
1193
- const HeightfieldCollider = props => {
1235
+ });
1236
+ const HeightfieldCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1194
1237
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1195
- shape: "heightfield"
1238
+ shape: "heightfield",
1239
+ ref: ref
1196
1240
  }));
1197
- };
1198
- const TrimeshCollider = props => {
1241
+ });
1242
+ const TrimeshCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1199
1243
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1200
- shape: "trimesh"
1244
+ shape: "trimesh",
1245
+ ref: ref
1201
1246
  }));
1202
- };
1203
- const ConeCollider = props => {
1247
+ });
1248
+ const ConeCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1204
1249
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1205
- shape: "cone"
1250
+ shape: "cone",
1251
+ ref: ref
1206
1252
  }));
1207
- };
1208
- const CylinderCollider = props => {
1253
+ });
1254
+ const CylinderCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1209
1255
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1210
- shape: "cylinder"
1256
+ shape: "cylinder",
1257
+ ref: ref
1211
1258
  }));
1212
- };
1213
- const ConvexHullCollider = props => {
1259
+ });
1260
+ const ConvexHullCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1214
1261
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1215
- shape: "convexHull"
1262
+ shape: "convexHull",
1263
+ ref: ref
1216
1264
  }));
1217
- };
1265
+ });
1218
1266
 
1219
1267
  const _excluded$1 = ["children", "type", "position", "rotation", "scale", "quaternion"];
1220
1268
  const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
@@ -1290,7 +1338,7 @@ const geometryFromCollider = collider => {
1290
1338
  y,
1291
1339
  z
1292
1340
  } = collider.shape.halfExtents;
1293
- return new three.BoxBufferGeometry(x * 2 + 0.01, y * 2 + 0.01, z * 2 + 0.01);
1341
+ return new three.BoxGeometry(x * 2 + 0.01, y * 2 + 0.01, z * 2 + 0.01);
1294
1342
  }
1295
1343
 
1296
1344
  case rapier3dCompat.ShapeType.RoundCuboid:
@@ -1307,7 +1355,7 @@ const geometryFromCollider = collider => {
1307
1355
  case rapier3dCompat.ShapeType.Ball:
1308
1356
  {
1309
1357
  const r = collider.shape.radius;
1310
- return new three.SphereBufferGeometry(r + +0.01, 8, 8);
1358
+ return new three.SphereGeometry(r + +0.01, 8, 8);
1311
1359
  }
1312
1360
 
1313
1361
  case rapier3dCompat.ShapeType.TriMesh:
@@ -1339,7 +1387,7 @@ const geometryFromCollider = collider => {
1339
1387
  {
1340
1388
  const r = collider.shape.radius;
1341
1389
  const h = collider.shape.halfHeight;
1342
- const g = new three.CylinderBufferGeometry(r, r, h * 2);
1390
+ const g = new three.CylinderGeometry(r, r, h * 2);
1343
1391
  return g;
1344
1392
  }
1345
1393
 
@@ -1347,7 +1395,7 @@ const geometryFromCollider = collider => {
1347
1395
  {
1348
1396
  const r = collider.shape.radius;
1349
1397
  const h = collider.shape.halfHeight;
1350
- const g = new three.CapsuleBufferGeometry(r, h * 2, 4, 8);
1398
+ const g = new three.CapsuleGeometry(r, h * 2, 4, 8);
1351
1399
  return g;
1352
1400
  }
1353
1401
 
@@ -1355,7 +1403,7 @@ const geometryFromCollider = collider => {
1355
1403
  {
1356
1404
  const r = collider.shape.radius;
1357
1405
  const h = collider.shape.halfHeight;
1358
- const g = new three.ConeBufferGeometry(r, h * 2, 16);
1406
+ const g = new three.ConeGeometry(r, h * 2, 16);
1359
1407
  return g;
1360
1408
  }
1361
1409
 
@@ -1375,7 +1423,7 @@ const geometryFromCollider = collider => {
1375
1423
  }
1376
1424
  }
1377
1425
 
1378
- return new three.BoxBufferGeometry(1, 1, 1);
1426
+ return new three.BoxGeometry(1, 1, 1);
1379
1427
  };
1380
1428
 
1381
1429
  const DebugShape = /*#__PURE__*/React.memo(({
@@ -84,24 +84,24 @@ const createRigidBodyApi = ref => {
84
84
 
85
85
  mass: () => ref.current().mass(),
86
86
 
87
- applyImpulse(impulseVector) {
88
- ref.current().applyImpulse(impulseVector, true);
87
+ applyImpulse(impulseVector, wakeUp = true) {
88
+ ref.current().applyImpulse(impulseVector, wakeUp);
89
89
  },
90
90
 
91
- applyTorqueImpulse(torqueVector) {
92
- ref.current().applyTorqueImpulse(torqueVector, true);
91
+ applyTorqueImpulse(torqueVector, wakeUp = true) {
92
+ ref.current().applyTorqueImpulse(torqueVector, wakeUp);
93
93
  },
94
94
 
95
- applyImpulseAtPoint: (impulseVector, impulsePoint) => ref.current().applyImpulseAtPoint(impulseVector, impulsePoint, true),
96
- addForce: force => ref.current().addForce(force, true),
97
- addForceAtPoint: (force, point) => ref.current().addForceAtPoint(force, point, true),
98
- addTorque: torque => ref.current().addTorque(torque, true),
95
+ applyImpulseAtPoint: (impulseVector, impulsePoint, wakeUp = true) => ref.current().applyImpulseAtPoint(impulseVector, impulsePoint, wakeUp),
96
+ addForce: (force, wakeUp = true) => ref.current().addForce(force, wakeUp),
97
+ addForceAtPoint: (force, point, wakeUp = true) => ref.current().addForceAtPoint(force, point, wakeUp),
98
+ addTorque: (torque, wakeUp = true) => ref.current().addTorque(torque, wakeUp),
99
99
 
100
100
  translation() {
101
101
  return rapierVector3ToVector3(ref.current().translation());
102
102
  },
103
103
 
104
- setTranslation: translation => ref.current().setTranslation(translation, true),
104
+ setTranslation: (translation, wakeUp = true) => ref.current().setTranslation(translation, wakeUp),
105
105
 
106
106
  rotation() {
107
107
  const {
@@ -113,8 +113,8 @@ const createRigidBodyApi = ref => {
113
113
  return new three.Quaternion(x, y, z, w);
114
114
  },
115
115
 
116
- setRotation: rotation => {
117
- ref.current().setRotation(rotation, true);
116
+ setRotation: (rotation, wakeUp = true) => {
117
+ ref.current().setRotation(rotation, wakeUp);
118
118
  },
119
119
 
120
120
  linvel() {
@@ -126,7 +126,7 @@ const createRigidBodyApi = ref => {
126
126
  return new three.Vector3(x, y, z);
127
127
  },
128
128
 
129
- setLinvel: velocity => ref.current().setLinvel(velocity, true),
129
+ setLinvel: (velocity, wakeUp = true) => ref.current().setLinvel(velocity, wakeUp),
130
130
 
131
131
  angvel() {
132
132
  const {
@@ -137,7 +137,7 @@ const createRigidBodyApi = ref => {
137
137
  return new three.Vector3(x, y, z);
138
138
  },
139
139
 
140
- setAngvel: velocity => ref.current().setAngvel(velocity, true),
140
+ setAngvel: (velocity, wakeUp = true) => ref.current().setAngvel(velocity, wakeUp),
141
141
 
142
142
  linearDamping() {
143
143
  return ref.current().linearDamping();
@@ -154,12 +154,12 @@ const createRigidBodyApi = ref => {
154
154
  ref.current().setNextKinematicRotation(rotation);
155
155
  },
156
156
  setNextKinematicTranslation: translation => ref.current().setNextKinematicTranslation(translation),
157
- resetForces: () => ref.current().resetForces(true),
158
- resetTorques: () => ref.current().resetTorques(true),
159
- lockRotations: locked => ref.current().lockRotations(locked, true),
160
- lockTranslations: locked => ref.current().lockTranslations(locked, true),
161
- setEnabledRotations: (x, y, z) => ref.current().setEnabledRotations(x, y, z, true),
162
- setEnabledTranslations: (x, y, z) => ref.current().setEnabledTranslations(x, y, z, true)
157
+ resetForces: (wakeUp = true) => ref.current().resetForces(wakeUp),
158
+ resetTorques: (wakeUp = true) => ref.current().resetTorques(wakeUp),
159
+ lockRotations: (locked, wakeUp = true) => ref.current().lockRotations(locked, wakeUp),
160
+ lockTranslations: (locked, wakeUp = true) => ref.current().lockTranslations(locked, wakeUp),
161
+ setEnabledRotations: (x, y, z, wakeUp = true) => ref.current().setEnabledRotations(x, y, z, wakeUp),
162
+ setEnabledTranslations: (x, y, z, wakeUp = true) => ref.current().setEnabledTranslations(x, y, z, wakeUp)
163
163
  };
164
164
  };
165
165
  const createInstancedRigidBodiesApi = bodiesGetter => ({
@@ -182,9 +182,9 @@ const createWorldApi = ref => {
182
182
  createRigidBody: desc => ref.current().createRigidBody(desc),
183
183
  createCollider: (desc, rigidBody) => ref.current().createCollider(desc, rigidBody),
184
184
  removeRigidBody: rigidBody => ref.current().removeRigidBody(rigidBody),
185
- removeCollider: collider => ref.current().removeCollider(collider, true),
186
- createImpulseJoint: (params, rigidBodyA, rigidBodyB) => ref.current().createImpulseJoint(params, rigidBodyA, rigidBodyB, true),
187
- removeImpulseJoint: joint => ref.current().removeImpulseJoint(joint, true),
185
+ removeCollider: (collider, wakeUp = true) => ref.current().removeCollider(collider, wakeUp),
186
+ createImpulseJoint: (params, rigidBodyA, rigidBodyB, wakeUp = true) => ref.current().createImpulseJoint(params, rigidBodyA, rigidBodyB, wakeUp),
187
+ removeImpulseJoint: (joint, wakeUp = true) => ref.current().removeImpulseJoint(joint, wakeUp),
188
188
  forEachCollider: callback => ref.current().forEachCollider(callback),
189
189
  setGravity: ({
190
190
  x,
@@ -746,6 +746,32 @@ const createColliderFromOptions = (options, world, scale, rigidBody) => {
746
746
  const desc = rapier3dCompat.ColliderDesc[options.shape](...scaledArgs);
747
747
  return world.createCollider(desc, rigidBody);
748
748
  };
749
+ const massPropertiesConflictError = "Please pick ONLY ONE of the `density`, `mass` and `massProperties` options.";
750
+
751
+ const setColliderMassOptions = (collider, options) => {
752
+ if (options.density !== undefined) {
753
+ if (options.mass !== undefined || options.massProperties !== undefined) {
754
+ throw new Error(massPropertiesConflictError);
755
+ }
756
+
757
+ collider.setDensity(options.density);
758
+ return;
759
+ }
760
+
761
+ if (options.mass !== undefined) {
762
+ if (options.massProperties !== undefined) {
763
+ throw new Error(massPropertiesConflictError);
764
+ }
765
+
766
+ collider.setMass(options.mass);
767
+ return;
768
+ }
769
+
770
+ if (options.massProperties !== undefined) {
771
+ collider.setMassProperties(options.massProperties.mass, options.massProperties.centerOfMass, options.massProperties.principalAngularInertia, options.massProperties.angularInertiaLocalFrame);
772
+ }
773
+ };
774
+
749
775
  const mutableColliderOptions = {
750
776
  sensor: (collider, value) => {
751
777
  collider.setSensor(value);
@@ -759,14 +785,14 @@ const mutableColliderOptions = {
759
785
  friction: (collider, value) => {
760
786
  collider.setFriction(value);
761
787
  },
788
+ frictionCombineRule: (collider, value) => {
789
+ collider.setFrictionCombineRule(value);
790
+ },
762
791
  restitution: (collider, value) => {
763
792
  collider.setRestitution(value);
764
793
  },
765
- density: (collider, value) => {
766
- collider.setDensity(value);
767
- },
768
- mass: (collider, value) => {
769
- collider.setMass(value);
794
+ restitutionCombineRule: (collider, value) => {
795
+ collider.setRestitutionCombineRule(value);
770
796
  }
771
797
  };
772
798
  const mutableColliderOptionKeys = Object.keys(mutableColliderOptions);
@@ -798,9 +824,14 @@ const setColliderOptions = (collider, options, states) => {
798
824
 
799
825
  mutableColliderOptionKeys.forEach(key => {
800
826
  if (key in options) {
801
- mutableColliderOptions[key](collider, options[key]);
827
+ const option = options[key];
828
+ mutableColliderOptions[key](collider, // @ts-ignore Option does not want to fit into the function, but it will
829
+ option, options);
802
830
  }
803
- });
831
+ }); // handle mass separately, because the assignments
832
+ // are exclusive.
833
+
834
+ setColliderMassOptions(collider, options);
804
835
  }
805
836
  };
806
837
  const useUpdateColliderOptions = (collidersRef, props, states) => {
@@ -1109,7 +1140,7 @@ const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
1109
1140
  };
1110
1141
 
1111
1142
  // Colliders
1112
- const AnyCollider = /*#__PURE__*/React.memo(props => {
1143
+ const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React__default["default"].forwardRef((props, forwardedRef) => {
1113
1144
  const {
1114
1145
  children,
1115
1146
  position,
@@ -1124,7 +1155,15 @@ const AnyCollider = /*#__PURE__*/React.memo(props => {
1124
1155
  } = useRapier();
1125
1156
  const rigidBodyContext = useRigidBodyContext();
1126
1157
  const ref = React.useRef(null);
1127
- const collidersRef = React.useRef([]);
1158
+ const collidersRef = React.useMemo(() => {
1159
+ if (forwardedRef !== null) {
1160
+ return forwardedRef;
1161
+ }
1162
+
1163
+ const result = /*#__PURE__*/React__default["default"].createRef();
1164
+ result.current = [];
1165
+ return result;
1166
+ }, []);
1128
1167
  React.useEffect(() => {
1129
1168
  const object = ref.current;
1130
1169
  const worldScale = object.getWorldScale(new three.Vector3());
@@ -1169,52 +1208,61 @@ const AnyCollider = /*#__PURE__*/React.memo(props => {
1169
1208
  scale: scale,
1170
1209
  ref: ref
1171
1210
  }, children);
1172
- });
1173
- const CuboidCollider = props => {
1211
+ }));
1212
+ const CuboidCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1174
1213
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1175
- shape: "cuboid"
1214
+ shape: "cuboid",
1215
+ ref: ref
1176
1216
  }));
1177
- };
1178
- const RoundCuboidCollider = props => {
1217
+ });
1218
+ const RoundCuboidCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1179
1219
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1180
- shape: "roundCuboid"
1220
+ shape: "roundCuboid",
1221
+ ref: ref
1181
1222
  }));
1182
- };
1183
- const BallCollider = props => {
1223
+ });
1224
+ const BallCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1184
1225
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1185
- shape: "ball"
1226
+ shape: "ball",
1227
+ ref: ref
1186
1228
  }));
1187
- };
1188
- const CapsuleCollider = props => {
1229
+ });
1230
+ const CapsuleCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1189
1231
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1190
- shape: "capsule"
1232
+ shape: "capsule",
1233
+ ref: ref
1191
1234
  }));
1192
- };
1193
- const HeightfieldCollider = props => {
1235
+ });
1236
+ const HeightfieldCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1194
1237
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1195
- shape: "heightfield"
1238
+ shape: "heightfield",
1239
+ ref: ref
1196
1240
  }));
1197
- };
1198
- const TrimeshCollider = props => {
1241
+ });
1242
+ const TrimeshCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1199
1243
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1200
- shape: "trimesh"
1244
+ shape: "trimesh",
1245
+ ref: ref
1201
1246
  }));
1202
- };
1203
- const ConeCollider = props => {
1247
+ });
1248
+ const ConeCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1204
1249
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1205
- shape: "cone"
1250
+ shape: "cone",
1251
+ ref: ref
1206
1252
  }));
1207
- };
1208
- const CylinderCollider = props => {
1253
+ });
1254
+ const CylinderCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1209
1255
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1210
- shape: "cylinder"
1256
+ shape: "cylinder",
1257
+ ref: ref
1211
1258
  }));
1212
- };
1213
- const ConvexHullCollider = props => {
1259
+ });
1260
+ const ConvexHullCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1214
1261
  return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1215
- shape: "convexHull"
1262
+ shape: "convexHull",
1263
+ ref: ref
1216
1264
  }));
1217
- };
1265
+ });
1218
1266
 
1219
1267
  const _excluded$1 = ["children", "type", "position", "rotation", "scale", "quaternion"];
1220
1268
  const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
@@ -1290,7 +1338,7 @@ const geometryFromCollider = collider => {
1290
1338
  y,
1291
1339
  z
1292
1340
  } = collider.shape.halfExtents;
1293
- return new three.BoxBufferGeometry(x * 2 + 0.01, y * 2 + 0.01, z * 2 + 0.01);
1341
+ return new three.BoxGeometry(x * 2 + 0.01, y * 2 + 0.01, z * 2 + 0.01);
1294
1342
  }
1295
1343
 
1296
1344
  case rapier3dCompat.ShapeType.RoundCuboid:
@@ -1307,7 +1355,7 @@ const geometryFromCollider = collider => {
1307
1355
  case rapier3dCompat.ShapeType.Ball:
1308
1356
  {
1309
1357
  const r = collider.shape.radius;
1310
- return new three.SphereBufferGeometry(r + +0.01, 8, 8);
1358
+ return new three.SphereGeometry(r + +0.01, 8, 8);
1311
1359
  }
1312
1360
 
1313
1361
  case rapier3dCompat.ShapeType.TriMesh:
@@ -1339,7 +1387,7 @@ const geometryFromCollider = collider => {
1339
1387
  {
1340
1388
  const r = collider.shape.radius;
1341
1389
  const h = collider.shape.halfHeight;
1342
- const g = new three.CylinderBufferGeometry(r, r, h * 2);
1390
+ const g = new three.CylinderGeometry(r, r, h * 2);
1343
1391
  return g;
1344
1392
  }
1345
1393
 
@@ -1347,7 +1395,7 @@ const geometryFromCollider = collider => {
1347
1395
  {
1348
1396
  const r = collider.shape.radius;
1349
1397
  const h = collider.shape.halfHeight;
1350
- const g = new three.CapsuleBufferGeometry(r, h * 2, 4, 8);
1398
+ const g = new three.CapsuleGeometry(r, h * 2, 4, 8);
1351
1399
  return g;
1352
1400
  }
1353
1401
 
@@ -1355,7 +1403,7 @@ const geometryFromCollider = collider => {
1355
1403
  {
1356
1404
  const r = collider.shape.radius;
1357
1405
  const h = collider.shape.halfHeight;
1358
- const g = new three.ConeBufferGeometry(r, h * 2, 16);
1406
+ const g = new three.ConeGeometry(r, h * 2, 16);
1359
1407
  return g;
1360
1408
  }
1361
1409
 
@@ -1375,7 +1423,7 @@ const geometryFromCollider = collider => {
1375
1423
  }
1376
1424
  }
1377
1425
 
1378
- return new three.BoxBufferGeometry(1, 1, 1);
1426
+ return new three.BoxGeometry(1, 1, 1);
1379
1427
  };
1380
1428
 
1381
1429
  const DebugShape = /*#__PURE__*/React.memo(({
@@ -3,7 +3,7 @@ export { CoefficientCombineRule, Collider as RapierCollider, RigidBody as Rapier
3
3
  import React, { useState, useEffect, useRef, useMemo, createContext, useContext, memo, forwardRef, useImperativeHandle, useLayoutEffect } from 'react';
4
4
  import { useAsset } from 'use-asset';
5
5
  import { useFrame } from '@react-three/fiber';
6
- import { Quaternion, Euler, Vector3, Object3D, Matrix4, MathUtils, InstancedMesh, MeshBasicMaterial, Color, PlaneGeometry, ConeBufferGeometry, CapsuleBufferGeometry, CylinderBufferGeometry, BufferGeometry, BufferAttribute, SphereBufferGeometry, BoxBufferGeometry, DynamicDrawUsage } from 'three';
6
+ import { Quaternion, Euler, Vector3, Object3D, Matrix4, MathUtils, InstancedMesh, MeshBasicMaterial, Color, PlaneGeometry, ConeGeometry, CapsuleGeometry, CylinderGeometry, BufferGeometry, BufferAttribute, SphereGeometry, BoxGeometry, DynamicDrawUsage } from 'three';
7
7
  import { mergeVertices, RoundedBoxGeometry } from 'three-stdlib';
8
8
 
9
9
  const _quaternion = new Quaternion();
@@ -59,24 +59,24 @@ const createRigidBodyApi = ref => {
59
59
 
60
60
  mass: () => ref.current().mass(),
61
61
 
62
- applyImpulse(impulseVector) {
63
- ref.current().applyImpulse(impulseVector, true);
62
+ applyImpulse(impulseVector, wakeUp = true) {
63
+ ref.current().applyImpulse(impulseVector, wakeUp);
64
64
  },
65
65
 
66
- applyTorqueImpulse(torqueVector) {
67
- ref.current().applyTorqueImpulse(torqueVector, true);
66
+ applyTorqueImpulse(torqueVector, wakeUp = true) {
67
+ ref.current().applyTorqueImpulse(torqueVector, wakeUp);
68
68
  },
69
69
 
70
- applyImpulseAtPoint: (impulseVector, impulsePoint) => ref.current().applyImpulseAtPoint(impulseVector, impulsePoint, true),
71
- addForce: force => ref.current().addForce(force, true),
72
- addForceAtPoint: (force, point) => ref.current().addForceAtPoint(force, point, true),
73
- addTorque: torque => ref.current().addTorque(torque, true),
70
+ applyImpulseAtPoint: (impulseVector, impulsePoint, wakeUp = true) => ref.current().applyImpulseAtPoint(impulseVector, impulsePoint, wakeUp),
71
+ addForce: (force, wakeUp = true) => ref.current().addForce(force, wakeUp),
72
+ addForceAtPoint: (force, point, wakeUp = true) => ref.current().addForceAtPoint(force, point, wakeUp),
73
+ addTorque: (torque, wakeUp = true) => ref.current().addTorque(torque, wakeUp),
74
74
 
75
75
  translation() {
76
76
  return rapierVector3ToVector3(ref.current().translation());
77
77
  },
78
78
 
79
- setTranslation: translation => ref.current().setTranslation(translation, true),
79
+ setTranslation: (translation, wakeUp = true) => ref.current().setTranslation(translation, wakeUp),
80
80
 
81
81
  rotation() {
82
82
  const {
@@ -88,8 +88,8 @@ const createRigidBodyApi = ref => {
88
88
  return new Quaternion(x, y, z, w);
89
89
  },
90
90
 
91
- setRotation: rotation => {
92
- ref.current().setRotation(rotation, true);
91
+ setRotation: (rotation, wakeUp = true) => {
92
+ ref.current().setRotation(rotation, wakeUp);
93
93
  },
94
94
 
95
95
  linvel() {
@@ -101,7 +101,7 @@ const createRigidBodyApi = ref => {
101
101
  return new Vector3(x, y, z);
102
102
  },
103
103
 
104
- setLinvel: velocity => ref.current().setLinvel(velocity, true),
104
+ setLinvel: (velocity, wakeUp = true) => ref.current().setLinvel(velocity, wakeUp),
105
105
 
106
106
  angvel() {
107
107
  const {
@@ -112,7 +112,7 @@ const createRigidBodyApi = ref => {
112
112
  return new Vector3(x, y, z);
113
113
  },
114
114
 
115
- setAngvel: velocity => ref.current().setAngvel(velocity, true),
115
+ setAngvel: (velocity, wakeUp = true) => ref.current().setAngvel(velocity, wakeUp),
116
116
 
117
117
  linearDamping() {
118
118
  return ref.current().linearDamping();
@@ -129,12 +129,12 @@ const createRigidBodyApi = ref => {
129
129
  ref.current().setNextKinematicRotation(rotation);
130
130
  },
131
131
  setNextKinematicTranslation: translation => ref.current().setNextKinematicTranslation(translation),
132
- resetForces: () => ref.current().resetForces(true),
133
- resetTorques: () => ref.current().resetTorques(true),
134
- lockRotations: locked => ref.current().lockRotations(locked, true),
135
- lockTranslations: locked => ref.current().lockTranslations(locked, true),
136
- setEnabledRotations: (x, y, z) => ref.current().setEnabledRotations(x, y, z, true),
137
- setEnabledTranslations: (x, y, z) => ref.current().setEnabledTranslations(x, y, z, true)
132
+ resetForces: (wakeUp = true) => ref.current().resetForces(wakeUp),
133
+ resetTorques: (wakeUp = true) => ref.current().resetTorques(wakeUp),
134
+ lockRotations: (locked, wakeUp = true) => ref.current().lockRotations(locked, wakeUp),
135
+ lockTranslations: (locked, wakeUp = true) => ref.current().lockTranslations(locked, wakeUp),
136
+ setEnabledRotations: (x, y, z, wakeUp = true) => ref.current().setEnabledRotations(x, y, z, wakeUp),
137
+ setEnabledTranslations: (x, y, z, wakeUp = true) => ref.current().setEnabledTranslations(x, y, z, wakeUp)
138
138
  };
139
139
  };
140
140
  const createInstancedRigidBodiesApi = bodiesGetter => ({
@@ -157,9 +157,9 @@ const createWorldApi = ref => {
157
157
  createRigidBody: desc => ref.current().createRigidBody(desc),
158
158
  createCollider: (desc, rigidBody) => ref.current().createCollider(desc, rigidBody),
159
159
  removeRigidBody: rigidBody => ref.current().removeRigidBody(rigidBody),
160
- removeCollider: collider => ref.current().removeCollider(collider, true),
161
- createImpulseJoint: (params, rigidBodyA, rigidBodyB) => ref.current().createImpulseJoint(params, rigidBodyA, rigidBodyB, true),
162
- removeImpulseJoint: joint => ref.current().removeImpulseJoint(joint, true),
160
+ removeCollider: (collider, wakeUp = true) => ref.current().removeCollider(collider, wakeUp),
161
+ createImpulseJoint: (params, rigidBodyA, rigidBodyB, wakeUp = true) => ref.current().createImpulseJoint(params, rigidBodyA, rigidBodyB, wakeUp),
162
+ removeImpulseJoint: (joint, wakeUp = true) => ref.current().removeImpulseJoint(joint, wakeUp),
163
163
  forEachCollider: callback => ref.current().forEachCollider(callback),
164
164
  setGravity: ({
165
165
  x,
@@ -721,6 +721,32 @@ const createColliderFromOptions = (options, world, scale, rigidBody) => {
721
721
  const desc = ColliderDesc[options.shape](...scaledArgs);
722
722
  return world.createCollider(desc, rigidBody);
723
723
  };
724
+ const massPropertiesConflictError = "Please pick ONLY ONE of the `density`, `mass` and `massProperties` options.";
725
+
726
+ const setColliderMassOptions = (collider, options) => {
727
+ if (options.density !== undefined) {
728
+ if (options.mass !== undefined || options.massProperties !== undefined) {
729
+ throw new Error(massPropertiesConflictError);
730
+ }
731
+
732
+ collider.setDensity(options.density);
733
+ return;
734
+ }
735
+
736
+ if (options.mass !== undefined) {
737
+ if (options.massProperties !== undefined) {
738
+ throw new Error(massPropertiesConflictError);
739
+ }
740
+
741
+ collider.setMass(options.mass);
742
+ return;
743
+ }
744
+
745
+ if (options.massProperties !== undefined) {
746
+ collider.setMassProperties(options.massProperties.mass, options.massProperties.centerOfMass, options.massProperties.principalAngularInertia, options.massProperties.angularInertiaLocalFrame);
747
+ }
748
+ };
749
+
724
750
  const mutableColliderOptions = {
725
751
  sensor: (collider, value) => {
726
752
  collider.setSensor(value);
@@ -734,14 +760,14 @@ const mutableColliderOptions = {
734
760
  friction: (collider, value) => {
735
761
  collider.setFriction(value);
736
762
  },
763
+ frictionCombineRule: (collider, value) => {
764
+ collider.setFrictionCombineRule(value);
765
+ },
737
766
  restitution: (collider, value) => {
738
767
  collider.setRestitution(value);
739
768
  },
740
- density: (collider, value) => {
741
- collider.setDensity(value);
742
- },
743
- mass: (collider, value) => {
744
- collider.setMass(value);
769
+ restitutionCombineRule: (collider, value) => {
770
+ collider.setRestitutionCombineRule(value);
745
771
  }
746
772
  };
747
773
  const mutableColliderOptionKeys = Object.keys(mutableColliderOptions);
@@ -773,9 +799,14 @@ const setColliderOptions = (collider, options, states) => {
773
799
 
774
800
  mutableColliderOptionKeys.forEach(key => {
775
801
  if (key in options) {
776
- mutableColliderOptions[key](collider, options[key]);
802
+ const option = options[key];
803
+ mutableColliderOptions[key](collider, // @ts-ignore Option does not want to fit into the function, but it will
804
+ option, options);
777
805
  }
778
- });
806
+ }); // handle mass separately, because the assignments
807
+ // are exclusive.
808
+
809
+ setColliderMassOptions(collider, options);
779
810
  }
780
811
  };
781
812
  const useUpdateColliderOptions = (collidersRef, props, states) => {
@@ -1084,7 +1115,7 @@ const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
1084
1115
  };
1085
1116
 
1086
1117
  // Colliders
1087
- const AnyCollider = /*#__PURE__*/memo(props => {
1118
+ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/React.forwardRef((props, forwardedRef) => {
1088
1119
  const {
1089
1120
  children,
1090
1121
  position,
@@ -1099,7 +1130,15 @@ const AnyCollider = /*#__PURE__*/memo(props => {
1099
1130
  } = useRapier();
1100
1131
  const rigidBodyContext = useRigidBodyContext();
1101
1132
  const ref = useRef(null);
1102
- const collidersRef = useRef([]);
1133
+ const collidersRef = useMemo(() => {
1134
+ if (forwardedRef !== null) {
1135
+ return forwardedRef;
1136
+ }
1137
+
1138
+ const result = /*#__PURE__*/React.createRef();
1139
+ result.current = [];
1140
+ return result;
1141
+ }, []);
1103
1142
  useEffect(() => {
1104
1143
  const object = ref.current;
1105
1144
  const worldScale = object.getWorldScale(new Vector3());
@@ -1144,52 +1183,61 @@ const AnyCollider = /*#__PURE__*/memo(props => {
1144
1183
  scale: scale,
1145
1184
  ref: ref
1146
1185
  }, children);
1147
- });
1148
- const CuboidCollider = props => {
1186
+ }));
1187
+ const CuboidCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1149
1188
  return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1150
- shape: "cuboid"
1189
+ shape: "cuboid",
1190
+ ref: ref
1151
1191
  }));
1152
- };
1153
- const RoundCuboidCollider = props => {
1192
+ });
1193
+ const RoundCuboidCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1154
1194
  return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1155
- shape: "roundCuboid"
1195
+ shape: "roundCuboid",
1196
+ ref: ref
1156
1197
  }));
1157
- };
1158
- const BallCollider = props => {
1198
+ });
1199
+ const BallCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1159
1200
  return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1160
- shape: "ball"
1201
+ shape: "ball",
1202
+ ref: ref
1161
1203
  }));
1162
- };
1163
- const CapsuleCollider = props => {
1204
+ });
1205
+ const CapsuleCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1164
1206
  return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1165
- shape: "capsule"
1207
+ shape: "capsule",
1208
+ ref: ref
1166
1209
  }));
1167
- };
1168
- const HeightfieldCollider = props => {
1210
+ });
1211
+ const HeightfieldCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1169
1212
  return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1170
- shape: "heightfield"
1213
+ shape: "heightfield",
1214
+ ref: ref
1171
1215
  }));
1172
- };
1173
- const TrimeshCollider = props => {
1216
+ });
1217
+ const TrimeshCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1174
1218
  return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1175
- shape: "trimesh"
1219
+ shape: "trimesh",
1220
+ ref: ref
1176
1221
  }));
1177
- };
1178
- const ConeCollider = props => {
1222
+ });
1223
+ const ConeCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1179
1224
  return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1180
- shape: "cone"
1225
+ shape: "cone",
1226
+ ref: ref
1181
1227
  }));
1182
- };
1183
- const CylinderCollider = props => {
1228
+ });
1229
+ const CylinderCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1184
1230
  return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1185
- shape: "cylinder"
1231
+ shape: "cylinder",
1232
+ ref: ref
1186
1233
  }));
1187
- };
1188
- const ConvexHullCollider = props => {
1234
+ });
1235
+ const ConvexHullCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1189
1236
  return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1190
- shape: "convexHull"
1237
+ shape: "convexHull",
1238
+ ref: ref
1191
1239
  }));
1192
- };
1240
+ });
1193
1241
 
1194
1242
  const _excluded$1 = ["children", "type", "position", "rotation", "scale", "quaternion"];
1195
1243
  const RigidBodyContext = /*#__PURE__*/createContext(undefined);
@@ -1265,7 +1313,7 @@ const geometryFromCollider = collider => {
1265
1313
  y,
1266
1314
  z
1267
1315
  } = collider.shape.halfExtents;
1268
- return new BoxBufferGeometry(x * 2 + 0.01, y * 2 + 0.01, z * 2 + 0.01);
1316
+ return new BoxGeometry(x * 2 + 0.01, y * 2 + 0.01, z * 2 + 0.01);
1269
1317
  }
1270
1318
 
1271
1319
  case ShapeType.RoundCuboid:
@@ -1282,7 +1330,7 @@ const geometryFromCollider = collider => {
1282
1330
  case ShapeType.Ball:
1283
1331
  {
1284
1332
  const r = collider.shape.radius;
1285
- return new SphereBufferGeometry(r + +0.01, 8, 8);
1333
+ return new SphereGeometry(r + +0.01, 8, 8);
1286
1334
  }
1287
1335
 
1288
1336
  case ShapeType.TriMesh:
@@ -1314,7 +1362,7 @@ const geometryFromCollider = collider => {
1314
1362
  {
1315
1363
  const r = collider.shape.radius;
1316
1364
  const h = collider.shape.halfHeight;
1317
- const g = new CylinderBufferGeometry(r, r, h * 2);
1365
+ const g = new CylinderGeometry(r, r, h * 2);
1318
1366
  return g;
1319
1367
  }
1320
1368
 
@@ -1322,7 +1370,7 @@ const geometryFromCollider = collider => {
1322
1370
  {
1323
1371
  const r = collider.shape.radius;
1324
1372
  const h = collider.shape.halfHeight;
1325
- const g = new CapsuleBufferGeometry(r, h * 2, 4, 8);
1373
+ const g = new CapsuleGeometry(r, h * 2, 4, 8);
1326
1374
  return g;
1327
1375
  }
1328
1376
 
@@ -1330,7 +1378,7 @@ const geometryFromCollider = collider => {
1330
1378
  {
1331
1379
  const r = collider.shape.radius;
1332
1380
  const h = collider.shape.halfHeight;
1333
- const g = new ConeBufferGeometry(r, h * 2, 16);
1381
+ const g = new ConeGeometry(r, h * 2, 16);
1334
1382
  return g;
1335
1383
  }
1336
1384
 
@@ -1350,7 +1398,7 @@ const geometryFromCollider = collider => {
1350
1398
  }
1351
1399
  }
1352
1400
 
1353
- return new BoxBufferGeometry(1, 1, 1);
1401
+ return new BoxGeometry(1, 1, 1);
1354
1402
  };
1355
1403
 
1356
1404
  const DebugShape = /*#__PURE__*/memo(({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-three/rapier",
3
- "version": "0.7.4",
3
+ "version": "0.7.5",
4
4
  "source": "src/index.ts",
5
5
  "main": "dist/react-three-rapier.cjs.js",
6
6
  "module": "dist/react-three-rapier.esm.js",
@@ -11,11 +11,16 @@
11
11
  "devDependencies": {
12
12
  "@react-three/drei": "^9.6.2",
13
13
  "@react-three/fiber": "^8.0.12",
14
+ "@react-three/test-renderer": "^8.0.17",
14
15
  "@types/react-dom": "^18.0.2",
15
16
  "@types/three": "^0.139.0",
17
+ "@vitejs/plugin-react": "^2.1.0",
18
+ "@vitest/ui": "^0.23.4",
19
+ "happy-dom": "^6.0.4",
16
20
  "react": "^18.1.0",
17
21
  "react-dom": "^18.1.0",
18
- "three": "^0.139.2"
22
+ "three": "^0.139.2",
23
+ "vitest": "^0.23.4"
19
24
  },
20
25
  "peerDependencies": {
21
26
  "@react-three/fiber": "^8.0.12",
@@ -24,8 +29,8 @@
24
29
  },
25
30
  "dependencies": {
26
31
  "@dimforge/rapier3d-compat": "0.9.0",
27
- "use-asset": "^1.0.4",
28
- "three-stdlib": "^2.15.0"
32
+ "three-stdlib": "^2.15.0",
33
+ "use-asset": "^1.0.4"
29
34
  },
30
35
  "repository": "https://github.com/pmndrs/react-three-rapier/tree/master/packages/react-three-rapier"
31
36
  }
package/readme.md CHANGED
@@ -9,6 +9,8 @@
9
9
 
10
10
  <p align="center">⚠️ Under heavy development. All APIs are subject to change. ⚠️</p>
11
11
 
12
+ For contributions, please read the [contributing guide](https://github.com/pmndrs/react-three-rapier/blob/main/packages/react-three-rapier/CONTRIBUTING.md).
13
+
12
14
  ## Usage
13
15
 
14
16
  ```tsx
@@ -171,7 +173,7 @@ const Scene = () => {
171
173
  colliders="ball"
172
174
  >
173
175
  <instancedMesh args={[undefined, undefined, COUNT]}>
174
- <sphereBufferGeometry args={[0.2]} />
176
+ <sphereGeometry args={[0.2]} />
175
177
  <meshPhysicalGeometry color="blue" />
176
178
 
177
179
  <CuboidCollider args={[0.1, 0.2, 0.1]} />