@react-three/rapier 0.11.3 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import { ColliderDesc, ActiveEvents, RigidBodyDesc, EventQueue } 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, useMemo, useEffect, useContext, useState, memo, createContext, useCallback, forwardRef, useImperativeHandle, useLayoutEffect } from 'react';
4
+ import React$1, { useRef, useMemo, useEffect, useContext, useState, memo, createContext, useCallback, forwardRef, useImperativeHandle, useLayoutEffect } from 'react';
5
5
  import { Quaternion, Euler, Vector3, Object3D, Matrix4, MathUtils, InstancedMesh, BufferAttribute, DynamicDrawUsage } from 'three';
6
6
  import { useAsset } from 'use-asset';
7
7
  import { mergeVertices, VertexNormalsHelper } from 'three-stdlib';
@@ -223,7 +223,7 @@ const createInstancedRigidBodiesApi = bodiesGetter => ({
223
223
  return bodiesGetter.current().length;
224
224
  }
225
225
 
226
- }); // TODO: Flesh this out
226
+ });
227
227
  const createWorldApi = ref => {
228
228
  return {
229
229
  raw: () => ref.current(),
@@ -256,8 +256,7 @@ const createWorldApi = ref => {
256
256
  },
257
257
  debugRender: () => ref.current().debugRender()
258
258
  };
259
- }; // TODO: Broken currently, waiting for Rapier3D to fix
260
-
259
+ };
261
260
  const createJointApi = ref => {
262
261
  return {
263
262
  raw: () => ref.current(),
@@ -731,8 +730,31 @@ const useRigidBodyEvents = (rigidBodyRef, props, events) => {
731
730
  };
732
731
 
733
732
  const useRapier = () => {
734
- return useContext(RapierContext);
733
+ return useContext(rapierContext);
734
+ };
735
+ const useBeforePhysicsStep = callback => {
736
+ const {
737
+ beforeStepCallbacks
738
+ } = useRapier();
739
+ useEffect(() => {
740
+ beforeStepCallbacks.add(callback);
741
+ return () => {
742
+ beforeStepCallbacks.delete(callback);
743
+ };
744
+ }, []);
735
745
  };
746
+ const useAfterPhysicsStep = callback => {
747
+ const {
748
+ afterStepCallbacks
749
+ } = useRapier();
750
+ useEffect(() => {
751
+ afterStepCallbacks.add(callback);
752
+ return () => {
753
+ afterStepCallbacks.delete(callback);
754
+ };
755
+ }, []);
756
+ }; // Internal hooks
757
+
736
758
  const useChildColliderProps = (ref, options, ignoreMeshColliders = true) => {
737
759
  const [colliderProps, setColliderProps] = useState([]);
738
760
  useEffect(() => {
@@ -796,103 +818,6 @@ const useRigidBody = (options = {}) => {
796
818
  useRigidBodyEvents(rigidBodyRef, mergedOptions, rigidBodyEvents);
797
819
  const api = useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
798
820
  return [ref, api, childColliderProps];
799
- }; // Joints
800
-
801
- const useImpulseJoint = (body1, body2, params) => {
802
- const {
803
- world
804
- } = useRapier();
805
- const jointRef = useRef();
806
- const getJointRef = useRef(() => {
807
- if (!jointRef.current) {
808
- let rb1;
809
- let rb2;
810
-
811
- if ("current" in body1 && body1.current && "current" in body2 && body2.current) {
812
- rb1 = world.getRigidBody(body1.current.handle);
813
- rb2 = world.getRigidBody(body2.current.handle);
814
- const newJoint = world.createImpulseJoint(params, rb1, rb2);
815
- jointRef.current = newJoint;
816
- }
817
- }
818
-
819
- return jointRef.current;
820
- });
821
- useEffect(() => {
822
- const joint = getJointRef.current();
823
- return () => {
824
- if (joint) {
825
- world.removeImpulseJoint(joint);
826
- jointRef.current = undefined;
827
- }
828
- };
829
- }, []);
830
- const api = useMemo(() => createJointApi(getJointRef), []);
831
- return api;
832
- };
833
- /**
834
- *
835
- * A fixed joint ensures that two rigid-bodies don't move relative to each other.
836
- * Fixed joints are characterized by one local frame (represented by an isometry) on each rigid-body.
837
- * The fixed-joint makes these frames coincide in world-space.
838
- */
839
-
840
- const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor, body2LocalFrame]) => {
841
- const {
842
- rapier
843
- } = useRapier();
844
- return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToVector3(body1Anchor), tupleToObject(body1LocalFrame, ["x", "y", "z", "w"]), vectorArrayToVector3(body2Anchor), tupleToObject(body2LocalFrame, ["x", "y", "z", "w"])));
845
- };
846
- /**
847
- * The spherical joint ensures that two points on the local-spaces of two rigid-bodies always coincide (it prevents any relative
848
- * translational motion at this points). This is typically used to simulate ragdolls arms, pendulums, etc.
849
- * They are characterized by one local anchor on each rigid-body. Each anchor represents the location of the
850
- * points that need to coincide on the local-space of each rigid-body.
851
- */
852
-
853
- const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
854
- const {
855
- rapier
856
- } = useRapier();
857
- return useImpulseJoint(body1, body2, rapier.JointData.spherical(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor)));
858
- };
859
- /**
860
- * The revolute joint prevents any relative movement between two rigid-bodies, except for relative
861
- * rotations along one axis. This is typically used to simulate wheels, fans, etc.
862
- * They are characterized by one local anchor as well as one local axis on each rigid-body.
863
- */
864
-
865
- const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis, limits]) => {
866
- const {
867
- rapier
868
- } = useRapier();
869
- const params = rapier.JointData.revolute(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis));
870
-
871
- if (limits) {
872
- params.limitsEnabled = true;
873
- params.limits = limits;
874
- }
875
-
876
- return useImpulseJoint(body1, body2, params);
877
- };
878
- /**
879
- * The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
880
- * It is characterized by one local anchor as well as one local axis on each rigid-body. In 3D, an optional
881
- * local tangent axis can be specified for each rigid-body.
882
- */
883
-
884
- const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis, limits]) => {
885
- const {
886
- rapier
887
- } = useRapier();
888
- const params = rapier.JointData.prismatic(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis));
889
-
890
- if (limits) {
891
- params.limitsEnabled = true;
892
- params.limits = limits;
893
- }
894
-
895
- return useImpulseJoint(body1, body2, params);
896
821
  };
