@react-three/rapier 0.2.0 → 0.3.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @react-three/rapier
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 7e36172: Add collision and sleep/awake events
8
+
3
9
  ## 0.2.0
4
10
 
5
11
  ### Minor Changes
@@ -1,7 +1,7 @@
1
1
  import React, { FC, ReactNode } from "react";
2
2
  import type Rapier from "@dimforge/rapier3d-compat";
3
3
  import { RigidBodyAutoCollider, Vector3Array, WorldApi } from "./types";
4
- import { ColliderHandle } from "@dimforge/rapier3d-compat";
4
+ import { ColliderHandle, RigidBody, RigidBodyHandle, TempContactManifold } from "@dimforge/rapier3d-compat";
5
5
  import { Object3D } from "three";
6
6
  export interface RapierContext {
7
7
  rapier: typeof Rapier;
@@ -11,8 +11,21 @@ export interface RapierContext {
11
11
  physicsOptions: {
12
12
  colliders: RigidBodyAutoCollider;
13
13
  };
14
+ rigidBodyEvents: EventMap;
14
15
  }
15
16
  export declare const RapierContext: React.Context<RapierContext | undefined>;
17
+ declare type EventMap = Map<ColliderHandle | RigidBodyHandle, {
18
+ onSleep?(): void;
19
+ onWake?(): void;
20
+ onCollisionEnter?({ target, manifold, flipped }: {
21
+ target: RigidBody;
22
+ manifold: TempContactManifold;
23
+ flipped: boolean;
24
+ }): void;
25
+ onCollisionExit?({ target }: {
26
+ target: RigidBody;
27
+ }): void;
28
+ }>;
16
29
  interface RapierWorldProps {
17
30
  gravity?: Vector3Array;
18
31
  colliders?: RigidBodyAutoCollider;
@@ -1,10 +1,9 @@
1
1
  import React from "react";
2
2
  import { ReactNode } from "react";
3
3
  import { Vector3 } from "three";
4
- import { BallArgs, CapsuleArgs, ConeArgs, ConvexHullArgs, CuboidArgs, CylinderArgs, HeightfieldArgs, RigidBodyAutoCollider, RoundCuboidArgs, TrimeshArgs, UseColliderOptions, UseRigidBodyOptions } from "./types";
4
+ import { BallArgs, CapsuleArgs, ConeArgs, ConvexHullArgs, CuboidArgs, CylinderArgs, HeightfieldArgs, RoundCuboidArgs, TrimeshArgs, UseColliderOptions, UseRigidBodyOptions } from "./types";
5
5
  interface RigidBodyProps extends UseRigidBodyOptions {
6
6
  children?: ReactNode;
7
- colliders?: RigidBodyAutoCollider | false;
8
7
  }
9
8
  export declare const RigidBody: React.ForwardRefExoticComponent<RigidBodyProps & React.RefAttributes<{
10
9
  raw: () => import("@dimforge/rapier3d-compat/dynamics/rigid_body").RigidBody | undefined;
@@ -1,5 +1,5 @@
1
1
  import { MutableRefObject } from "react";
2
- import { CoefficientCombineRule, RigidBody as RapierRigidBody, Collider as RapierCollider } from "@dimforge/rapier3d-compat";
2
+ import { CoefficientCombineRule, RigidBody as RapierRigidBody, Collider as RapierCollider, TempContactManifold } from "@dimforge/rapier3d-compat";
3
3
  import { createColliderApi, createJointApi, createRigidBodyApi, createWorldApi } from "./api";
4
4
  export { RapierRigidBody, RapierCollider };
5
5
  export { CoefficientCombineRule as CoefficientCombineRule, } from "@dimforge/rapier3d-compat";
@@ -162,6 +162,22 @@ export interface UseRigidBodyOptions {
162
162
  * Setting this to false will disable automatic colliders.
163
163
  */
164
164
  colliders?: RigidBodyAutoCollider | false;
165
+ /**
166
+ * Callback when this rigidbody collides with another rigidbody
167
+ */
168
+ onCollisionEnter?({}: {
169
+ target: RapierRigidBody;
170
+ manifold: TempContactManifold;
171
+ flipped: boolean;
172
+ }): void;
173
+ /**
174
+ * Callback when this rigidbody stops colliding with another rigidbody
175
+ */
176
+ onCollisionExit?({}: {
177
+ target: RapierRigidBody;
178
+ }): void;
179
+ onSleep?(): void;
180
+ onWake?(): void;
165
181
  }
166
182
  export declare type SphericalJointParams = [
167
183
  body1Anchor: Vector3Array,
@@ -12,6 +12,6 @@ export declare const createColliderFromOptions: <A>(options: UseColliderOptions<
12
12
  x: number;
13
13
  y: number;
14
14
  z: number;
15
- }) => Collider;
16
- export declare const createCollidersFromChildren: (object: Object3D, rigidBody: RapierRigidBody, type: RigidBodyAutoCollider, world: WorldApi) => Collider[];
15
+ }, hasCollisionEvents?: boolean) => Collider;
16
+ export declare const createCollidersFromChildren: (object: Object3D, rigidBody: RapierRigidBody, type: RigidBodyAutoCollider, world: WorldApi, hasCollisionEvents?: boolean) => Collider[];
17
17
  export declare const scaleVertices: (vertices: ArrayLike<number>, scale: Vector3) => number[];
@@ -5,8 +5,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var React = require('react');
6
6
  var useAsset = require('use-asset');
7
7
  var fiber = require('@react-three/fiber');
8
- var three = require('three');
9
8
  var rapier3dCompat = require('@dimforge/rapier3d-compat');
9
+ var three = require('three');
10
10
 
11
11
  function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
12
12
 
@@ -67,7 +67,7 @@ const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
67
67
  x: 1,
68
68
  y: 1,
69
69
  z: 1
70
- }) => {
70
+ }, hasCollisionEvents = false) => {
71
71
  var _options$shape, _options$args, _options$restitution, _options$restitutionC, _options$friction, _options$frictionComb;
72
72
 
73
73
  const mass = (options === null || options === void 0 ? void 0 : options.mass) || 1;
@@ -85,7 +85,12 @@ const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
85
85
  y: ry,
86
86
  z: rz,
87
87
  w: 1
88
- }).setRestitution((_options$restitution = options === null || options === void 0 ? void 0 : options.restitution) !== null && _options$restitution !== void 0 ? _options$restitution : 0).setRestitutionCombineRule((_options$restitutionC = options === null || options === void 0 ? void 0 : options.restitutionCombineRule) !== null && _options$restitutionC !== void 0 ? _options$restitutionC : rapier3dCompat.CoefficientCombineRule.Average).setFriction((_options$friction = options === null || options === void 0 ? void 0 : options.friction) !== null && _options$friction !== void 0 ? _options$friction : 0.7).setFrictionCombineRule((_options$frictionComb = options === null || options === void 0 ? void 0 : options.frictionCombineRule) !== null && _options$frictionComb !== void 0 ? _options$frictionComb : rapier3dCompat.CoefficientCombineRule.Average); // If any of the mass properties are specified, add mass properties
88
+ }).setRestitution((_options$restitution = options === null || options === void 0 ? void 0 : options.restitution) !== null && _options$restitution !== void 0 ? _options$restitution : 0).setRestitutionCombineRule((_options$restitutionC = options === null || options === void 0 ? void 0 : options.restitutionCombineRule) !== null && _options$restitutionC !== void 0 ? _options$restitutionC : rapier3dCompat.CoefficientCombineRule.Average).setFriction((_options$friction = options === null || options === void 0 ? void 0 : options.friction) !== null && _options$friction !== void 0 ? _options$friction : 0.7).setFrictionCombineRule((_options$frictionComb = options === null || options === void 0 ? void 0 : options.frictionCombineRule) !== null && _options$frictionComb !== void 0 ? _options$frictionComb : rapier3dCompat.CoefficientCombineRule.Average);
89
+
90
+ if (hasCollisionEvents) {
91
+ colliderDesc = colliderDesc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
92
+ } // If any of the mass properties are specified, add mass properties
93
+
89
94
 
