@react-three/rapier 0.16.0-canary.0 → 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.
@@ -9,4 +9,4 @@ export interface InstancedRigidBodiesProps extends RigidBodyProps {
9
9
  colliderNodes?: ReactNode[];
10
10
  children: ReactNode;
11
11
  }
12
- export declare const InstancedRigidBodies: React.MemoExoticComponent<React.ForwardRefExoticComponent<InstancedRigidBodiesProps & React.RefAttributes<(RapierRigidBody | null)[]>>>;
12
+ export declare const InstancedRigidBodies: React.MemoExoticComponent<React.ForwardRefExoticComponent<InstancedRigidBodiesProps & React.RefAttributes<(RapierRigidBody | null)[] | null>>>;
@@ -0,0 +1,2 @@
1
+ import { ForwardedRef, MutableRefObject } from "react";
2
+ export declare const useForwardedRef: <T>(forwardedRef: ForwardedRef<T>, defaultValue?: T | null) => MutableRefObject<T>;
@@ -1119,6 +1119,20 @@ const euler = ({
1119
1119
  return new three.Euler(x, y, z);
1120
1120
  };
1121
1121
 
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
+
1122
1136
  /**
1123
1137
  * A collider is a shape that can be attached to a rigid body to define its physical properties.
1124
1138
  * @internal
@@ -1138,24 +1152,30 @@ const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((prop
1138
1152
  colliderStates
1139
1153
  } = useRapier();
1140
1154
  const rigidBodyContext = useRigidBodyContext();
1141
- const ref = React.useRef(null); // We spread the props out here to make sure that the ref is updated when the props change.
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.
1142
1157
 
1143
1158
  const immutablePropArray = immutableColliderOptions.flatMap(key => Array.isArray(props[key]) ? [...props[key]] : props[key]);
1144
1159
  const getInstance = useImperativeInstance(() => {
1145
- const worldScale = ref.current.getWorldScale(vec3());
1160
+ const worldScale = objectRef.current.getWorldScale(vec3());
1146
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;
1147
1168
  return collider;
1148
1169
  }, collider => {
1149
1170
  world.removeCollider(collider);
1150
1171
  }, [...immutablePropArray, rigidBodyContext]);
1151
1172
  React.useEffect(() => {
1152
1173
  const collider = getInstance();
1153
- 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));
1154
1175
  return () => {
1155
1176
  colliderStates.delete(collider.handle);
1156
1177
  };
1157
1178
  }, [getInstance]);
1158
- React.useImperativeHandle(forwardedRef, () => getInstance(), [getInstance]);
1159
1179
  const mergedProps = React.useMemo(() => {
1160
1180
  return _objectSpread2(_objectSpread2({}, cleanRigidBodyPropsForCollider(rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options)), props);
1161
1181
  }, [props, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options]);
@@ -1166,7 +1186,7 @@ const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((prop
1166
1186
  rotation: rotation,
1167
1187
  quaternion: quaternion,
1168
1188
  scale: scale,
1169
- ref: ref,
1189
+ ref: objectRef,
1170
1190
  name: name
1171
1191
  }, children);
1172
1192
  }));
@@ -1454,7 +1474,8 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
1454
1474
  } = props,
1455
1475
  objectProps = _objectWithoutProperties(props, _excluded$1);
1456
1476
 
1457
- const ref = React.useRef(null);
1477
+ const objectRef = React.useRef(null);
1478
+ const rigidBodyRef = useForwardedRef(forwardedRef);
1458
1479
  const {
1459
1480
  world,
1460
1481
  rigidBodyStates,
@@ -1469,11 +1490,17 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
1469
1490
  const immutablePropArray = immutableRigidBodyOptions.flatMap(key => {
1470
1491
  return Array.isArray(mergedOptions[key]) ? [...mergedOptions[key]] : mergedOptions[key];
1471
1492
  });
1472
- const childColliderProps = useChildColliderProps(ref, mergedOptions); // Provide a way to eagerly create rigidbody
1493
+ const childColliderProps = useChildColliderProps(objectRef, mergedOptions); // Provide a way to eagerly create rigidbody
1473
1494
 
1474
1495
  const getRigidBody = useImperativeInstance(() => {
1475
1496
  const desc = rigidBodyDescFromOptions(mergedOptions);
1476
1497
  const rigidBody = world.createRigidBody(desc);
1498
+
1499
+ if (typeof forwardedRef === "function") {
1500
+ forwardedRef(rigidBody);
1501
+ }
1502
+
1503
+ rigidBodyRef.current = rigidBody;
1477
1504
  return rigidBody;
1478
1505
  }, rigidBody => {
1479
1506
  world.removeRigidBody(rigidBody);
@@ -1483,7 +1510,7 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
1483
1510
  const rigidBody = getRigidBody();
1484
1511
  const state = createRigidBodyState({
1485
1512
  rigidBody,
1486
- object: ref.current
1513
+ object: objectRef.current
1487
1514
  });
1488
1515
  rigidBodyStates.set(rigidBody.handle, props.transformState ? props.transformState(state) : state);
1489
1516
  return () => {
@@ -1492,10 +1519,9 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
1492
1519
  }, [getRigidBody]);
1493
1520
  useUpdateRigidBodyOptions(getRigidBody, mergedOptions, rigidBodyStates);
1494
1521
  useRigidBodyEvents(getRigidBody, mergedOptions, rigidBodyEvents);
1495
- React.useImperativeHandle(forwardedRef, () => getRigidBody(), [getRigidBody]);
1496
1522
  const contextValue = React.useMemo(() => {
1497
1523
  return {
1498
- ref,
1524
+ ref: objectRef,
1499
1525
  getRigidBody: getRigidBody,
1500
1526
  options: mergedOptions
1501
1527
  };
@@ -1503,7 +1529,7 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
1503
1529
  return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
1504
1530
  value: contextValue
1505
1531
  }, /*#__PURE__*/React__default["default"].createElement("object3D", _extends({
1506
- ref: ref
1532
+ ref: objectRef
1507
1533
  }, objectProps, {
1508
1534
  position: position,
1509
1535
  rotation: rotation,
@@ -1550,9 +1576,10 @@ const MeshCollider = /*#__PURE__*/React.memo(props => {
1550
1576
  MeshCollider.displayName = "MeshCollider";
1551
1577
 
1552
1578
  const _excluded = ["children", "instances", "colliderNodes", "position", "rotation", "quaternion", "scale"];
1553
- const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props, ref) => {
1554
- const object = React.useRef(null);
1555
- 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);
1556
1583
 
1557
1584
  const {
1558
1585
  // instanced props
@@ -1567,14 +1594,12 @@ const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forward
1567
1594
  } = props,
1568
1595
  rigidBodyProps = _objectWithoutProperties(props, _excluded);
1569
1596
 
1570
- const rigidBodyApis = React.useRef([]);
1571
- React.useImperativeHandle(ref, () => rigidBodyApis.current, [instances]);
1572
- const childColliderProps = useChildColliderProps(object, _objectSpread2(_objectSpread2({}, props), {}, {
1597
+ const childColliderProps = useChildColliderProps(objectRef, _objectSpread2(_objectSpread2({}, props), {}, {
1573
1598
  children: undefined
1574
1599
  }));
1575
1600
 
1576
1601
  const getInstancedMesh = () => {
1577
- const firstChild = instancedWrapper.current.children[0];
1602
+ const firstChild = instanceWrapperRef.current.children[0];
1578
1603
 
1579
1604
  if (firstChild && "isInstancedMesh" in firstChild) {
1580
1605
  return firstChild;
@@ -1614,16 +1639,16 @@ const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forward
1614
1639
  };
1615
1640
 
1616
1641
  return /*#__PURE__*/React__default["default"].createElement("object3D", _extends({
1617
- ref: object
1642
+ ref: objectRef
1618
1643
  }, rigidBodyProps, {
1619
1644
  position: position,
1620
1645
  rotation: rotation,
1621
1646
  quaternion: quaternion,
1622
1647
  scale: scale
1623
1648
  }), /*#__PURE__*/React__default["default"].createElement("object3D", {
1624
- ref: instancedWrapper
1649
+ ref: instanceWrapperRef
1625
1650
  }, children), instances === null || instances === void 0 ? void 0 : instances.map((instance, index) => /*#__PURE__*/React__default["default"].createElement(RigidBody, _extends({}, rigidBodyProps, instance, {
1626
- ref: body => rigidBodyApis.current[index] = body,
1651
+ ref: body => rigidBodiesRef.current[index] = body,
1627
1652
  transformState: state => applyInstancedState(state, index)
1628
1653
  }), /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, colliderNodes.map((node, index) => /*#__PURE__*/React__default["default"].createElement(React.Fragment, {
1629
1654
  key: index
@@ -1645,7 +1670,8 @@ const useImpulseJoint = (body1, body2, params) => {
1645
1670
  useImperativeInstance(() => {
1646
1671
  if (body1.current && body2.current) {
1647
1672
  const newJoint = world.createImpulseJoint(params, body1.current, body2.current);
1648
- jointRef.current = newJoint;
1673
+ jointRef.current = newJoint; // console.log(body1.current, body2.current, newJoint);
1674
+
1649
1675
  return newJoint;
1650
1676
  }
1651
1677
  }, joint => {
@@ -1119,6 +1119,20 @@ const euler = ({
1119
1119
  return new three.Euler(x, y, z);
1120
1120
  };
1121
1121
 
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
+
1122
1136
  /**
1123
1137
  * A collider is a shape that can be attached to a rigid body to define its physical properties.
1124
1138
  * @internal
@@ -1138,24 +1152,30 @@ const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((prop
1138
1152
  colliderStates
1139
1153
  } = useRapier();
1140
1154
  const rigidBodyContext = useRigidBodyContext();
1141
- const ref = React.useRef(null); // We spread the props out here to make sure that the ref is updated when the props change.
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.
1142
1157
 
1143
1158
  const immutablePropArray = immutableColliderOptions.flatMap(key => Array.isArray(props[key]) ? [...props[key]] : props[key]);
1144
1159
  const getInstance = useImperativeInstance(() => {
1145
- const worldScale = ref.current.getWorldScale(vec3());
1160
+ const worldScale = objectRef.current.getWorldScale(vec3());
1146
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;
1147
1168
  return collider;
1148
1169
  }, collider => {
1149
1170
  world.removeCollider(collider);
1150
1171
  }, [...immutablePropArray, rigidBodyContext]);
1151
1172
  React.useEffect(() => {
1152
1173
  const collider = getInstance();
1153
- 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));
1154
1175
  return () => {
1155
1176
  colliderStates.delete(collider.handle);
1156
1177
  };
1157
1178
  }, [getInstance]);
1158
- React.useImperativeHandle(forwardedRef, () => getInstance(), [getInstance]);
1159
1179
  const mergedProps = React.useMemo(() => {
1160
1180
  return _objectSpread2(_objectSpread2({}, cleanRigidBodyPropsForCollider(rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options)), props);
1161
1181
  }, [props, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options]);
@@ -1166,7 +1186,7 @@ const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((prop
1166
1186
  rotation: rotation,
1167
1187
  quaternion: quaternion,
1168
1188
  scale: scale,
1169
- ref: ref,
1189
+ ref: objectRef,
1170
1190
  name: name
1171
1191
  }, children);
1172
1192
  }));
@@ -1454,7 +1474,8 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
1454
1474
  } = props,
1455
1475
  objectProps = _objectWithoutProperties(props, _excluded$1);
1456
1476
 
1457
- const ref = React.useRef(null);
1477
+ const objectRef = React.useRef(null);
1478
+ const rigidBodyRef = useForwardedRef(forwardedRef);
1458
1479
  const {
1459
1480
  world,
1460
1481
  rigidBodyStates,
@@ -1469,11 +1490,17 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
1469
1490
  const immutablePropArray = immutableRigidBodyOptions.flatMap(key => {
1470
1491
  return Array.isArray(mergedOptions[key]) ? [...mergedOptions[key]] : mergedOptions[key];
1471
1492
  });
1472
- const childColliderProps = useChildColliderProps(ref, mergedOptions); // Provide a way to eagerly create rigidbody
1493
+ const childColliderProps = useChildColliderProps(objectRef, mergedOptions); // Provide a way to eagerly create rigidbody
1473
1494
 
1474
1495
  const getRigidBody = useImperativeInstance(() => {
1475
1496
  const desc = rigidBodyDescFromOptions(mergedOptions);
1476
1497
  const rigidBody = world.createRigidBody(desc);
1498
+
1499
+ if (typeof forwardedRef === "function") {
1500
+ forwardedRef(rigidBody);
1501
+ }
1502
+
1503
+ rigidBodyRef.current = rigidBody;
1477
1504
  return rigidBody;
1478
1505
  }, rigidBody => {
1479
1506
  world.removeRigidBody(rigidBody);
@@ -1483,7 +1510,7 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
1483
1510
  const rigidBody = getRigidBody();
1484
1511
  const state = createRigidBodyState({
1485
1512
  rigidBody,
1486
- object: ref.current
1513
+ object: objectRef.current
1487
1514
  });
1488
1515
  rigidBodyStates.set(rigidBody.handle, props.transformState ? props.transformState(state) : state);
1489
1516
  return () => {
@@ -1492,10 +1519,9 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
1492
1519
  }, [getRigidBody]);
1493
1520
  useUpdateRigidBodyOptions(getRigidBody, mergedOptions, rigidBodyStates);
1494
1521
  useRigidBodyEvents(getRigidBody, mergedOptions, rigidBodyEvents);
1495
- React.useImperativeHandle(forwardedRef, () => getRigidBody(), [getRigidBody]);
1496
1522
  const contextValue = React.useMemo(() => {
1497
1523
  return {
1498
- ref,
1524
+ ref: objectRef,
1499
1525
  getRigidBody: getRigidBody,
1500
1526
  options: mergedOptions
1501
1527
  };
@@ -1503,7 +1529,7 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
1503
1529
  return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
1504
1530
  value: contextValue
1505
1531
  }, /*#__PURE__*/React__default["default"].createElement("object3D", _extends({
1506
- ref: ref
1532
+ ref: objectRef
1507
1533
  }, objectProps, {
1508
1534
  position: position,
1509
1535
  rotation: rotation,
@@ -1550,9 +1576,10 @@ const MeshCollider = /*#__PURE__*/React.memo(props => {
1550
1576
  MeshCollider.displayName = "MeshCollider";
1551
1577
 
1552
1578
  const _excluded = ["children", "instances", "colliderNodes", "position", "rotation", "quaternion", "scale"];
1553
- const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props, ref) => {
1554
- const object = React.useRef(null);
1555
- 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);
1556
1583
 
1557
1584
  const {
1558
1585
  // instanced props
@@ -1567,14 +1594,12 @@ const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forward
1567
1594
  } = props,
1568
1595
  rigidBodyProps = _objectWithoutProperties(props, _excluded);
1569
1596
 
1570
- const rigidBodyApis = React.useRef([]);
1571
- React.useImperativeHandle(ref, () => rigidBodyApis.current, [instances]);
1572
- const childColliderProps = useChildColliderProps(object, _objectSpread2(_objectSpread2({}, props), {}, {
1597
+ const childColliderProps = useChildColliderProps(objectRef, _objectSpread2(_objectSpread2({}, props), {}, {
1573
1598
  children: undefined
1574
1599
  }));
1575
1600
 
1576
1601
  const getInstancedMesh = () => {
1577
- const firstChild = instancedWrapper.current.children[0];
1602
+ const firstChild = instanceWrapperRef.current.children[0];
1578
1603
 
1579
1604
  if (firstChild && "isInstancedMesh" in firstChild) {
1580
1605
  return firstChild;
@@ -1614,16 +1639,16 @@ const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forward
1614
1639
  };
1615
1640
 
1616
1641
  return /*#__PURE__*/React__default["default"].createElement("object3D", _extends({
1617
- ref: object
1642
+ ref: objectRef
1618
1643
  }, rigidBodyProps, {
1619
1644
  position: position,
1620
1645
  rotation: rotation,
1621
1646
  quaternion: quaternion,
1622
1647
  scale: scale
1623
1648
  }), /*#__PURE__*/React__default["default"].createElement("object3D", {
1624
- ref: instancedWrapper
1649
+ ref: instanceWrapperRef
1625
1650
  }, children), instances === null || instances === void 0 ? void 0 : instances.map((instance, index) => /*#__PURE__*/React__default["default"].createElement(RigidBody, _extends({}, rigidBodyProps, instance, {
1626
- ref: body => rigidBodyApis.current[index] = body,
1651
+ ref: body => rigidBodiesRef.current[index] = body,
1627
1652
  transformState: state => applyInstancedState(state, index)
1628
1653
  }), /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, colliderNodes.map((node, index) => /*#__PURE__*/React__default["default"].createElement(React.Fragment, {
1629
1654
  key: index
@@ -1645,7 +1670,8 @@ const useImpulseJoint = (body1, body2, params) => {
1645
1670
  useImperativeInstance(() => {
1646
1671
  if (body1.current && body2.current) {
1647
1672
  const newJoint = world.createImpulseJoint(params, body1.current, body2.current);
1648
- jointRef.current = newJoint;
1673
+ jointRef.current = newJoint; // console.log(body1.current, body2.current, newJoint);
1674
+
1649
1675
  return newJoint;
1650
1676
  }
1651
1677
  }, joint => {
@@ -1,7 +1,7 @@
1
1
  import { ActiveEvents, ColliderDesc, EventQueue, RigidBodyDesc } from '@dimforge/rapier3d-compat';
2
2
  export { CoefficientCombineRule, Collider as RapierCollider, RigidBody as RapierRigidBody } from '@dimforge/rapier3d-compat';
3
3
  import { useFrame, useThree } from '@react-three/fiber';
4
- import React, { useRef, useEffect, memo, useMemo, useContext, useState, useCallback, createContext, forwardRef, useImperativeHandle, Fragment } from 'react';
4
+ import React, { useRef, useEffect, memo, useMemo, useContext, useState, useCallback, createContext, forwardRef, Fragment } from 'react';
5
5
  import { Quaternion, Euler, Vector3, Object3D, Matrix4, BufferAttribute, MathUtils, DynamicDrawUsage } from 'three';
6
6
  import { useAsset } from 'use-asset';
7
7
  import { mergeVertices } from 'three-stdlib';
@@ -1094,6 +1094,20 @@ const euler = ({
1094
1094
  return new Euler(x, y, z);
1095
1095
  };
1096
1096
 
1097
+ const useForwardedRef = (forwardedRef, defaultValue = null) => {
1098
+ const innerRef = useRef(defaultValue); // Update the forwarded ref when the inner ref changes
1099
+
1100
+ if (forwardedRef && typeof forwardedRef !== "function") {
1101
+ if (!forwardedRef.current) {
1102
+ forwardedRef.current = innerRef.current;
1103
+ }
1104
+
1105
+ return forwardedRef;
1106
+ }
1107
+
1108
+ return innerRef;
1109
+ };
1110
+
1097
1111
  /**
1098
1112
  * A collider is a shape that can be attached to a rigid body to define its physical properties.
1099
1113
  * @internal
@@ -1113,24 +1127,30 @@ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwarded
1113
1127
  colliderStates
1114
1128
  } = useRapier();
1115
1129
  const rigidBodyContext = useRigidBodyContext();
1116
- const ref = useRef(null); // We spread the props out here to make sure that the ref is updated when the props change.
1130
+ const colliderRef = useForwardedRef(forwardedRef);
1131
+ const objectRef = useRef(null); // We spread the props out here to make sure that the ref is updated when the props change.
1117
1132
 
1118
1133
  const immutablePropArray = immutableColliderOptions.flatMap(key => Array.isArray(props[key]) ? [...props[key]] : props[key]);
1119
1134
  const getInstance = useImperativeInstance(() => {
1120
- const worldScale = ref.current.getWorldScale(vec3());
1135
+ const worldScale = objectRef.current.getWorldScale(vec3());
1121
1136
  const collider = createColliderFromOptions(props, world, worldScale, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.getRigidBody);
1137
+
1138
+ if (typeof forwardedRef == "function") {
1139
+ forwardedRef(collider);
1140
+ }
1141
+
1142
+ colliderRef.current = collider;
1122
1143
  return collider;
1123
1144
  }, collider => {
1124
1145
  world.removeCollider(collider);
1125
1146
  }, [...immutablePropArray, rigidBodyContext]);
1126
1147
  useEffect(() => {
1127
1148
  const collider = getInstance();
1128
- colliderStates.set(collider.handle, createColliderState(collider, ref.current, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
1149
+ colliderStates.set(collider.handle, createColliderState(collider, objectRef.current, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
1129
1150
  return () => {
1130
1151
  colliderStates.delete(collider.handle);
1131
1152
  };
1132
1153
  }, [getInstance]);
1133
- useImperativeHandle(forwardedRef, () => getInstance(), [getInstance]);
1134
1154
  const mergedProps = useMemo(() => {
1135
1155
  return _objectSpread2(_objectSpread2({}, cleanRigidBodyPropsForCollider(rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options)), props);
1136
1156
  }, [props, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options]);
@@ -1141,7 +1161,7 @@ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwarded
1141
1161
  rotation: rotation,
1142
1162
  quaternion: quaternion,
1143
1163
  scale: scale,
1144
- ref: ref,
1164
+ ref: objectRef,
1145
1165
  name: name
1146
1166
  }, children);
1147
1167
  }));
@@ -1429,7 +1449,8 @@ const RigidBody = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwardedRe
1429
1449
  } = props,
1430
1450
  objectProps = _objectWithoutProperties(props, _excluded$1);
1431
1451
 
1432
- const ref = useRef(null);
1452
+ const objectRef = useRef(null);
1453
+ const rigidBodyRef = useForwardedRef(forwardedRef);
1433
1454
  const {
1434
1455
  world,
1435
1456
  rigidBodyStates,
@@ -1444,11 +1465,17 @@ const RigidBody = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwardedRe
1444
1465
  const immutablePropArray = immutableRigidBodyOptions.flatMap(key => {
1445
1466
  return Array.isArray(mergedOptions[key]) ? [...mergedOptions[key]] : mergedOptions[key];
1446
1467
  });
1447
- const childColliderProps = useChildColliderProps(ref, mergedOptions); // Provide a way to eagerly create rigidbody
1468
+ const childColliderProps = useChildColliderProps(objectRef, mergedOptions); // Provide a way to eagerly create rigidbody
1448
1469
 
1449
1470
  const getRigidBody = useImperativeInstance(() => {
1450
1471
  const desc = rigidBodyDescFromOptions(mergedOptions);
1451
1472
  const rigidBody = world.createRigidBody(desc);
1473
+
1474
+ if (typeof forwardedRef === "function") {
1475
+ forwardedRef(rigidBody);
1476
+ }
1477
+
1478
+ rigidBodyRef.current = rigidBody;
1452
1479
  return rigidBody;
1453
1480
  }, rigidBody => {
1454
1481
  world.removeRigidBody(rigidBody);
@@ -1458,7 +1485,7 @@ const RigidBody = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwardedRe
1458
1485
  const rigidBody = getRigidBody();
1459
1486
  const state = createRigidBodyState({
1460
1487
  rigidBody,
1461
- object: ref.current
1488
+ object: objectRef.current
1462
1489
  });
1463
1490
  rigidBodyStates.set(rigidBody.handle, props.transformState ? props.transformState(state) : state);
1464
1491
  return () => {
@@ -1467,10 +1494,9 @@ const RigidBody = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwardedRe
1467
1494
  }, [getRigidBody]);
1468
1495
  useUpdateRigidBodyOptions(getRigidBody, mergedOptions, rigidBodyStates);
1469
1496
  useRigidBodyEvents(getRigidBody, mergedOptions, rigidBodyEvents);
1470
- useImperativeHandle(forwardedRef, () => getRigidBody(), [getRigidBody]);
1471
1497
  const contextValue = useMemo(() => {
1472
1498
  return {
1473
- ref,
1499
+ ref: objectRef,
1474
1500
  getRigidBody: getRigidBody,
1475
1501
  options: mergedOptions
1476
1502
  };
@@ -1478,7 +1504,7 @@ const RigidBody = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwardedRe
1478
1504
  return /*#__PURE__*/React.createElement(RigidBodyContext.Provider, {
1479
1505
  value: contextValue
1480
1506
  }, /*#__PURE__*/React.createElement("object3D", _extends({
1481
- ref: ref
1507
+ ref: objectRef
1482
1508
  }, objectProps, {
1483
1509
  position: position,
1484
1510
  rotation: rotation,
@@ -1525,9 +1551,10 @@ const MeshCollider = /*#__PURE__*/memo(props => {
1525
1551
  MeshCollider.displayName = "MeshCollider";
1526
1552
 
1527
1553
  const _excluded = ["children", "instances", "colliderNodes", "position", "rotation", "quaternion", "scale"];
1528
- const InstancedRigidBodies = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, ref) => {
1529
- const object = useRef(null);
1530
- const instancedWrapper = useRef(null);
1554
+ const InstancedRigidBodies = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwardedRef) => {
1555
+ const rigidBodiesRef = useForwardedRef(forwardedRef, []);
1556
+ const objectRef = useRef(null);
1557
+ const instanceWrapperRef = useRef(null);
1531
1558
 
1532
1559
  const {
1533
1560
  // instanced props
@@ -1542,14 +1569,12 @@ const InstancedRigidBodies = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props,
1542
1569
  } = props,
1543
1570
  rigidBodyProps = _objectWithoutProperties(props, _excluded);
1544
1571
 
1545
- const rigidBodyApis = useRef([]);
1546
- useImperativeHandle(ref, () => rigidBodyApis.current, [instances]);
1547
- const childColliderProps = useChildColliderProps(object, _objectSpread2(_objectSpread2({}, props), {}, {
1572
+ const childColliderProps = useChildColliderProps(objectRef, _objectSpread2(_objectSpread2({}, props), {}, {
1548
1573
  children: undefined
1549
1574
  }));
1550
1575
 
1551
1576
  const getInstancedMesh = () => {
1552
- const firstChild = instancedWrapper.current.children[0];
1577
+ const firstChild = instanceWrapperRef.current.children[0];
1553
1578
 
1554
1579
  if (firstChild && "isInstancedMesh" in firstChild) {
1555
1580
  return firstChild;
@@ -1589,16 +1614,16 @@ const InstancedRigidBodies = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props,
1589
1614
  };
1590
1615
 
1591
1616
  return /*#__PURE__*/React.createElement("object3D", _extends({
1592
- ref: object
1617
+ ref: objectRef
1593
1618
  }, rigidBodyProps, {
1594
1619
  position: position,
1595
1620
  rotation: rotation,
1596
1621
  quaternion: quaternion,
1597
1622
  scale: scale
1598
1623
  }), /*#__PURE__*/React.createElement("object3D", {
1599
- ref: instancedWrapper
1624
+ ref: instanceWrapperRef
1600
1625
  }, children), instances === null || instances === void 0 ? void 0 : instances.map((instance, index) => /*#__PURE__*/React.createElement(RigidBody, _extends({}, rigidBodyProps, instance, {
1601
- ref: body => rigidBodyApis.current[index] = body,
1626
+ ref: body => rigidBodiesRef.current[index] = body,
1602
1627
  transformState: state => applyInstancedState(state, index)
1603
1628
  }), /*#__PURE__*/React.createElement(React.Fragment, null, colliderNodes.map((node, index) => /*#__PURE__*/React.createElement(Fragment, {
1604
1629
  key: index
@@ -1620,7 +1645,8 @@ const useImpulseJoint = (body1, body2, params) => {
1620
1645
  useImperativeInstance(() => {
1621
1646
  if (body1.current && body2.current) {
1622
1647
  const newJoint = world.createImpulseJoint(params, body1.current, body2.current);
1623
- jointRef.current = newJoint;
1648
+ jointRef.current = newJoint; // console.log(body1.current, body2.current, newJoint);
1649
+
1624
1650
  return newJoint;
1625
1651
  }
1626
1652
  }, joint => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-three/rapier",
3
- "version": "0.16.0-canary.0",
3
+ "version": "0.16.0-canary.1",
4
4
  "source": "src/index.ts",
5
5
  "main": "dist/react-three-rapier.cjs.js",
6
6
  "module": "dist/react-three-rapier.esm.js",