@react-three/rapier 0.15.1 → 0.16.0-canary.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -72,37 +72,37 @@ function _objectSpread2(target) {
72
72
  return target;
73
73
  }
74
74
 
75
- const createWorldApi = ref => {
75
+ const createWorldApi = getWorld => {
76
76
  return {
77
- raw: () => ref.current(),
78
- getCollider: handle => ref.current().getCollider(handle),
79
- getRigidBody: handle => ref.current().getRigidBody(handle),
80
- createRigidBody: desc => ref.current().createRigidBody(desc),
81
- createCollider: (desc, rigidBody) => ref.current().createCollider(desc, rigidBody),
77
+ raw: () => getWorld(),
78
+ getCollider: handle => getWorld().getCollider(handle),
79
+ getRigidBody: handle => getWorld().getRigidBody(handle),
80
+ createRigidBody: desc => getWorld().createRigidBody(desc),
81
+ createCollider: (desc, rigidBody) => getWorld().createCollider(desc, rigidBody),
82
82
  removeRigidBody: rigidBody => {
83
- if (!ref.current().bodies.contains(rigidBody.handle)) return;
84
- ref.current().removeRigidBody(rigidBody);
83
+ if (!getWorld().bodies.contains(rigidBody.handle)) return;
84
+ getWorld().removeRigidBody(rigidBody);
85
85
  },
86
86
  removeCollider: (collider, wakeUp = true) => {
87
- if (!ref.current().colliders.contains(collider.handle)) return;
88
- ref.current().removeCollider(collider, wakeUp);
87
+ if (!getWorld().colliders.contains(collider.handle)) return;
88
+ getWorld().removeCollider(collider, wakeUp);
89
89
  },
90
- createImpulseJoint: (params, rigidBodyA, rigidBodyB, wakeUp = true) => ref.current().createImpulseJoint(params, rigidBodyA, rigidBodyB, wakeUp),
90
+ createImpulseJoint: (params, rigidBodyA, rigidBodyB, wakeUp = true) => getWorld().createImpulseJoint(params, rigidBodyA, rigidBodyB, wakeUp),
91
91
  removeImpulseJoint: (joint, wakeUp = true) => {
92
- if (!ref.current().impulseJoints.contains(joint.handle)) return;
93
- ref.current().removeImpulseJoint(joint, wakeUp);
92
+ if (!getWorld().impulseJoints.contains(joint.handle)) return;
93
+ getWorld().removeImpulseJoint(joint, wakeUp);
94
94
  },
95
- forEachCollider: callback => ref.current().forEachCollider(callback),
95
+ forEachCollider: callback => getWorld().forEachCollider(callback),
96
96
  setGravity: ({
97
97
  x,
98
98
  y,
99
99
  z
100
- }) => ref.current().gravity = {
100
+ }) => getWorld().gravity = {
101
101
  x,
102
102
  y,
103
103
  z
104
104
  },
105
- debugRender: () => ref.current().debugRender()
105
+ debugRender: () => getWorld().debugRender()
106
106
  };
107
107
  };
108
108
 
@@ -295,6 +295,7 @@ const createColliderFromOptions = (options, world, scale, getRigidBody) => {
295
295
  const desc = rapier3dCompat.ColliderDesc[options.shape](...scaledArgs);
296
296
  return world.createCollider(desc, getRigidBody === null || getRigidBody === void 0 ? void 0 : getRigidBody());
297
297
  };
298
+ const immutableColliderOptions = ["shape", "args"];
298
299
  const massPropertiesConflictError = "Please pick ONLY ONE of the `density`, `mass` and `massProperties` options.";
299
300
 
300
301
  const setColliderMassOptions = (collider, options) => {
@@ -343,7 +344,7 @@ const mutableColliderOptions = {
343
344
  restitutionCombineRule: (collider, value) => {
344
345
  collider.setRestitutionCombineRule(value);
345
346
  },
346
- // To make sure the options all mutalbe options are listed
347
+ // To make sure the options all mutable options are listed
347
348
  quaternion: () => {},
348
349
  position: () => {},
349
350
  rotation: () => {},
@@ -405,7 +406,7 @@ const useUpdateColliderOptions = (getCollider, props, states) => {
405
406
  React.useEffect(() => {
406
407
  const collider = getCollider();
407
408
  setColliderOptions(collider, props, states);
408
- }, mutablePropsAsFlatArray);
409
+ }, [...mutablePropsAsFlatArray, getCollider]);
409
410
  };