90
95
  if (options !== null && options !== void 0 && options.mass || options !== null && options !== void 0 && options.centerOfMass || options !== null && options !== void 0 && options.principalAngularInertia) {
91
96
  colliderDesc.setDensity(0);
@@ -108,7 +113,7 @@ const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
108
113
  const collider = world.createCollider(colliderDesc, rigidBodyHandle);
109
114
  return collider;
110
115
  };
111
- const createCollidersFromChildren = (object, rigidBody, type, world) => {
116
+ const createCollidersFromChildren = (object, rigidBody, type, world, hasCollisionEvents = false) => {
112
117
  const colliders = [];
113
118
  let desc;
114
119
  let offset = new three.Vector3();
@@ -181,6 +186,11 @@ const createCollidersFromChildren = (object, rigidBody, type, world) => {
181
186
  z: rz,
182
187
  w: rw
183
188
  });
189
+
190
+ if (hasCollisionEvents) {
191
+ desc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
192
+ }
193
+
184
194
  const collider = world.createCollider(desc, rigidBody.handle);
185
195
  colliders.push(collider);
186
196
  }
@@ -316,7 +326,9 @@ const Physics = ({
316
326
  return worldRef.current;
317
327
  });
318
328
  const [colliderMeshes] = React.useState(() => new Map());
319
- const [rigidBodyMeshes] = React.useState(() => new Map()); // Init world
329
+ const [rigidBodyMeshes] = React.useState(() => new Map());
330
+ const [rigidBodyEvents] = React.useState(() => new Map());
331
+ const [eventQueue] = React.useState(() => new rapier3dCompat.EventQueue(false)); // Init world
320
332
 