897
822
 
898
823
  const calcForceByType = {
@@ -974,13 +899,13 @@ const Attractor = /*#__PURE__*/memo(props => {
974
899
  attractorStates.delete(uuid);
975
900
  };
976
901
  }, [props]);
977
- return /*#__PURE__*/React.createElement("object3D", {
902
+ return /*#__PURE__*/React$1.createElement("object3D", {
978
903
  ref: object,
979
904
  position: position
980
905
  });
981
906
  });
982
907
 
983
- const RapierContext = /*#__PURE__*/createContext(undefined);
908
+ const rapierContext = /*#__PURE__*/createContext(undefined);
984
909
 
985
910
  const getCollisionPayloadFromSource = (target, other) => {
986
911
  var _target$collider$stat, _target$rigidBody$sta, _other$collider$state, _other$rigidBody$stat, _other$collider$state2, _other$rigidBody$stat2;
@@ -1035,7 +960,9 @@ const Physics = ({
1035
960
  const rigidBodyEvents = useConst(() => new Map());
1036
961
  const colliderEvents = useConst(() => new Map());
1037
962
  const eventQueue = useConst(() => new EventQueue(false));
1038
- const attractorStates = useConst(() => new Map()); // Init world
963
+ const attractorStates = useConst(() => new Map());
964
+ const beforeStepCallbacks = useConst(() => new Set());
965
+ const afterStepCallbacks = useConst(() => new Set()); // Init world
1039
966
 
1040
967
  useEffect(() => {
1041
968
  const world = getWorldRef.current();
@@ -1054,6 +981,7 @@ const Physics = ({
1054
981
  world.gravity = vectorArrayToVector3(_gravity);
1055
982
  }
1056
983
  }, [_gravity]);
984
+ const api = useMemo(() => createWorldApi(getWorldRef), []);
1057
985
  const getSourceFromColliderHandle = useCallback(handle => {
1058
986
  const world = worldRef.current;
1059
987
 
@@ -1100,9 +1028,21 @@ const Physics = ({
1100
1028
 
1101
1029
  const clampedDelta = MathUtils.clamp(dt, 0, 0.2);
1102
1030
 
1031
+ const stepWorld = () => {
1032
+ // Trigger beforeStep callbacks
1033
+ beforeStepCallbacks.forEach(callback => {
1034
+ callback(api);
1035
+ });
1036
+ world.step(eventQueue); // Trigger afterStep callbacks
1037
+
1038
+ afterStepCallbacks.forEach(callback => {
1039
+ callback(api);
1040
+ });
1041
+ };
1042
+
1103
1043
  if (timeStepVariable) {
1104
1044
  world.timestep = clampedDelta;
1105
- world.step(eventQueue);
1045
+ stepWorld();
1106
1046
  } else {
1107
1047
  world.timestep = _timeStep; // don't step time forwards if paused
1108
1048
  // Increase accumulator
@@ -1126,7 +1066,7 @@ const Physics = ({
1126
1066
  applyAttractorForceOnRigidBody(body, attractorState);
1127
1067
  });
1128
1068
  });
1129
- world.step(eventQueue);
1069
+ stepWorld();
1130
1070
  steppingState.accumulator -= _timeStep;
1131
1071
  }
1132
1072
  }
@@ -1289,7 +1229,6 @@ const Physics = ({
1289
1229
  useFrame((_, dt) => {
1290
1230
  if (!_paused) step(dt);
1291
1231
  }, updatePriority);
1292
- const api = useMemo(() => createWorldApi(getWorldRef), []);
1293
1232
  const context = useMemo(() => ({
1294
1233
  rapier,
1295
1234
  world: api,
@@ -1302,10 +1241,12 @@ const Physics = ({
1302
1241
  rigidBodyEvents,
1303
1242
  colliderEvents,
1304
1243
  attractorStates,
1244
+ beforeStepCallbacks,
1245
+ afterStepCallbacks,
1305
1246
  isPaused: _paused,
1306
1247
  step
1307
1248
  }), [_paused, step]);
1308
- return /*#__PURE__*/React.createElement(RapierContext.Provider, {
1249
+ return /*#__PURE__*/React$1.createElement(rapierContext.Provider, {
1309
1250
  value: context
1310
1251
  }, children);
1311
1252
  };
@@ -1362,7 +1303,7 @@ function _objectWithoutProperties(source, excluded) {
1362
1303
  }
1363
1304
 
1364
1305
  // Colliders
1365
- const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/React.forwardRef((props, forwardedRef) => {
1306
+ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/React$1.forwardRef((props, forwardedRef) => {
1366
1307
  const {
1367
1308
  children,
1368
1309
  position,
@@ -1383,7 +1324,7 @@ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/React.forwardRef((props, for
1383
1324
  return forwardedRef;
1384
1325
  }
1385
1326
 
1386
- const result = /*#__PURE__*/React.createRef();
1327
+ const result = /*#__PURE__*/React$1.createRef();
1387
1328
  result.current = [];
1388
1329
  return result;
1389
1330
  }, []);
@@ -1424,7 +1365,7 @@ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/React.forwardRef((props, for
1424
1365
  }, [props, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options]);
1425
1366
  useUpdateColliderOptions(collidersRef, mergedProps, colliderStates);
1426
1367
  useColliderEvents(collidersRef, mergedProps, colliderEvents);
1427
- return /*#__PURE__*/React.createElement("object3D", {
1368
+ return /*#__PURE__*/React$1.createElement("object3D", {
1428
1369
  position: position,
1429
1370
  rotation: rotation,
1430
1371
  quaternion: quaternion,
@@ -1433,56 +1374,56 @@ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/React.forwardRef((props, for
1433
1374
  name: name
1434
1375
  }, children);
1435
1376
  }));
1436
- const CuboidCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1437
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1377
+ const CuboidCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1378
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1438
1379
  shape: "cuboid",
1439
1380
  ref: ref
1440
1381
  }));
1441
1382
  });
1442
- const RoundCuboidCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1443
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1383
+ const RoundCuboidCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1384
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1444
1385
  shape: "roundCuboid",
1445
1386
  ref: ref
1446
1387
  }));
1447
1388
  });
1448
- const BallCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1449
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1389
+ const BallCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1390
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1450
1391
  shape: "ball",
1451
1392
  ref: ref
1452
1393
  }));
1453
1394
  });