410
411
 
411
412
  const isChildOfMeshCollider = child => {
@@ -682,6 +683,33 @@ const Debug = /*#__PURE__*/React.memo(() => {
682
683
  }), /*#__PURE__*/React__default["default"].createElement("bufferGeometry", null)));
683
684
  });
684
685
 
686
+ /**
687
+ * Initiate an instance and return a safe getter
688
+ */
689
+
690
+ const useImperativeInstance = (createFn, destroyFn, dependencyList) => {
691
+ const ref = React.useRef();
692
+ const getInstance = React.useCallback(() => {
693
+ if (!ref.current) {
694
+ ref.current = createFn();
695
+ }
696
+
697
+ return ref.current;
698
+ }, dependencyList);
699
+ React.useEffect(() => {
700
+ // Save the destroy function and instance
701
+ const instance = getInstance();
702
+
703
+ const destroy = () => destroyFn(instance);
704
+
705
+ return () => {
706
+ destroy();
707
+ ref.current = undefined;
708
+ };
709
+ }, [getInstance]);
710
+ return getInstance;
711
+ };
712
+
685
713
  const rapierContext = /*#__PURE__*/React.createContext(undefined);
686
714
 
687
715
  const getCollisionPayloadFromSource = (target, other) => {
@@ -731,77 +759,60 @@ const Physics = ({
731
759
  const rapier = useAsset.useAsset(importRapier);
732
760
  const {
733
761
  invalidate
734
- } = fiber.useThree();
735
- const worldRef = React.useRef();
736
- const getWorldRef = React.useRef(() => {
737
- if (!worldRef.current) {
738
- const world = new rapier.World(vectorArrayToVector3(_gravity));
739
- worldRef.current = world;
740
- }
762
+ } = fiber.useThree(); // Init World
741
763
 
742
- return worldRef.current;
743
- });
764
+ const getWorld = useImperativeInstance(() => {
765
+ return new rapier.World(vectorArrayToVector3(_gravity));
766
+ }, world => {
767
+ world.free();
768
+ }, []);
744
769
  const rigidBodyStates = useConst(() => new Map());
745
770
  const colliderStates = useConst(() => new Map());
746
771
  const rigidBodyEvents = useConst(() => new Map());
747
772
  const colliderEvents = useConst(() => new Map());
748
773
  const eventQueue = useConst(() => new rapier3dCompat.EventQueue(false));
749
774
  const beforeStepCallbacks = useConst(() => new Set());
750
- const afterStepCallbacks = useConst(() => new Set()); // Init world
751
-
752
- React.useEffect(() => {
753
- const world = getWorldRef.current();
754
- return () => {
755
- if (world) {
756
- world.free();
757
- worldRef.current = undefined;
758
- }
759
- };
760
- }, []); // Update gravity
775
+ const afterStepCallbacks = useConst(() => new Set()); // Update gravity
761
776
 
762
777
  React.useEffect(() => {
763
- const world = worldRef.current;
778
+ const world = getWorld();
764
779
 
765
780
  if (world) {
766
781
  world.gravity = vectorArrayToVector3(_gravity);
767
782
  }
768
783
  }, [_gravity]);
769
- const api = React.useMemo(() => createWorldApi(getWorldRef), []);
784
+ const api = React.useMemo(() => createWorldApi(getWorld), []);
770
785
  const getSourceFromColliderHandle = React.useCallback(handle => {
771
- const world = worldRef.current;
772
-
773
- if (world) {
774
- var _collider$parent;
775
-
776
- const collider = world.getCollider(handle);
777
- const colEvents = colliderEvents.get(handle);
778
- const colliderState = colliderStates.get(handle);
779
- const rigidBodyHandle = collider === null || collider === void 0 ? void 0 : (_collider$parent = collider.parent()) === null || _collider$parent === void 0 ? void 0 : _collider$parent.handle;
780
- const rigidBody = rigidBodyHandle !== undefined ? world.getRigidBody(rigidBodyHandle) : undefined;
781
- const rbEvents = rigidBody && rigidBodyHandle !== undefined ? rigidBodyEvents.get(rigidBodyHandle) : undefined;
782
- const rigidBodyState = rigidBodyHandle !== undefined ? rigidBodyStates.get(rigidBodyHandle) : undefined;
783
- const source = {
784
- collider: {
785
- object: collider,
786
- events: colEvents,
787
- state: colliderState
788
- },
789
- rigidBody: {
790
- object: rigidBody,
791
- events: rbEvents,
792
- state: rigidBodyState
793
- }
794
- };
795
- return source;
796
- }
786
+ var _collider$parent;
787
+
788
+ const world = getWorld();
789
+ const collider = world.getCollider(handle);
790
+ const colEvents = colliderEvents.get(handle);
791
+ const colliderState = colliderStates.get(handle);
792
+ const rigidBodyHandle = collider === null || collider === void 0 ? void 0 : (_collider$parent = collider.parent()) === null || _collider$parent === void 0 ? void 0 : _collider$parent.handle;
793
+ const rigidBody = rigidBodyHandle !== undefined ? world.getRigidBody(rigidBodyHandle) : undefined;
794
+ const rbEvents = rigidBody && rigidBodyHandle !== undefined ? rigidBodyEvents.get(rigidBodyHandle) : undefined;
795
+ const rigidBodyState = rigidBodyHandle !== undefined ? rigidBodyStates.get(rigidBodyHandle) : undefined;
796
+ const source = {
797
+ collider: {
798
+ object: collider,
799
+ events: colEvents,
800
+ state: colliderState
801
+ },
802
+ rigidBody: {
803
+ object: rigidBody,
804
+ events: rbEvents,
805
+ state: rigidBodyState
806
+ }
807
+ };
808
+ return source;
797
809
  }, []);
798
810
  const [steppingState] = React.useState({
799
811
  previousState: {},
800
812
  accumulator: 0
801
813
  });
802
814
  const step = React.useCallback(dt => {
803
- const world = worldRef.current;
804
- if (!world) return;
815
+ const world = getWorld();
805
816
  /* Check if the timestep is supposed to be variable. We'll do this here
806
817
  once so we don't have to string-check every frame. */
807
818
 
@@ -1057,29 +1068,6 @@ function _extends() {
1057
1068
  return _extends.apply(this, arguments);
1058
1069
  }
1059
1070
 
1060
- /**
1061
- * Initiate an instance and return a safe getter
1062
- */
1063
-
1064
- const useImperativeInstance = (createFn, destroyFn) => {
1065
- const ref = React.useRef();
1066
- const refGetter = React.useMemo(() => () => {
1067
- if (!ref.current) {
1068
- ref.current = createFn();
1069
- }
1070
-
1071
- return ref.current;
1072
- }, []);
1073
- React.useEffect(() => {
1074
- const instance = refGetter();
1075
- return () => {
1076
- destroyFn(instance);
1077
- ref.current = undefined;
1078
- };
1079
- }, []);
1080
- return refGetter;
1081
- };
1082
-
1083
1071
  /**
1084
1072
  * Takes an object resembling a Vector3 and returs a Three.Vector3
1085
1073
  * @category Math helpers
@@ -1131,7 +1119,19 @@ const euler = ({
1131
1119
  return new three.Euler(x, y, z);
1132
1120
  };
1133
1121
 
1134
- // Colliders
1122
+ const useForwardedRef = (forwardedRef, defaultValue = null) => {
1123
+ const innerRef = React.useRef(defaultValue); // Update the forwarded ref when the inner ref changes
1124
+
1125
+ if (forwardedRef && typeof forwardedRef !== "function") {
1126
+ if (!forwardedRef.current) {
1127
+ forwardedRef.current = innerRef.current;
1128
+ }
1129
+
1130
+ return forwardedRef;
1131
+ }
1132
+
1133
+ return innerRef;
1134
+ };
1135
1135
 
1136
1136
  /**
1137
1137
  * A collider is a shape that can be attached to a rigid body to define its physical properties.
@@ -1152,22 +1152,30 @@ const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((prop
1152
1152
  colliderStates
1153
1153
  } = useRapier();
1154
1154
  const rigidBodyContext = useRigidBodyContext();
1155
- const ref = React.useRef(null);
1155
+ const colliderRef = useForwardedRef(forwardedRef);
1156
+ const objectRef = React.useRef(null); // We spread the props out here to make sure that the ref is updated when the props change.
1157
+
1158
+ const immutablePropArray = immutableColliderOptions.flatMap(key => Array.isArray(props[key]) ? [...props[key]] : props[key]);
1156
1159
  const getInstance = useImperativeInstance(() => {
1157
- const worldScale = ref.current.getWorldScale(vec3());
1160
+ const worldScale = objectRef.current.getWorldScale(vec3());
1158
1161
  const collider = createColliderFromOptions(props, world, worldScale, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.getRigidBody);
1162
+
1163
+ if (typeof forwardedRef == "function") {
1164
+ forwardedRef(collider);
1165
+ }
1166
+
1167
+ colliderRef.current = collider;
1159
1168
  return collider;
1160
1169
  }, collider => {
1161
1170
  world.removeCollider(collider);
1162
- });
1171
+ }, [...immutablePropArray, rigidBodyContext]);
1163
1172
  React.useEffect(() => {
1164
1173
  const collider = getInstance();
1165
- colliderStates.set(collider.handle, createColliderState(collider, ref.current, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
1174
+ colliderStates.set(collider.handle, createColliderState(collider, objectRef.current, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
1166
1175
  return () => {
1167
1176
  colliderStates.delete(collider.handle);
1168
1177
  };
1169
- }, []);
1170
- React.useImperativeHandle(forwardedRef, () => getInstance());
1178
+ }, [getInstance]);
1171
1179
  const mergedProps = React.useMemo(() => {
1172
1180
  return _objectSpread2(_objectSpread2({}, cleanRigidBodyPropsForCollider(rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options)), props);
1173
1181
  }, [props, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options]);
@@ -1178,7 +1186,7 @@ const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((prop
1178
1186
  rotation: rotation,
1179
1187
  quaternion: quaternion,
1180
1188
  scale: scale,
1181
- ref: ref,
1189
+ ref: objectRef,
1182
1190
  name: name
1183
1191
  }, children);
1184
1192
  }));
@@ -1193,102 +1201,106 @@ const CuboidCollider = /*#__PURE__*/React__default["default"].forwardRef((props,
1193
1201
  ref: ref
1194
1202
  }));
1195
1203
  });
1204
+ CuboidCollider.displayName = "CuboidCollider";
1205
+
1196
1206
  /**
1197
1207
  * A round cuboid collider shape
1198
1208
  * @category Colliders
1199
1209
  */
1210
+ const RoundCuboidCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1211
+ shape: "roundCuboid",
1212
+ ref: ref
1213
+ })));
1214
+ RoundCuboidCollider.displayName = "RoundCuboidCollider";
1200
1215
 