321
333
  React.useLayoutEffect(() => {
322
334
  const world = getWorldRef.current();
@@ -336,10 +348,27 @@ const Physics = ({
336
348
  const now = performance.now();
337
349
  const delta = Math.min(100, now - time.current);
338
350
  world.timestep = delta / 1000;
339
- world.step(); // Update meshes
351
+ world.step(eventQueue); // Update meshes
340
352
 
341
353
  rigidBodyMeshes.forEach((mesh, handle) => {
342
354
  const rigidBody = world.getRigidBody(handle);
355
+ const events = rigidBodyEvents.get(handle);
356
+
357
+ if (events !== null && events !== void 0 && events.onSleep || events !== null && events !== void 0 && events.onWake) {
358
+ if (rigidBody.isSleeping() && !mesh.userData.isSleeping) {
359
+ var _events$onSleep;
360
+
361
+ events === null || events === void 0 ? void 0 : (_events$onSleep = events.onSleep) === null || _events$onSleep === void 0 ? void 0 : _events$onSleep.call(events);
362
+ }
363
+
364
+ if (!rigidBody.isSleeping() && mesh.userData.isSleeping) {
365
+ var _events$onWake;
366
+
367
+ events === null || events === void 0 ? void 0 : (_events$onWake = events.onWake) === null || _events$onWake === void 0 ? void 0 : _events$onWake.call(events);
368
+ }
369
+
370
+ mesh.userData.isSleeping = rigidBody.isSleeping();
371
+ }
343
372
 
344
373
  if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !mesh.parent) {
345
374
  return;
@@ -367,6 +396,48 @@ const Physics = ({
367
396
  o.updateMatrix();
368
397
  mesh.position.setFromMatrixPosition(o.matrix);
369
398
  mesh.rotation.setFromRotationMatrix(o.matrix);
399
+ }); // Collision events
400
+
401
+ eventQueue.drainCollisionEvents((handle1, handle2, started) => {
402
+ const collider1 = world.getCollider(handle1);
403
+ const collider2 = world.getCollider(handle2);
404
+ const rigidBodyHandle1 = collider1.parent();
405
+ const rigidBodyHandle2 = collider2.parent();
406
+
407
+ if (!collider1 || !collider2 || !rigidBodyHandle1 || !rigidBodyHandle2) {
408
+ return;
409
+ }
410
+
411
+ const rigidBody1 = world.getRigidBody(rigidBodyHandle1);
412
+ const rigidBody2 = world.getRigidBody(rigidBodyHandle2);
413
+ const events1 = rigidBodyEvents.get(rigidBodyHandle1);
414
+ const events2 = rigidBodyEvents.get(rigidBodyHandle2);
415
+
416
+ if (started) {
417
+ world.contactPair(handle1, handle2, (manifold, flipped) => {
418
+ var _events1$onCollisionE, _events2$onCollisionE;
419
+
420
+ events1 === null || events1 === void 0 ? void 0 : (_events1$onCollisionE = events1.onCollisionEnter) === null || _events1$onCollisionE === void 0 ? void 0 : _events1$onCollisionE.call(events1, {
421
+ target: rigidBody2,
422
+ manifold,
423
+ flipped
424
+ });
425
+ events2 === null || events2 === void 0 ? void 0 : (_events2$onCollisionE = events2.onCollisionEnter) === null || _events2$onCollisionE === void 0 ? void 0 : _events2$onCollisionE.call(events2, {
426
+ target: rigidBody1,
427
+ manifold,
428
+ flipped
429
+ });
430
+ });
431
+ } else {
432
+ var _events1$onCollisionE2, _events2$onCollisionE2;
433
+
434
+ events1 === null || events1 === void 0 ? void 0 : (_events1$onCollisionE2 = events1.onCollisionExit) === null || _events1$onCollisionE2 === void 0 ? void 0 : _events1$onCollisionE2.call(events1, {
435
+ target: rigidBody2
436
+ });
437
+ events2 === null || events2 === void 0 ? void 0 : (_events2$onCollisionE2 = events2.onCollisionExit) === null || _events2$onCollisionE2 === void 0 ? void 0 : _events2$onCollisionE2.call(events2, {
438
+ target: rigidBody1
439
+ });
440
+ }
370
441
  });
371
442
  time.current = now;
372
443
  });
@@ -379,7 +450,8 @@ const Physics = ({
379
450
  gravity: _gravity
380
451
  },
381
452
  colliderMeshes,
382
- rigidBodyMeshes
453
+ rigidBodyMeshes,
454
+ rigidBodyEvents
383
455
  }), []);
384
456
  return /*#__PURE__*/React__default["default"].createElement(RapierContext.Provider, {
385
457
  value: context
@@ -435,7 +507,8 @@ const useRigidBody = (options = {}) => {
435
507
  rapier,
436
508
  world,
437
509
  rigidBodyMeshes,
438
- physicsOptions
510
+ physicsOptions,
511
+ rigidBodyEvents
439
512
  } = useRapier();
440
513
  const ref = React.useRef(); // Create rigidbody
441
514
 
@@ -470,9 +543,11 @@ const useRigidBody = (options = {}) => {
470
543
 
471
544
  if (!ref.current) {
472
545
  ref.current = new three.Object3D();
473
- } // Get intitial world transforms
546
+ } // isSleeping used for onSleep and onWake events
474
547
 
475
548
 
549
+ ref.current.userData.isSleeping = false; // Get intitial world transforms
550
+
476
551
  const worldPosition = ref.current.getWorldPosition(new three.Vector3());
477
552
  const worldRotation = ref.current.getWorldQuaternion(new three.Quaternion());
478
553
  const scale = ((_ref$current$parent = ref.current.parent) === null || _ref$current$parent === void 0 ? void 0 : _ref$current$parent.getWorldScale(new three.Vector3())) || {
@@ -500,7 +575,8 @@ const useRigidBody = (options = {}) => {
500
575
  rigidBody.resetForces(false);
501
576
  rigidBody.resetTorques(false);
502
577
  const colliderSetting = (_ref = (_options$colliders = options === null || options === void 0 ? void 0 : options.colliders) !== null && _options$colliders !== void 0 ? _options$colliders : physicsOptions.colliders) !== null && _ref !== void 0 ? _ref : false;
503
- const autoColliders = colliderSetting !== false ? createCollidersFromChildren(ref.current, rigidBody, colliderSetting, world) : [];
578
+ const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
579
+ const autoColliders = colliderSetting !== false ? createCollidersFromChildren(ref.current, rigidBody, colliderSetting, world, hasCollisionEvents) : [];
504
580
  rigidBody.wakeUp();
505
581
  rigidBodyMeshes.set(rigidBody.handle, ref.current);
506
582
  return () => {
@@ -509,7 +585,20 @@ const useRigidBody = (options = {}) => {
509
585
  rigidBodyRef.current = undefined;
510
586
  rigidBodyMeshes.delete(rigidBody.handle);
511
587
  };
512
- }, []);
588
+ }, []); // Events
589
+
590
+ React.useEffect(() => {
591
+ const rigidBody = getRigidBodyRef.current();
592
+ rigidBodyEvents.set(rigidBody.handle, {
593
+ onCollisionEnter: options === null || options === void 0 ? void 0 : options.onCollisionEnter,
594
+ onCollisionExit: options === null || options === void 0 ? void 0 : options.onCollisionExit,
595
+ onSleep: options === null || options === void 0 ? void 0 : options.onSleep,
596
+ onWake: options === null || options === void 0 ? void 0 : options.onWake
597
+ });
598
+ return () => {
599
+ rigidBodyEvents.delete(rigidBody.handle);
600
+ };
601
+ }, [options.onCollisionEnter, options.onCollisionExit]);
513
602
  const api = React.useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
514
603
  return [ref, api];
515
604
  };
@@ -823,7 +912,7 @@ const _excluded = ["children"],
823
912
  _excluded2 = ["children"];
824
913
  const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
825
914
 
826
- const useParentRigidBody = () => React.useContext(RigidBodyContext); // RigidBody
915
+ const useRigidBodyContext = () => React.useContext(RigidBodyContext); // RigidBody
827
916
 
828
917
 
829
918
  const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
@@ -835,7 +924,7 @@ const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
835
924
  const [object, rigidBody] = useRigidBody(props);
836
925
  React.useImperativeHandle(ref, () => rigidBody);
837
926
  return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
838
- value: [object, rigidBody]
927
+ value: [object, rigidBody, !!(props.onCollisionEnter || props.onCollisionExit)]
839
928
  }, /*#__PURE__*/React__default["default"].createElement("object3D", {
840
929
  ref: object
841
930
  }, children));