1454
- const CapsuleCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1455
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1395
+ const CapsuleCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1396
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1456
1397
  shape: "capsule",
1457
1398
  ref: ref
1458
1399
  }));
1459
1400
  });
1460
- const HeightfieldCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1461
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1401
+ const HeightfieldCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1402
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1462
1403
  shape: "heightfield",
1463
1404
  ref: ref
1464
1405
  }));
1465
1406
  });
1466
- const TrimeshCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1467
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1407
+ const TrimeshCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1408
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1468
1409
  shape: "trimesh",
1469
1410
  ref: ref
1470
1411
  }));
1471
1412
  });
1472
- const ConeCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1473
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1413
+ const ConeCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1414
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1474
1415
  shape: "cone",
1475
1416
  ref: ref
1476
1417
  }));
1477
1418
  });
1478
- const CylinderCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1479
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1419
+ const CylinderCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1420
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1480
1421
  shape: "cylinder",
1481
1422
  ref: ref
1482
1423
  }));
1483
1424
  });
1484
- const ConvexHullCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1485
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1425
+ const ConvexHullCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1426
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1486
1427
  shape: "convexHull",
1487
1428
  ref: ref
1488
1429
  }));
@@ -1518,22 +1459,22 @@ const RigidBody = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, ref) => {
1518
1459
  api,
1519
1460
  options: props
1520
1461
  }), [object, api, props]);