1201
- const RoundCuboidCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1202
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1203
- shape: "roundCuboid",
1204
- ref: ref
1205
- }));
1206
- });
1207
1216
  /**
1208
1217
  * A ball collider shape
1209
1218
  * @category Colliders
1210
1219
  */
1220
+ const BallCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1221
+ shape: "ball",
1222
+ ref: ref
1223
+ })));
1224
+ BallCollider.displayName = "BallCollider";
1211
1225
 
1212
- const BallCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1213
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1214
- shape: "ball",
1215
- ref: ref
1216
- }));
1217
- });
1218
1226
  /**
1219
1227
  * A capsule collider shape
1220
1228
  * @category Colliders
1221
1229
  */
1230
+ const CapsuleCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1231
+ shape: "capsule",
1232
+ ref: ref
1233
+ })));
1234
+ CapsuleCollider.displayName = "CapsuleCollider";
1222
1235
 
1223
- const CapsuleCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1224
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1225
- shape: "capsule",
1226
- ref: ref
1227
- }));
1228
- });
1229
1236
  /**
1230
1237
  * A heightfield collider shape
1231
1238
  * @category Colliders
1232
1239
  */
1240
+ const HeightfieldCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1241
+ shape: "heightfield",
1242
+ ref: ref
1243
+ })));
1244
+ HeightfieldCollider.displayName = "HeightfieldCollider";
1233
1245
 