@@ -850,11 +939,11 @@ const AnyCollider = _ref2 => {
850
939
  const {
851
940
  world
852
941
  } = useRapier();
853
- const [, rigidBody] = useParentRigidBody();
942
+ const [, rigidBody, hasCollisionEvents] = useRigidBodyContext();
854
943
  const ref = React.useRef(null);
855
944
  React.useEffect(() => {
856
945
  const scale = ref.current.getWorldScale(new three.Vector3());
857
- const collider = createColliderFromOptions(props, world, rigidBody.handle, scale);
946
+ const collider = createColliderFromOptions(props, world, rigidBody.handle, scale, hasCollisionEvents);
858
947
  return () => {
859
948
  world.removeCollider(collider);
860
949
  };
@@ -5,8 +5,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var React = require('react');
6
6
  var useAsset = require('use-asset');
7
7
  var fiber = require('@react-three/fiber');
8
- var three = require('three');
9
8
  var rapier3dCompat = require('@dimforge/rapier3d-compat');
9
+ var three = require('three');
10
10
 
11
11
  function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
12
12
 
@@ -67,7 +67,7 @@ const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
67
67
  x: 1,
68
68
  y: 1,
69
69
  z: 1
70
- }) => {
70
+ }, hasCollisionEvents = false) => {
71
71
  var _options$shape, _options$args, _options$restitution, _options$restitutionC, _options$friction, _options$frictionComb;
72
72
 
73
73
  const mass = (options === null || options === void 0 ? void 0 : options.mass) || 1;
@@ -85,7 +85,12 @@ const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
85
85
  y: ry,
86
86
  z: rz,
87
87
  w: 1
88
- }).setRestitution((_options$restitution = options === null || options === void 0 ? void 0 : options.restitution) !== null && _options$restitution !== void 0 ? _options$restitution : 0).setRestitutionCombineRule((_options$restitutionC = options === null || options === void 0 ? void 0 : options.restitutionCombineRule) !== null && _options$restitutionC !== void 0 ? _options$restitutionC : rapier3dCompat.CoefficientCombineRule.Average).setFriction((_options$friction = options === null || options === void 0 ? void 0 : options.friction) !== null && _options$friction !== void 0 ? _options$friction : 0.7).setFrictionCombineRule((_options$frictionComb = options === null || options === void 0 ? void 0 : options.frictionCombineRule) !== null && _options$frictionComb !== void 0 ? _options$frictionComb : rapier3dCompat.CoefficientCombineRule.Average); // If any of the mass properties are specified, add mass properties
88
+ }).setRestitution((_options$restitution = options === null || options === void 0 ? void 0 : options.restitution) !== null && _options$restitution !== void 0 ? _options$restitution : 0).setRestitutionCombineRule((_options$restitutionC = options === null || options === void 0 ? void 0 : options.restitutionCombineRule) !== null && _options$restitutionC !== void 0 ? _options$restitutionC : rapier3dCompat.CoefficientCombineRule.Average).setFriction((_options$friction = options === null || options === void 0 ? void 0 : options.friction) !== null && _options$friction !== void 0 ? _options$friction : 0.7).setFrictionCombineRule((_options$frictionComb = options === null || options === void 0 ? void 0 : options.frictionCombineRule) !== null && _options$frictionComb !== void 0 ? _options$frictionComb : rapier3dCompat.CoefficientCombineRule.Average);
89
+
90
+ if (hasCollisionEvents) {
91
+ colliderDesc = colliderDesc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
92
+ } // If any of the mass properties are specified, add mass properties
93
+
89
94
 
90
95
  if (options !== null && options !== void 0 && options.mass || options !== null && options !== void 0 && options.centerOfMass || options !== null && options !== void 0 && options.principalAngularInertia) {
91
96
  colliderDesc.setDensity(0);
@@ -108,7 +113,7 @@ const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
108
113
  const collider = world.createCollider(colliderDesc, rigidBodyHandle);
109
114
  return collider;
110
115
  };
111
- const createCollidersFromChildren = (object, rigidBody, type, world) => {
116
+ const createCollidersFromChildren = (object, rigidBody, type, world, hasCollisionEvents = false) => {
112
117
  const colliders = [];
113
118
  let desc;
114
119
  let offset = new three.Vector3();
@@ -181,6 +186,11 @@ const createCollidersFromChildren = (object, rigidBody, type, world) => {
181
186
  z: rz,
182
187
  w: rw
183
188
  });
189
+
190
+ if (hasCollisionEvents) {
191
+ desc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
192
+ }
193
+
184
194
  const collider = world.createCollider(desc, rigidBody.handle);
185
195
  colliders.push(collider);
186
196
  }
@@ -316,7 +326,9 @@ const Physics = ({
316
326
  return worldRef.current;
317
327
  });
318
328
  const [colliderMeshes] = React.useState(() => new Map());
319
- const [rigidBodyMeshes] = React.useState(() => new Map()); // Init world
329
+ const [rigidBodyMeshes] = React.useState(() => new Map());
330
+ const [rigidBodyEvents] = React.useState(() => new Map());
331
+ const [eventQueue] = React.useState(() => new rapier3dCompat.EventQueue(false)); // Init world
320
332
 