1521
- return /*#__PURE__*/React.createElement(RigidBodyContext.Provider, {
1462
+ return /*#__PURE__*/React$1.createElement(RigidBodyContext.Provider, {
1522
1463
  value: contextValue
1523
- }, /*#__PURE__*/React.createElement("object3D", _extends({
1464
+ }, /*#__PURE__*/React$1.createElement("object3D", _extends({
1524
1465
  ref: object
1525
1466
  }, objectProps, {
1526
1467
  position: position,
1527
1468
  rotation: rotation,
1528
1469
  quaternion: quaternion,
1529
1470
  scale: scale
1530
- }), children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React.createElement(AnyCollider, _extends({
1471
+ }), children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React$1.createElement(AnyCollider, _extends({
1531
1472
  key: index
1532
1473
  }, colliderProps)))));
1533
1474
  }));
1534
1475
  RigidBody.displayName = "RigidBody";
1535
1476
 
1536
- const MeshCollider = props => {
1477
+ const MeshCollider = /*#__PURE__*/memo(props => {
1537
1478
  const {
1538
1479
  children,
1539
1480
  type
@@ -1553,15 +1494,15 @@ const MeshCollider = props => {
1553
1494
  });
1554
1495
  }, [physicsOptions, options]);
1555
1496
  const childColliderProps = useChildColliderProps(object, mergedOptions, false);
1556
- return /*#__PURE__*/React.createElement("object3D", {
1497
+ return /*#__PURE__*/React$1.createElement("object3D", {
1557
1498
  ref: object,
1558
1499
  userData: {
1559
1500
  r3RapierType: "MeshCollider"
1560
1501
  }
1561
- }, children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React.createElement(AnyCollider, _extends({
1502
+ }, children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React$1.createElement(AnyCollider, _extends({
1562
1503
  key: index
1563
1504
  }, colliderProps))));
1564
- };
1505
+ });
1565
1506
  MeshCollider.displayName = "MeshCollider";
1566
1507
 
1567
1508
  function mapsEqual(map1, map2) {
@@ -1611,19 +1552,19 @@ const AttractorHelper = props => {
1611
1552
  (_normalsHelper$curren = normalsHelper.current) === null || _normalsHelper$curren === void 0 ? void 0 : _normalsHelper$curren.update();
1612
1553
  }
1613
1554
  });
1614
- return /*#__PURE__*/React.createElement("mesh", {
1555
+ return /*#__PURE__*/React$1.createElement("mesh", {
1615
1556
  ref: ref,
1616
1557
  position: props.object.position,
1617
1558
  frustumCulled: false
1618
- }, /*#__PURE__*/React.createElement("sphereGeometry", {
1559
+ }, /*#__PURE__*/React$1.createElement("sphereGeometry", {
1619
1560
  args: [0.2, 6, 6]
1620
- }), /*#__PURE__*/React.createElement("meshBasicMaterial", {
1561
+ }), /*#__PURE__*/React$1.createElement("meshBasicMaterial", {
1621
1562
  color: color,
1622
1563
  wireframe: true
1623
1564
  }));
1624
1565
  };
1625
1566
 
1626
- const Debug = () => {
1567
+ const Debug = /*#__PURE__*/memo(() => {
1627
1568
  const {
1628
1569
  world,
1629
1570
  attractorStates
@@ -1643,16 +1584,16 @@ const Debug = () => {
1643
1584
  currMap.current = new Map(attractorStates);
1644
1585
  }
1645
1586
  });
1646
- return /*#__PURE__*/React.createElement("group", null, /*#__PURE__*/React.createElement("lineSegments", {
1587
+ return /*#__PURE__*/React$1.createElement("group", null, /*#__PURE__*/React$1.createElement("lineSegments", {
1647
1588
  ref: ref,
1648
1589
  frustumCulled: false
1649
- }, /*#__PURE__*/React.createElement("lineBasicMaterial", {
1590
+ }, /*#__PURE__*/React$1.createElement("lineBasicMaterial", {
1650
1591
  color: 0xffffff,
1651
1592
  vertexColors: true
1652
- }), /*#__PURE__*/React.createElement("bufferGeometry", null)), attractors.map((attractor, i) => /*#__PURE__*/React.createElement(AttractorHelper, _extends({
1593
+ }), /*#__PURE__*/React$1.createElement("bufferGeometry", null)), attractors.map((attractor, i) => /*#__PURE__*/React$1.createElement(AttractorHelper, _extends({
1653
1594
  key: attractor.object.uuid
1654
1595
  }, attractor))));
1655
- };
1596
+ });
1656
1597
 
1657
1598
  const _excluded = ["positions", "rotations", "children"];
1658
1599
  const InstancedRigidBodies = /*#__PURE__*/forwardRef((props, ref) => {
@@ -1766,6 +1707,103 @@ const InstancedRigidBodies = /*#__PURE__*/forwardRef((props, ref) => {
1766
1707
  });
1767
1708
  InstancedRigidBodies.displayName = "InstancedRigidBodies";
1768
1709
 
1710
+ const useImpulseJoint = (body1, body2, params) => {
1711
+ const {
1712
+ world
1713
+ } = useRapier();
1714
+ const jointRef = useRef();
1715
+ const getJointRef = useRef(() => {
1716
+ if (!jointRef.current) {
1717
+ let rb1;
1718
+ let rb2;
1719
+
1720
+ if ("current" in body1 && body1.current && "current" in body2 && body2.current) {
1721
+ rb1 = world.getRigidBody(body1.current.handle);
1722
+ rb2 = world.getRigidBody(body2.current.handle);
1723
+ const newJoint = world.createImpulseJoint(params, rb1, rb2);
1724
+ jointRef.current = newJoint;
1725
+ }
1726
+ }
1727
+
1728
+ return jointRef.current;
1729
+ });
1730
+ useEffect(() => {
1731
+ const joint = getJointRef.current();
1732
+ return () => {
1733
+ if (joint) {
1734
+ world.removeImpulseJoint(joint);
1735
+ jointRef.current = undefined;
1736
+ }
1737
+ };
1738
+ }, []);
1739
+ const api = useMemo(() => createJointApi(getJointRef), []);
1740
+ return api;
1741
+ };
1742
+ /**
1743
+ *
1744
+ * A fixed joint ensures that two rigid-bodies don't move relative to each other.
1745
+ * Fixed joints are characterized by one local frame (represented by an isometry) on each rigid-body.
1746
+ * The fixed-joint makes these frames coincide in world-space.
1747
+ */
1748
+
1749
+ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor, body2LocalFrame]) => {
1750
+ const {
1751
+ rapier
1752
+ } = useRapier();
1753
+ return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToVector3(body1Anchor), tupleToObject(body1LocalFrame, ["x", "y", "z", "w"]), vectorArrayToVector3(body2Anchor), tupleToObject(body2LocalFrame, ["x", "y", "z", "w"])));
1754
+ };
1755
+ /**
1756
+ * The spherical joint ensures that two points on the local-spaces of two rigid-bodies always coincide (it prevents any relative
1757
+ * translational motion at this points). This is typically used to simulate ragdolls arms, pendulums, etc.
1758
+ * They are characterized by one local anchor on each rigid-body. Each anchor represents the location of the
1759
+ * points that need to coincide on the local-space of each rigid-body.
1760
+ */
1761
+
1762
+ const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
1763
+ const {
1764
+ rapier
1765
+ } = useRapier();
1766
+ return useImpulseJoint(body1, body2, rapier.JointData.spherical(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor)));
1767
+ };
1768
+ /**
1769
+ * The revolute joint prevents any relative movement between two rigid-bodies, except for relative
1770
+ * rotations along one axis. This is typically used to simulate wheels, fans, etc.
1771
+ * They are characterized by one local anchor as well as one local axis on each rigid-body.
1772
+ */
1773
+
1774
+ const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis, limits]) => {
1775
+ const {
1776
+ rapier
1777
+ } = useRapier();
1778
+ const params = rapier.JointData.revolute(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis));
1779
+
1780
+ if (limits) {
1781
+ params.limitsEnabled = true;
1782
+ params.limits = limits;
1783
+ }
1784
+
1785
+ return useImpulseJoint(body1, body2, params);
1786
+ };
1787
+ /**
1788
+ * The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
1789
+ * It is characterized by one local anchor as well as one local axis on each rigid-body. In 3D, an optional
1790
+ * local tangent axis can be specified for each rigid-body.
1791
+ */
1792
+
1793
+ const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis, limits]) => {
1794
+ const {
1795
+ rapier
1796
+ } = useRapier();
1797
+ const params = rapier.JointData.prismatic(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis));
1798
+
1799
+ if (limits) {
1800
+ params.limitsEnabled = true;
1801
+ params.limits = limits;
1802
+ }
1803
+
1804
+ return useImpulseJoint(body1, body2, params);
1805
+ };
1806
+
1769
1807
  /**
1770
1808
  * Calculates an InteractionGroup bitmask for use in the `collisionGroups` or `solverGroups`
1771
1809
  * properties of RigidBody or Collider components. The first argument represents a list of
@@ -1802,4 +1840,4 @@ const interactionGroups = (memberships, filters) => (bitmask(memberships) << 16)
1802
1840
 
1803
1841
  const bitmask = groups => [groups].flat().reduce((acc, layer) => acc | 1 << layer, 0);
1804
1842
 
1805
- export { AnyCollider, Attractor, BallCollider, CapsuleCollider, ConeCollider, ConvexHullCollider, CuboidCollider, CylinderCollider, Debug, HeightfieldCollider, InstancedRigidBodies, MeshCollider, Physics, RigidBody, RoundCuboidCollider, TrimeshCollider, interactionGroups, useChildColliderProps, useFixedJoint, useImpulseJoint, usePrismaticJoint, useRapier, useRevoluteJoint, useRigidBody, useSphericalJoint };
1843
+ export { AnyCollider, Attractor, BallCollider, CapsuleCollider, ConeCollider, ConvexHullCollider, CuboidCollider, CylinderCollider, Debug, HeightfieldCollider, InstancedRigidBodies, MeshCollider, Physics, RigidBody, RoundCuboidCollider, TrimeshCollider, interactionGroups, useAfterPhysicsStep, useBeforePhysicsStep, useFixedJoint, useImpulseJoint, usePrismaticJoint, useRapier, useRevoluteJoint, useSphericalJoint };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-three/rapier",
3
- "version": "0.11.3",
3
+ "version": "0.12.0",
4
4
  "source": "src/index.ts",
5
5
  "main": "dist/react-three-rapier.cjs.js",
6
6
  "module": "dist/react-three-rapier.esm.js",