1234
- const HeightfieldCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1235
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1236
- shape: "heightfield",
1237
- ref: ref
1238
- }));
1239
- });
1240
1246
  /**
1241
1247
  * A trimesh collider shape
1242
1248
  * @category Colliders
1243
1249
  */
1250
+ const TrimeshCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1251
+ shape: "trimesh",
1252
+ ref: ref
1253
+ })));
1254
+ TrimeshCollider.displayName = "TrimeshCollider";
1244
1255
 
1245
- const TrimeshCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1246
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1247
- shape: "trimesh",
1248
- ref: ref
1249
- }));
1250
- });
1251
1256
  /**
1252
1257
  * A cone collider shape
1253
1258
  * @category Colliders
1254
1259
  */
1260
+ const ConeCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1261
+ shape: "cone",
1262
+ ref: ref
1263
+ })));
1264
+ ConeCollider.displayName = "ConeCollider";
1265
+
1266
+ /**
1267
+ * A round cylinder collider shape
1268
+ * @category Colliders
1269
+ */
1270
+ const RoundConeCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1271
+ shape: "roundCone",
1272
+ ref: ref
1273
+ })));
1274
+ RoundConeCollider.displayName = "RoundConeCollider";
1255
1275
 
1256
- const ConeCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1257
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1258
- shape: "cone",
1259
- ref: ref
1260
- }));
1261
- });
1262
1276
  /**
1263
1277
  * A cylinder collider shape
1264
1278
  * @category Colliders
1265
1279
  */