321
333
  React.useLayoutEffect(() => {
322
334
  const world = getWorldRef.current();
@@ -336,10 +348,27 @@ const Physics = ({
336
348
  const now = performance.now();
337
349
  const delta = Math.min(100, now - time.current);
338
350
  world.timestep = delta / 1000;
339
- world.step(); // Update meshes
351
+ world.step(eventQueue); // Update meshes
340
352
 
341
353
  rigidBodyMeshes.forEach((mesh, handle) => {
342
354
  const rigidBody = world.getRigidBody(handle);
355
+ const events = rigidBodyEvents.get(handle);
356
+
357
+ if (events !== null && events !== void 0 && events.onSleep || events !== null && events !== void 0 && events.onWake) {
358
+ if (rigidBody.isSleeping() && !mesh.userData.isSleeping) {
359
+ var _events$onSleep;
360
+
361
+ events === null || events === void 0 ? void 0 : (_events$onSleep = events.onSleep) === null || _events$onSleep === void 0 ? void 0 : _events$onSleep.call(events);
362
+ }
363
+
364
+ if (!rigidBody.isSleeping() && mesh.userData.isSleeping) {
365
+ var _events$onWake;
366
+
367
+ events === null || events === void 0 ? void 0 : (_events$onWake = events.onWake) === null || _events$onWake === void 0 ? void 0 : _events$onWake.call(events);
368
+ }
369
+
370
+ mesh.userData.isSleeping = rigidBody.isSleeping();
371
+ }
343
372
 
344
373
  if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !mesh.parent) {
345
374
  return;
@@ -367,6 +396,48 @@ const Physics = ({
367
396
  o.updateMatrix();
368
397
  mesh.position.setFromMatrixPosition(o.matrix);
369
398
  mesh.rotation.setFromRotationMatrix(o.matrix);
399
+ }); // Collision events
400
+
401
+ eventQueue.drainCollisionEvents((handle1, handle2, started) => {
402
+ const collider1 = world.getCollider(handle1);
403
+ const collider2 = world.getCollider(handle2);
404
+ const rigidBodyHandle1 = collider1.parent();
405
+ const rigidBodyHandle2 = collider2.parent();
406
+
407
+ if (!collider1 || !collider2 || !rigidBodyHandle1 || !rigidBodyHandle2) {
408
+ return;
409
+ }
410
+
411
+ const rigidBody1 = world.getRigidBody(rigidBodyHandle1);
412
+ const rigidBody2 = world.getRigidBody(rigidBodyHandle2);
413
+ const events1 = rigidBodyEvents.get(rigidBodyHandle1);
414
+ const events2 = rigidBodyEvents.get(rigidBodyHandle2);
415
+
416
+ if (started) {
417
+ world.contactPair(handle1, handle2, (manifold, flipped) => {
418
+ var _events1$onCollisionE, _events2$onCollisionE;
419
+
420
+ events1 === null || events1 === void 0 ? void 0 : (_events1$onCollisionE = events1.onCollisionEnter) === null || _events1$onCollisionE === void 0 ? void 0 : _events1$onCollisionE.call(events1, {
421
+ target: rigidBody2,
422
+ manifold,
423
+ flipped
424
+ });
425
+ events2 === null || events2 === void 0 ? void 0 : (_events2$onCollisionE = events2.onCollisionEnter) === null || _events2$onCollisionE === void 0 ? void 0 : _events2$onCollisionE.call(events2, {
426
+ target: rigidBody1,
427
+ manifold,
428
+ flipped
429
+ });
430
+ });
431
+ } else {
432
+ var _events1$onCollisionE2, _events2$onCollisionE2;
433
+
434
+ events1 === null || events1 === void 0 ? void 0 : (_events1$onCollisionE2 = events1.onCollisionExit) === null || _events1$onCollisionE2 === void 0 ? void 0 : _events1$onCollisionE2.call(events1, {
435
+ target: rigidBody2
436
+ });
437
+ events2 === null || events2 === void 0 ? void 0 : (_events2$onCollisionE2 = events2.onCollisionExit) === null || _events2$onCollisionE2 === void 0 ? void 0 : _events2$onCollisionE2.call(events2, {
438
+ target: rigidBody1
439
+ });
440
+ }
370
441
  });
371
442
  time.current = now;
372
443
  });
@@ -379,7 +450,8 @@ const Physics = ({
379
450
  gravity: _gravity
380
451
  },
381
452
  colliderMeshes,
382
- rigidBodyMeshes
453
+ rigidBodyMeshes,
454
+ rigidBodyEvents
383
455
  }), []);
384
456
  return /*#__PURE__*/React__default["default"].createElement(RapierContext.Provider, {
385
457
  value: context
@@ -435,7 +507,8 @@ const useRigidBody = (options = {}) => {
435
507
  rapier,
436
508
  world,
437
509
  rigidBodyMeshes,
438
- physicsOptions
510
+ physicsOptions,
511
+ rigidBodyEvents
439
512
  } = useRapier();
440
513
  const ref = React.useRef(); // Create rigidbody
441
514
 
@@ -470,9 +543,11 @@ const useRigidBody = (options = {}) => {
470
543
 
471
544
  if (!ref.current) {
472
545
  ref.current = new three.Object3D();
473
- } // Get intitial world transforms
546
+ } // isSleeping used for onSleep and onWake events
474
547
 
475
548
 
549
+ ref.current.userData.isSleeping = false; // Get intitial world transforms
550
+
476
551
  const worldPosition = ref.current.getWorldPosition(new three.Vector3());
477
552
  const worldRotation = ref.current.getWorldQuaternion(new three.Quaternion());
478
553
  const scale = ((_ref$current$parent = ref.current.parent) === null || _ref$current$parent === void 0 ? void 0 : _ref$current$parent.getWorldScale(new three.Vector3())) || {
@@ -500,7 +575,8 @@ const useRigidBody = (options = {}) => {
500
575
  rigidBody.resetForces(false);
501
576
  rigidBody.resetTorques(false);
502
577
  const colliderSetting = (_ref = (_options$colliders = options === null || options === void 0 ? void 0 : options.colliders) !== null && _options$colliders !== void 0 ? _options$colliders : physicsOptions.colliders) !== null && _ref !== void 0 ? _ref : false;
503
- const autoColliders = colliderSetting !== false ? createCollidersFromChildren(ref.current, rigidBody, colliderSetting, world) : [];
578
+ const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
579
+ const autoColliders = colliderSetting !== false ? createCollidersFromChildren(ref.current, rigidBody, colliderSetting, world, hasCollisionEvents) : [];
504
580
  rigidBody.wakeUp();
505
581
  rigidBodyMeshes.set(rigidBody.handle, ref.current);
506
582
  return () => {
@@ -509,7 +585,20 @@ const useRigidBody = (options = {}) => {
509
585
  rigidBodyRef.current = undefined;
510
586
  rigidBodyMeshes.delete(rigidBody.handle);
511
587
  };
512
- }, []);
588
+ }, []); // Events
589
+
590
+ React.useEffect(() => {
591
+ const rigidBody = getRigidBodyRef.current();
592
+ rigidBodyEvents.set(rigidBody.handle, {
593
+ onCollisionEnter: options === null || options === void 0 ? void 0 : options.onCollisionEnter,
594
+ onCollisionExit: options === null || options === void 0 ? void 0 : options.onCollisionExit,
595
+ onSleep: options === null || options === void 0 ? void 0 : options.onSleep,
596
+ onWake: options === null || options === void 0 ? void 0 : options.onWake
597
+ });
598
+ return () => {
599
+ rigidBodyEvents.delete(rigidBody.handle);
600
+ };
601
+ }, [options.onCollisionEnter, options.onCollisionExit]);
513
602
  const api = React.useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
514
603
  return [ref, api];
515
604
  };
@@ -823,7 +912,7 @@ const _excluded = ["children"],
823
912
  _excluded2 = ["children"];
824
913
  const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
825
914
 
826
- const useParentRigidBody = () => React.useContext(RigidBodyContext); // RigidBody
915
+ const useRigidBodyContext = () => React.useContext(RigidBodyContext); // RigidBody
827
916
 
828
917
 
829
918
  const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
@@ -835,7 +924,7 @@ const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
835
924
  const [object, rigidBody] = useRigidBody(props);
836
925
  React.useImperativeHandle(ref, () => rigidBody);
837
926
  return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
838
- value: [object, rigidBody]
927
+ value: [object, rigidBody, !!(props.onCollisionEnter || props.onCollisionExit)]
839
928
  }, /*#__PURE__*/React__default["default"].createElement("object3D", {
840
929
  ref: object
841
930
  }, children));