1280
+ const CylinderCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1281
+ shape: "cylinder",
1282
+ ref: ref
1283
+ })));
1284
+ CylinderCollider.displayName = "CylinderCollider";
1285
+
1286
+ /**
1287
+ * A round cylinder collider shape
1288
+ * @category Colliders
1289
+ */
1290
+ const RoundCylinderCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1291
+ shape: "roundCylinder",
1292
+ ref: ref
1293
+ })));
1294
+ CylinderCollider.displayName = "RoundCylinderCollider";
1266
1295
 
1267
- const CylinderCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1268
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1269
- shape: "cylinder",
1270
- ref: ref
1271
- }));
1272
- });
1273
1296
  /**
1274
1297
  * A convex hull collider shape
1275
1298
  * @category Colliders
1276
1299
  */
1277
-
1278
- const ConvexHullCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => {
1279
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1280
- shape: "convexHull",
1281
- ref: ref
1282
- }));
1283
- });
1284
- CuboidCollider.displayName = "CuboidCollider";
1285
- RoundCuboidCollider.displayName = "RoundCuboidCollider";
1286
- BallCollider.displayName = "BallCollider";
1287
- CapsuleCollider.displayName = "CapsuleCollider";
1288
- HeightfieldCollider.displayName = "HeightfieldCollider";
1289
- TrimeshCollider.displayName = "TrimeshCollider";
1290
- ConeCollider.displayName = "ConeCollider";
1291
- CylinderCollider.displayName = "CylinderCollider";
1300
+ const ConvexHullCollider = /*#__PURE__*/React__default["default"].forwardRef((props, ref) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1301
+ shape: "convexHull",
1302
+ ref: ref
1303
+ })));
1292
1304
  ConvexHullCollider.displayName = "ConvexHullCollider";
1293
1305
 