@@ -850,11 +939,11 @@ const AnyCollider = _ref2 => {
850
939
  const {
851
940
  world
852
941
  } = useRapier();
853
- const [, rigidBody] = useParentRigidBody();
942
+ const [, rigidBody, hasCollisionEvents] = useRigidBodyContext();
854
943
  const ref = React.useRef(null);
855
944
  React.useEffect(() => {
856
945
  const scale = ref.current.getWorldScale(new three.Vector3());
857
- const collider = createColliderFromOptions(props, world, rigidBody.handle, scale);
946
+ const collider = createColliderFromOptions(props, world, rigidBody.handle, scale, hasCollisionEvents);
858
947
  return () => {
859
948
  world.removeCollider(collider);
860
949
  };
@@ -1,9 +1,9 @@
1
1
  import React, { useRef, useState, useLayoutEffect, useMemo, createContext, useContext, useEffect, forwardRef, useImperativeHandle, memo } from 'react';
2
2
  import { useAsset } from 'use-asset';
3
3
  import { useFrame } from '@react-three/fiber';
4
- import { Vector3, Quaternion, Object3D, Euler, CylinderBufferGeometry, BufferGeometry, BufferAttribute, SphereBufferGeometry, BoxBufferGeometry } from 'three';
5
- import { ColliderDesc, CoefficientCombineRule, ShapeType } from '@dimforge/rapier3d-compat';
4
+ import { ColliderDesc, CoefficientCombineRule, ActiveEvents, EventQueue, ShapeType } from '@dimforge/rapier3d-compat';
6
5
  export { CoefficientCombineRule, Collider as RapierCollider, RigidBody as RapierRigidBody } from '@dimforge/rapier3d-compat';
6
+ import { Vector3, Quaternion, Object3D, Euler, CylinderBufferGeometry, BufferGeometry, BufferAttribute, SphereBufferGeometry, BoxBufferGeometry } from 'three';
7
7
 
8
8
  const vectorArrayToObject = arr => {
9
9
  const [x, y, z] = arr;
@@ -42,7 +42,7 @@ const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
42
42
  x: 1,
43
43
  y: 1,
44
44
  z: 1
45
- }) => {
45
+ }, hasCollisionEvents = false) => {
46
46
  var _options$shape, _options$args, _options$restitution, _options$restitutionC, _options$friction, _options$frictionComb;
47
47
 
48
48
  const mass = (options === null || options === void 0 ? void 0 : options.mass) || 1;
@@ -60,7 +60,12 @@ const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
60
60
  y: ry,
61
61
  z: rz,
62
62
  w: 1
63
- }).setRestitution((_options$restitution = options === null || options === void 0 ? void 0 : options.restitution) !== null && _options$restitution !== void 0 ? _options$restitution : 0).setRestitutionCombineRule((_options$restitutionC = options === null || options === void 0 ? void 0 : options.restitutionCombineRule) !== null && _options$restitutionC !== void 0 ? _options$restitutionC : CoefficientCombineRule.Average).setFriction((_options$friction = options === null || options === void 0 ? void 0 : options.friction) !== null && _options$friction !== void 0 ? _options$friction : 0.7).setFrictionCombineRule((_options$frictionComb = options === null || options === void 0 ? void 0 : options.frictionCombineRule) !== null && _options$frictionComb !== void 0 ? _options$frictionComb : CoefficientCombineRule.Average); // If any of the mass properties are specified, add mass properties
63
+ }).setRestitution((_options$restitution = options === null || options === void 0 ? void 0 : options.restitution) !== null && _options$restitution !== void 0 ? _options$restitution : 0).setRestitutionCombineRule((_options$restitutionC = options === null || options === void 0 ? void 0 : options.restitutionCombineRule) !== null && _options$restitutionC !== void 0 ? _options$restitutionC : CoefficientCombineRule.Average).setFriction((_options$friction = options === null || options === void 0 ? void 0 : options.friction) !== null && _options$friction !== void 0 ? _options$friction : 0.7).setFrictionCombineRule((_options$frictionComb = options === null || options === void 0 ? void 0 : options.frictionCombineRule) !== null && _options$frictionComb !== void 0 ? _options$frictionComb : CoefficientCombineRule.Average);
64
+
65
+ if (hasCollisionEvents) {
66
+ colliderDesc = colliderDesc.setActiveEvents(ActiveEvents.COLLISION_EVENTS);
67
+ } // If any of the mass properties are specified, add mass properties
68
+
64
69
 
65
70
  if (options !== null && options !== void 0 && options.mass || options !== null && options !== void 0 && options.centerOfMass || options !== null && options !== void 0 && options.principalAngularInertia) {
66
71
  colliderDesc.setDensity(0);
@@ -83,7 +88,7 @@ const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
83
88
  const collider = world.createCollider(colliderDesc, rigidBodyHandle);
84
89
  return collider;
85
90
  };
86
- const createCollidersFromChildren = (object, rigidBody, type, world) => {
91
+ const createCollidersFromChildren = (object, rigidBody, type, world, hasCollisionEvents = false) => {
87
92
  const colliders = [];
88
93
  let desc;
89
94
  let offset = new Vector3();
@@ -156,6 +161,11 @@ const createCollidersFromChildren = (object, rigidBody, type, world) => {
156
161
  z: rz,
157
162
  w: rw
158
163
  });
164
+
165
+ if (hasCollisionEvents) {
166
+ desc.setActiveEvents(ActiveEvents.COLLISION_EVENTS);
167
+ }
168
+
159
169
  const collider = world.createCollider(desc, rigidBody.handle);
160
170
  colliders.push(collider);
161
171
  }
@@ -291,7 +301,9 @@ const Physics = ({
291
301
  return worldRef.current;
292
302
  });
293
303
  const [colliderMeshes] = useState(() => new Map());
294
- const [rigidBodyMeshes] = useState(() => new Map()); // Init world
304
+ const [rigidBodyMeshes] = useState(() => new Map());
305
+ const [rigidBodyEvents] = useState(() => new Map());
306
+ const [eventQueue] = useState(() => new EventQueue(false)); // Init world
295
307
 