1294
1306
  const rigidBodyDescFromOptions = options => {
@@ -1323,6 +1335,7 @@ const createRigidBodyState = ({
1323
1335
  meshType: _meshType
1324
1336
  };
1325
1337
  };
1338
+ const immutableRigidBodyOptions = ["args", "colliders", "canSleep"];
1326
1339
  const mutableRigidBodyOptions = {
1327
1340
  gravityScale: (rb, value) => {
1328
1341
  rb.setGravityScale(value, true);
@@ -1461,7 +1474,8 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
1461
1474
  } = props,
1462
1475
  objectProps = _objectWithoutProperties(props, _excluded$1);
1463
1476
 
1464
- const ref = React.useRef(null);
1477
+ const objectRef = React.useRef(null);
1478
+ const rigidBodyRef = useForwardedRef(forwardedRef);
1465
1479
  const {
1466
1480
  world,
1467
1481
  rigidBodyStates,
@@ -1473,41 +1487,49 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
1473
1487
  children: undefined
1474
1488
  });
1475
1489
  }, [physicsOptions, props]);
1476
- const childColliderProps = useChildColliderProps(ref, mergedOptions); // Provide a way to eagerly create rigidbody
1490
+ const immutablePropArray = immutableRigidBodyOptions.flatMap(key => {
1491
+ return Array.isArray(mergedOptions[key]) ? [...mergedOptions[key]] : mergedOptions[key];
1492
+ });
1493
+ const childColliderProps = useChildColliderProps(objectRef, mergedOptions); // Provide a way to eagerly create rigidbody
1477
1494
 
1478
- const getInstance = useImperativeInstance(() => {
1495
+ const getRigidBody = useImperativeInstance(() => {
1479
1496
  const desc = rigidBodyDescFromOptions(mergedOptions);
1480
1497
  const rigidBody = world.createRigidBody(desc);
1498
+
1499
+ if (typeof forwardedRef === "function") {
1500
+ forwardedRef(rigidBody);
1501
+ }
1502
+
1503
+ rigidBodyRef.current = rigidBody;
1481
1504
  return rigidBody;
1482
1505
  }, rigidBody => {
1483
1506
  world.removeRigidBody(rigidBody);
1484
- }); // Only provide a object state after the ref has been set
1507
+ }, immutablePropArray); // Only provide a object state after the ref has been set
1485
1508
 
1486
1509
  React.useEffect(() => {
1487
- const rigidBody = getInstance();
1510
+ const rigidBody = getRigidBody();
1488
1511
  const state = createRigidBodyState({
1489
1512
  rigidBody,
1490
- object: ref.current
1513
+ object: objectRef.current
1491
1514
  });
1492
1515
  rigidBodyStates.set(rigidBody.handle, props.transformState ? props.transformState(state) : state);
1493
1516
  return () => {
1494
1517
  rigidBodyStates.delete(rigidBody.handle);
1495
1518
  };
1496
- }, []);
1497
- useUpdateRigidBodyOptions(getInstance, mergedOptions, rigidBodyStates);
1498
- useRigidBodyEvents(getInstance, mergedOptions, rigidBodyEvents);
1499
- React.useImperativeHandle(forwardedRef, () => getInstance());
1519
+ }, [getRigidBody]);
1520
+ useUpdateRigidBodyOptions(getRigidBody, mergedOptions, rigidBodyStates);
1521
+ useRigidBodyEvents(getRigidBody, mergedOptions, rigidBodyEvents);
1500
1522
  const contextValue = React.useMemo(() => {
1501
1523
  return {
1502
- ref,
1503
- getRigidBody: getInstance,
1524
+ ref: objectRef,
1525
+ getRigidBody: getRigidBody,
1504
1526
  options: mergedOptions
1505
1527
  };
1506
- }, [mergedOptions]);
1528
+ }, [getRigidBody]);
1507
1529
  return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
1508
1530
  value: contextValue