296
308
  useLayoutEffect(() => {
297
309
  const world = getWorldRef.current();
@@ -311,10 +323,27 @@ const Physics = ({
311
323
  const now = performance.now();
312
324
  const delta = Math.min(100, now - time.current);
313
325
  world.timestep = delta / 1000;
314
- world.step(); // Update meshes
326
+ world.step(eventQueue); // Update meshes
315
327
 
316
328
  rigidBodyMeshes.forEach((mesh, handle) => {
317
329
  const rigidBody = world.getRigidBody(handle);
330
+ const events = rigidBodyEvents.get(handle);
331
+
332
+ if (events !== null && events !== void 0 && events.onSleep || events !== null && events !== void 0 && events.onWake) {
333
+ if (rigidBody.isSleeping() && !mesh.userData.isSleeping) {
334
+ var _events$onSleep;
335
+
336
+ events === null || events === void 0 ? void 0 : (_events$onSleep = events.onSleep) === null || _events$onSleep === void 0 ? void 0 : _events$onSleep.call(events);
337
+ }
338
+
339
+ if (!rigidBody.isSleeping() && mesh.userData.isSleeping) {
340
+ var _events$onWake;
341
+
342
+ events === null || events === void 0 ? void 0 : (_events$onWake = events.onWake) === null || _events$onWake === void 0 ? void 0 : _events$onWake.call(events);
343
+ }
344
+
345
+ mesh.userData.isSleeping = rigidBody.isSleeping();
346
+ }
318
347
 
319
348
  if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !mesh.parent) {
320
349
  return;
@@ -342,6 +371,48 @@ const Physics = ({
342
371
  o.updateMatrix();
343
372
  mesh.position.setFromMatrixPosition(o.matrix);
344
373
  mesh.rotation.setFromRotationMatrix(o.matrix);
374
+ }); // Collision events
375
+
376
+ eventQueue.drainCollisionEvents((handle1, handle2, started) => {
377
+ const collider1 = world.getCollider(handle1);
378
+ const collider2 = world.getCollider(handle2);
379
+ const rigidBodyHandle1 = collider1.parent();
380
+ const rigidBodyHandle2 = collider2.parent();
381
+
382
+ if (!collider1 || !collider2 || !rigidBodyHandle1 || !rigidBodyHandle2) {
383
+ return;
384
+ }
385
+
386
+ const rigidBody1 = world.getRigidBody(rigidBodyHandle1);
387
+ const rigidBody2 = world.getRigidBody(rigidBodyHandle2);
388
+ const events1 = rigidBodyEvents.get(rigidBodyHandle1);
389
+ const events2 = rigidBodyEvents.get(rigidBodyHandle2);
390
+
391
+ if (started) {
392
+ world.contactPair(handle1, handle2, (manifold, flipped) => {
393
+ var _events1$onCollisionE, _events2$onCollisionE;
394
+
395
+ events1 === null || events1 === void 0 ? void 0 : (_events1$onCollisionE = events1.onCollisionEnter) === null || _events1$onCollisionE === void 0 ? void 0 : _events1$onCollisionE.call(events1, {
396
+ target: rigidBody2,
397
+ manifold,
398
+ flipped
399
+ });
400
+ events2 === null || events2 === void 0 ? void 0 : (_events2$onCollisionE = events2.onCollisionEnter) === null || _events2$onCollisionE === void 0 ? void 0 : _events2$onCollisionE.call(events2, {
401
+ target: rigidBody1,
402
+ manifold,
403
+ flipped
404
+ });
405
+ });
406
+ } else {
407
+ var _events1$onCollisionE2, _events2$onCollisionE2;
408
+
409
+ events1 === null || events1 === void 0 ? void 0 : (_events1$onCollisionE2 = events1.onCollisionExit) === null || _events1$onCollisionE2 === void 0 ? void 0 : _events1$onCollisionE2.call(events1, {
410
+ target: rigidBody2
411
+ });
412
+ events2 === null || events2 === void 0 ? void 0 : (_events2$onCollisionE2 = events2.onCollisionExit) === null || _events2$onCollisionE2 === void 0 ? void 0 : _events2$onCollisionE2.call(events2, {
413
+ target: rigidBody1
414
+ });
415
+ }
345
416
  });
346
417
  time.current = now;
347
418
  });
@@ -354,7 +425,8 @@ const Physics = ({
354
425
  gravity: _gravity
355
426
  },
356
427
  colliderMeshes,
357
- rigidBodyMeshes
428
+ rigidBodyMeshes,
429
+ rigidBodyEvents
358
430
  }), []);
359
431
  return /*#__PURE__*/React.createElement(RapierContext.Provider, {
360
432
  value: context
@@ -410,7 +482,8 @@ const useRigidBody = (options = {}) => {
410
482
  rapier,
411
483
  world,
412
484
  rigidBodyMeshes,
413
- physicsOptions
485
+ physicsOptions,
486
+ rigidBodyEvents
414
487
  } = useRapier();
415
488
  const ref = useRef(); // Create rigidbody
416
489
 
@@ -445,8 +518,10 @@ const useRigidBody = (options = {}) => {
445
518
 
446
519
  if (!ref.current) {
447
520
  ref.current = new Object3D();
448
- } // Get intitial world transforms
521
+ } // isSleeping used for onSleep and onWake events
522
+
449
523
 
524
+ ref.current.userData.isSleeping = false; // Get intitial world transforms
450
525
 
451
526
  const worldPosition = ref.current.getWorldPosition(new Vector3());
452
527
  const worldRotation = ref.current.getWorldQuaternion(new Quaternion());
@@ -475,7 +550,8 @@ const useRigidBody = (options = {}) => {
475
550
  rigidBody.resetForces(false);
476
551
  rigidBody.resetTorques(false);
477
552
  const colliderSetting = (_ref = (_options$colliders = options === null || options === void 0 ? void 0 : options.colliders) !== null && _options$colliders !== void 0 ? _options$colliders : physicsOptions.colliders) !== null && _ref !== void 0 ? _ref : false;
478
- const autoColliders = colliderSetting !== false ? createCollidersFromChildren(ref.current, rigidBody, colliderSetting, world) : [];
553
+ const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
554
+ const autoColliders = colliderSetting !== false ? createCollidersFromChildren(ref.current, rigidBody, colliderSetting, world, hasCollisionEvents) : [];
479
555
  rigidBody.wakeUp();
480
556
  rigidBodyMeshes.set(rigidBody.handle, ref.current);
481
557
  return () => {
@@ -484,7 +560,20 @@ const useRigidBody = (options = {}) => {
484
560
  rigidBodyRef.current = undefined;
485
561
  rigidBodyMeshes.delete(rigidBody.handle);
486
562
  };
487
- }, []);
563
+ }, []); // Events
564
+
565
+ useEffect(() => {
566
+ const rigidBody = getRigidBodyRef.current();
567
+ rigidBodyEvents.set(rigidBody.handle, {
568
+ onCollisionEnter: options === null || options === void 0 ? void 0 : options.onCollisionEnter,
569
+ onCollisionExit: options === null || options === void 0 ? void 0 : options.onCollisionExit,
570
+ onSleep: options === null || options === void 0 ? void 0 : options.onSleep,
571
+ onWake: options === null || options === void 0 ? void 0 : options.onWake
572
+ });
573
+ return () => {
574
+ rigidBodyEvents.delete(rigidBody.handle);
575
+ };
576
+ }, [options.onCollisionEnter, options.onCollisionExit]);
488
577
  const api = useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
489
578
  return [ref, api];
490
579
  };
@@ -798,7 +887,7 @@ const _excluded = ["children"],
798
887
  _excluded2 = ["children"];
799
888
  const RigidBodyContext = /*#__PURE__*/createContext(undefined);
800
889
 
801
- const useParentRigidBody = () => useContext(RigidBodyContext); // RigidBody
890
+ const useRigidBodyContext = () => useContext(RigidBodyContext); // RigidBody
802
891
 
803
892
 
804
893
  const RigidBody = /*#__PURE__*/forwardRef((_ref, ref) => {
@@ -810,7 +899,7 @@ const RigidBody = /*#__PURE__*/forwardRef((_ref, ref) => {
810
899
  const [object, rigidBody] = useRigidBody(props);
811
900
  useImperativeHandle(ref, () => rigidBody);
812
901
  return /*#__PURE__*/React.createElement(RigidBodyContext.Provider, {
813
- value: [object, rigidBody]
902
+ value: [object, rigidBody, !!(props.onCollisionEnter || props.onCollisionExit)]
814
903
  }, /*#__PURE__*/React.createElement("object3D", {
815
904
  ref: object
816
905
  }, children));
@@ -825,11 +914,11 @@ const AnyCollider = _ref2 => {
825
914
  const {
826
915
  world
827
916
  } = useRapier();
828
- const [, rigidBody] = useParentRigidBody();
917
+ const [, rigidBody, hasCollisionEvents] = useRigidBodyContext();
829
918
  const ref = useRef(null);
830
919
  useEffect(() => {
831
920
  const scale = ref.current.getWorldScale(new Vector3());
832
- const collider = createColliderFromOptions(props, world, rigidBody.handle, scale);
921
+ const collider = createColliderFromOptions(props, world, rigidBody.handle, scale, hasCollisionEvents);
833
922
  return () => {
834
923
  world.removeCollider(collider);
835
924
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-three/rapier",
3
- "version": "0.2.0",
3
+ "version": "0.3.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",