1509
1531
  }, /*#__PURE__*/React__default["default"].createElement("object3D", _extends({
1510
- ref: ref
1532
+ ref: objectRef
1511
1533
  }, objectProps, {
1512
1534
  position: position,
1513
1535
  rotation: rotation,
@@ -1554,9 +1576,10 @@ const MeshCollider = /*#__PURE__*/React.memo(props => {
1554
1576
  MeshCollider.displayName = "MeshCollider";
1555
1577
 
1556
1578
  const _excluded = ["children", "instances", "colliderNodes", "position", "rotation", "quaternion", "scale"];
1557
- const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props, ref) => {
1558
- const object = React.useRef(null);
1559
- const instancedWrapper = React.useRef(null);
1579
+ const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props, forwardedRef) => {
1580
+ const rigidBodiesRef = useForwardedRef(forwardedRef, []);
1581
+ const objectRef = React.useRef(null);
1582
+ const instanceWrapperRef = React.useRef(null);
1560
1583
 
1561
1584
  const {
1562
1585
  // instanced props
@@ -1571,14 +1594,12 @@ const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forward
1571
1594
  } = props,
1572
1595
  rigidBodyProps = _objectWithoutProperties(props, _excluded);
1573
1596
 
1574
- const rigidBodyApis = React.useRef([]);
1575
- React.useImperativeHandle(ref, () => rigidBodyApis.current, [instances]);
1576
- const childColliderProps = useChildColliderProps(object, _objectSpread2(_objectSpread2({}, props), {}, {
1597
+ const childColliderProps = useChildColliderProps(objectRef, _objectSpread2(_objectSpread2({}, props), {}, {
1577
1598
  children: undefined
1578
1599
  }));
1579
1600
 
1580
1601
  const getInstancedMesh = () => {
1581
- const firstChild = instancedWrapper.current.children[0];
1602
+ const firstChild = instanceWrapperRef.current.children[0];
1582
1603
 
1583
1604
  if (firstChild && "isInstancedMesh" in firstChild) {
1584
1605
  return firstChild;
@@ -1618,16 +1639,16 @@ const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forward
1618
1639
  };
1619
1640
 
1620
1641
  return /*#__PURE__*/React__default["default"].createElement("object3D", _extends({
1621
- ref: object
1642
+ ref: objectRef
1622
1643
  }, rigidBodyProps, {
1623
1644
  position: position,
1624
1645
  rotation: rotation,
1625
1646
  quaternion: quaternion,
1626
1647
  scale: scale
1627
1648
  }), /*#__PURE__*/React__default["default"].createElement("object3D", {
1628
- ref: instancedWrapper
1649
+ ref: instanceWrapperRef
1629
1650
  }, children), instances === null || instances === void 0 ? void 0 : instances.map((instance, index) => /*#__PURE__*/React__default["default"].createElement(RigidBody, _extends({}, rigidBodyProps, instance, {
1630
- ref: body => rigidBodyApis.current[index] = body,
1651
+ ref: body => rigidBodiesRef.current[index] = body,
1631
1652
  transformState: state => applyInstancedState(state, index)
1632
1653
  }), /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, colliderNodes.map((node, index) => /*#__PURE__*/React__default["default"].createElement(React.Fragment, {
1633
1654
  key: index
@@ -1649,7 +1670,8 @@ const useImpulseJoint = (body1, body2, params) => {
1649
1670
  useImperativeInstance(() => {
1650
1671
  if (body1.current && body2.current) {
1651
1672
  const newJoint = world.createImpulseJoint(params, body1.current, body2.current);
1652
- jointRef.current = newJoint;
1673
+ jointRef.current = newJoint; // console.log(body1.current, body2.current, newJoint);
1674
+
1653
1675
  return newJoint;
1654
1676
  }
1655
1677
  }, joint => {
@@ -1657,7 +1679,7 @@ const useImpulseJoint = (body1, body2, params) => {
1657
1679
  jointRef.current = undefined;
1658
1680
  world.removeImpulseJoint(joint);
1659
1681
  }
1660
- });
1682
+ }, []);
1661
1683
  return jointRef;
1662
1684
  };
1663
1685
  /**
@@ -1792,7 +1814,9 @@ exports.InstancedRigidBodies = InstancedRigidBodies;
1792
1814
  exports.MeshCollider = MeshCollider;
1793
1815
  exports.Physics = Physics;
1794
1816
  exports.RigidBody = RigidBody;
1817
+ exports.RoundConeCollider = RoundConeCollider;
1795
1818
  exports.RoundCuboidCollider = RoundCuboidCollider;
1819
+ exports.RoundCylinderCollider = RoundCylinderCollider;
1796
1820
  exports.TrimeshCollider = TrimeshCollider;
1797
1821
  exports.euler = euler;
1798
1822
  exports.interactionGroups = interactionGroups;