@react-three/rapier 0.8.2 → 0.9.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,9 +1,9 @@
1
- import { EventQueue, RigidBodyDesc, ColliderDesc, ActiveEvents } from '@dimforge/rapier3d-compat';
1
+ import { EventQueue, ColliderDesc, ActiveEvents, RigidBodyDesc } from '@dimforge/rapier3d-compat';
2
2
  export { CoefficientCombineRule, Collider as RapierCollider, RigidBody as RapierRigidBody } from '@dimforge/rapier3d-compat';
3
- import React, { useRef, useState, useEffect, useMemo, createContext, useContext, memo, forwardRef, useImperativeHandle, useLayoutEffect } from 'react';
4
- import { useAsset } from 'use-asset';
5
3
  import { useFrame } from '@react-three/fiber';
4
+ import React, { useRef, useState, useEffect, useCallback, useMemo, createContext, useContext, memo, forwardRef, useImperativeHandle, useLayoutEffect } from 'react';
6
5
  import { Quaternion, Euler, Vector3, Object3D, Matrix4, MathUtils, InstancedMesh, BufferAttribute, DynamicDrawUsage } from 'three';
6
+ import { useAsset } from 'use-asset';
7
7
  import { mergeVertices } from 'three-stdlib';
8
8
 
9
9
  const _quaternion = new Quaternion();
@@ -227,7 +227,8 @@ const Physics = ({
227
227
  children,
228
228
  timeStep: _timeStep = 1 / 60,
229
229
  paused: _paused = false,
230
- updatePriority
230
+ updatePriority,
231
+ interpolate: _interpolate = true
231
232
  }) => {
232
233
  const rapier = useAsset(importRapier);
233
234
  const worldRef = useRef();
@@ -263,12 +264,40 @@ const Physics = ({
263
264
  }
264
265
  }, [_gravity]);
265
266
  const [steppingState] = useState({
267
+ previousState: {},
266
268
  accumulator: 0
267
269
  });
268
270
  /* Check if the timestep is supposed to be variable. We'll do this here
269
271
  once so we don't have to string-check every frame. */
270
272
 
271
273
  const timeStepVariable = _timeStep === "vary";
274
+ const getSourceFromColliderHandle = useCallback(handle => {
275
+ const world = worldRef.current;
276
+
277
+ if (world) {
278
+ var _collider$parent;
279
+
280
+ const collider = world.getCollider(handle);
281
+ const colEvents = colliderEvents.get(handle);
282
+ const colliderState = colliderStates.get(handle);
283
+ const rigidBodyHandle = collider === null || collider === void 0 ? void 0 : (_collider$parent = collider.parent()) === null || _collider$parent === void 0 ? void 0 : _collider$parent.handle;
284
+ const rigidBody = rigidBodyHandle ? world.getRigidBody(rigidBodyHandle) : undefined;
285
+ const rbEvents = rigidBody && rigidBodyHandle ? rigidBodyEvents.get(rigidBodyHandle) : undefined;
286
+ const rigidBodyState = rigidBodyHandle ? rigidBodyStates.get(rigidBodyHandle) : undefined;
287
+ return {
288
+ collider: {
289
+ object: collider,
290
+ events: colEvents,
291
+ state: colliderState
292
+ },
293
+ rigidBody: {
294
+ object: rigidBody,
295
+ events: rbEvents,
296
+ state: rigidBodyState
297
+ }
298
+ };
299
+ }
300
+ }, []);
272
301
  useFrame((_, dt) => {
273
302
  const world = worldRef.current;
274
303
  if (!world) return;
@@ -290,13 +319,25 @@ const Physics = ({
290
319
 
291
320
  if (!_paused) {
292
321
  while (steppingState.accumulator >= _timeStep) {
322
+ if (_interpolate) {
323
+ // Set up previous state
324
+ // needed for accurate interpolations if the world steps more than once
325
+ steppingState.previousState = {};
326
+ world.forEachRigidBody(body => {
327
+ steppingState.previousState[body.handle] = {
328
+ position: body.translation(),
329
+ rotation: body.rotation()
330
+ };
331
+ });
332
+ }
333
+
293
334
  world.step(eventQueue);
294
335
  steppingState.accumulator -= _timeStep;
295
336
  }
296
337
  }
297
338
  }
298
339
 
299
- const interpolationAlpha = timeStepVariable ? 1 : steppingState.accumulator % _timeStep / _timeStep; // Update meshes
340
+ const interpolationAlpha = timeStepVariable || !_interpolate ? 1 : steppingState.accumulator / _timeStep; // Update meshes
300
341
 
301
342
  rigidBodyStates.forEach((state, handle) => {
302
343
  const rigidBody = world.getRigidBody(handle);
@@ -323,7 +364,20 @@ const Physics = ({
323
364
  }
324
365
 
325
366
  let t = rigidBody.translation();
326
- let r = rigidBody.rotation(); // Get new position
367
+ let r = rigidBody.rotation();
368
+ let previousState = steppingState.previousState[handle];
369
+
370
+ if (previousState) {
371
+ // Get previous simulated world position
372
+ _matrix4.compose(previousState.position, rapierQuaternionToQuaternion(previousState.rotation), state.scale).premultiply(state.invertedWorldMatrix).decompose(_position, _rotation, _scale); // Apply previous tick position
373
+
374
+
375
+ if (!(state.object instanceof InstancedMesh)) {
376
+ state.object.position.copy(_position);
377
+ state.object.quaternion.copy(_rotation);
378
+ }
379
+ } // Get new position
380
+
327
381
 
328
382
  _matrix4.compose(t, rapierQuaternionToQuaternion(r), state.scale).premultiply(state.invertedWorldMatrix).decompose(_position, _rotation, _scale);
329
383
 
@@ -331,146 +385,182 @@ const Physics = ({
331
385
  state.setMatrix(_matrix4);
332
386
  state.object.instanceMatrix.needsUpdate = true;
333
387
  } else {
334
- // Interpolate from last position
388
+ // Interpolate to new position
335
389
  state.object.position.lerp(_position, interpolationAlpha);
336
390
  state.object.quaternion.slerp(_rotation, interpolationAlpha);
337
391
  }
338
392
  });
339
393
  eventQueue.drainCollisionEvents((handle1, handle2, started) => {
340
- var _collider1$parent, _collider2$parent;
341
-
342
- const collider1 = world.getCollider(handle1);
343
- const collider2 = world.getCollider(handle2);
344
- const rigidBodyHandle1 = (_collider1$parent = collider1.parent()) === null || _collider1$parent === void 0 ? void 0 : _collider1$parent.handle;
345
- const rigidBodyHandle2 = (_collider2$parent = collider2.parent()) === null || _collider2$parent === void 0 ? void 0 : _collider2$parent.handle; // Collision Events
394
+ const source1 = getSourceFromColliderHandle(handle1);
395
+ const source2 = getSourceFromColliderHandle(handle2); // Collision Events
346
396
 
347
- if (!collider1 || !collider2) {
397
+ if (!(source1 !== null && source1 !== void 0 && source1.collider.object) || !(source2 !== null && source2 !== void 0 && source2.collider.object)) {
348
398
  return;
349
399
  }
350
400
 
351
- const collider1Events = colliderEvents.get(collider1.handle);
352
- const collider2Events = colliderEvents.get(collider2.handle);
353
- const rigidBody1 = rigidBodyHandle1 ? world.getRigidBody(rigidBodyHandle1) : undefined;
354
- const rigidBody2 = rigidBodyHandle2 ? world.getRigidBody(rigidBodyHandle2) : undefined;
355
- const rigidBody1Events = rigidBodyHandle1 ? rigidBodyEvents.get(rigidBodyHandle1) : undefined;
356
- const rigidBody2Events = rigidBodyHandle2 ? rigidBodyEvents.get(rigidBodyHandle2) : undefined;
357
- const collider1State = colliderStates.get(collider1.handle);
358
- const collider2State = colliderStates.get(collider2.handle);
359
- const rigidBody1State = rigidBodyHandle1 ? rigidBodyStates.get(rigidBodyHandle1) : undefined;
360
- const rigidBody2State = rigidBodyHandle2 ? rigidBodyStates.get(rigidBodyHandle2) : undefined;
361
-
362
401
  if (started) {
363
- world.contactPair(collider1, collider2, (manifold, flipped) => {
364
- var _rigidBody1Events$onC, _rigidBody2Events$onC, _collider1Events$onCo, _collider2Events$onCo;
402
+ world.contactPair(source1.collider.object, source2.collider.object, (manifold, flipped) => {
403
+ var _source1$rigidBody$ev, _source1$rigidBody$ev2, _source2$collider$sta, _source2$rigidBody$st, _source2$rigidBody$ev, _source2$rigidBody$ev2, _source1$collider$sta, _source1$rigidBody$st, _source1$collider$eve, _source1$collider$eve2, _source2$collider$sta2, _source2$rigidBody$st2, _source2$collider$eve, _source2$collider$eve2, _source1$collider$sta2, _source1$rigidBody$st2;
365
404
 
366
405
  /* RigidBody events */
367
- rigidBody1Events === null || rigidBody1Events === void 0 ? void 0 : (_rigidBody1Events$onC = rigidBody1Events.onCollisionEnter) === null || _rigidBody1Events$onC === void 0 ? void 0 : _rigidBody1Events$onC.call(rigidBody1Events, {
368
- rigidBody: rigidBody2,
369
- collider: collider2,
370
- colliderObject: collider2State === null || collider2State === void 0 ? void 0 : collider2State.object,
371
- rigidBodyObject: rigidBody2State === null || rigidBody2State === void 0 ? void 0 : rigidBody2State.object,
406
+ (_source1$rigidBody$ev = source1.rigidBody.events) === null || _source1$rigidBody$ev === void 0 ? void 0 : (_source1$rigidBody$ev2 = _source1$rigidBody$ev.onCollisionEnter) === null || _source1$rigidBody$ev2 === void 0 ? void 0 : _source1$rigidBody$ev2.call(_source1$rigidBody$ev, {
407
+ rigidBody: source2.rigidBody.object,
408
+ collider: source2.collider.object,
409
+ colliderObject: (_source2$collider$sta = source2.collider.state) === null || _source2$collider$sta === void 0 ? void 0 : _source2$collider$sta.object,
410
+ rigidBodyObject: (_source2$rigidBody$st = source2.rigidBody.state) === null || _source2$rigidBody$st === void 0 ? void 0 : _source2$rigidBody$st.object,
372
411
  manifold,
373
412
  flipped
374
413
  });
375
- rigidBody2Events === null || rigidBody2Events === void 0 ? void 0 : (_rigidBody2Events$onC = rigidBody2Events.onCollisionEnter) === null || _rigidBody2Events$onC === void 0 ? void 0 : _rigidBody2Events$onC.call(rigidBody2Events, {
376
- rigidBody: rigidBody1,
377
- collider: collider1,
378
- colliderObject: collider1State === null || collider1State === void 0 ? void 0 : collider1State.object,
379
- rigidBodyObject: rigidBody1State === null || rigidBody1State === void 0 ? void 0 : rigidBody1State.object,
414
+ (_source2$rigidBody$ev = source2.rigidBody.events) === null || _source2$rigidBody$ev === void 0 ? void 0 : (_source2$rigidBody$ev2 = _source2$rigidBody$ev.onCollisionEnter) === null || _source2$rigidBody$ev2 === void 0 ? void 0 : _source2$rigidBody$ev2.call(_source2$rigidBody$ev, {
415
+ rigidBody: source1.rigidBody.object,
416
+ collider: source1.collider.object,
417
+ colliderObject: (_source1$collider$sta = source1.collider.state) === null || _source1$collider$sta === void 0 ? void 0 : _source1$collider$sta.object,
418
+ rigidBodyObject: (_source1$rigidBody$st = source1.rigidBody.state) === null || _source1$rigidBody$st === void 0 ? void 0 : _source1$rigidBody$st.object,
380
419
  manifold,
381
420
  flipped
382
421
  });
383
422
  /* Collider events */
384
423
 
385
- collider1Events === null || collider1Events === void 0 ? void 0 : (_collider1Events$onCo = collider1Events.onCollisionEnter) === null || _collider1Events$onCo === void 0 ? void 0 : _collider1Events$onCo.call(collider1Events, {
386
- rigidBody: rigidBody2,
387
- collider: collider2,
388
- colliderObject: collider2State === null || collider2State === void 0 ? void 0 : collider2State.object,
389
- rigidBodyObject: rigidBody2State === null || rigidBody2State === void 0 ? void 0 : rigidBody2State.object,
424
+ (_source1$collider$eve = source1.collider.events) === null || _source1$collider$eve === void 0 ? void 0 : (_source1$collider$eve2 = _source1$collider$eve.onCollisionEnter) === null || _source1$collider$eve2 === void 0 ? void 0 : _source1$collider$eve2.call(_source1$collider$eve, {
425
+ rigidBody: source2.rigidBody.object,
426
+ collider: source2.collider.object,
427
+ colliderObject: (_source2$collider$sta2 = source2.collider.state) === null || _source2$collider$sta2 === void 0 ? void 0 : _source2$collider$sta2.object,
428
+ rigidBodyObject: (_source2$rigidBody$st2 = source2.rigidBody.state) === null || _source2$rigidBody$st2 === void 0 ? void 0 : _source2$rigidBody$st2.object,
390
429
  manifold,
391
430
  flipped
392
431
  });
393
- collider2Events === null || collider2Events === void 0 ? void 0 : (_collider2Events$onCo = collider2Events.onCollisionEnter) === null || _collider2Events$onCo === void 0 ? void 0 : _collider2Events$onCo.call(collider2Events, {
394
- rigidBody: rigidBody1,
395
- collider: collider1,
396
- colliderObject: collider1State === null || collider1State === void 0 ? void 0 : collider1State.object,
397
- rigidBodyObject: rigidBody1State === null || rigidBody1State === void 0 ? void 0 : rigidBody1State.object,
432
+ (_source2$collider$eve = source2.collider.events) === null || _source2$collider$eve === void 0 ? void 0 : (_source2$collider$eve2 = _source2$collider$eve.onCollisionEnter) === null || _source2$collider$eve2 === void 0 ? void 0 : _source2$collider$eve2.call(_source2$collider$eve, {
433
+ rigidBody: source1.rigidBody.object,
434
+ collider: source1.collider.object,
435
+ colliderObject: (_source1$collider$sta2 = source1.collider.state) === null || _source1$collider$sta2 === void 0 ? void 0 : _source1$collider$sta2.object,
436
+ rigidBodyObject: (_source1$rigidBody$st2 = source1.rigidBody.state) === null || _source1$rigidBody$st2 === void 0 ? void 0 : _source1$rigidBody$st2.object,
398
437
  manifold,
399
438
  flipped
400
439
  });
401
440
  });
402
441
  } else {
403
- var _rigidBody1Events$onC2, _rigidBody2Events$onC2, _collider1Events$onCo2, _collider2Events$onCo2;
442
+ var _source1$rigidBody$ev3, _source1$rigidBody$ev4, _source2$rigidBody$ev3, _source2$rigidBody$ev4, _source1$collider$eve3, _source1$collider$eve4, _source2$collider$eve3, _source2$collider$eve4;
404
443
 
405
- rigidBody1Events === null || rigidBody1Events === void 0 ? void 0 : (_rigidBody1Events$onC2 = rigidBody1Events.onCollisionExit) === null || _rigidBody1Events$onC2 === void 0 ? void 0 : _rigidBody1Events$onC2.call(rigidBody1Events, {
406
- rigidBody: rigidBody2,
407
- collider: collider2
444
+ (_source1$rigidBody$ev3 = source1.rigidBody.events) === null || _source1$rigidBody$ev3 === void 0 ? void 0 : (_source1$rigidBody$ev4 = _source1$rigidBody$ev3.onCollisionExit) === null || _source1$rigidBody$ev4 === void 0 ? void 0 : _source1$rigidBody$ev4.call(_source1$rigidBody$ev3, {
445
+ rigidBody: source2.rigidBody.object,
446
+ collider: source2.collider.object
408
447
  });
409
- rigidBody2Events === null || rigidBody2Events === void 0 ? void 0 : (_rigidBody2Events$onC2 = rigidBody2Events.onCollisionExit) === null || _rigidBody2Events$onC2 === void 0 ? void 0 : _rigidBody2Events$onC2.call(rigidBody2Events, {
410
- rigidBody: rigidBody1,
411
- collider: collider1
448
+ (_source2$rigidBody$ev3 = source2.rigidBody.events) === null || _source2$rigidBody$ev3 === void 0 ? void 0 : (_source2$rigidBody$ev4 = _source2$rigidBody$ev3.onCollisionExit) === null || _source2$rigidBody$ev4 === void 0 ? void 0 : _source2$rigidBody$ev4.call(_source2$rigidBody$ev3, {
449
+ rigidBody: source1.rigidBody.object,
450
+ collider: source1.collider.object
412
451
  });
413
- collider1Events === null || collider1Events === void 0 ? void 0 : (_collider1Events$onCo2 = collider1Events.onCollisionExit) === null || _collider1Events$onCo2 === void 0 ? void 0 : _collider1Events$onCo2.call(collider1Events, {
414
- rigidBody: rigidBody2,
415
- collider: collider2
452
+ (_source1$collider$eve3 = source1.collider.events) === null || _source1$collider$eve3 === void 0 ? void 0 : (_source1$collider$eve4 = _source1$collider$eve3.onCollisionExit) === null || _source1$collider$eve4 === void 0 ? void 0 : _source1$collider$eve4.call(_source1$collider$eve3, {
453
+ rigidBody: source2.rigidBody.object,
454
+ collider: source2.collider.object
416
455
  });
417
- collider2Events === null || collider2Events === void 0 ? void 0 : (_collider2Events$onCo2 = collider2Events.onCollisionExit) === null || _collider2Events$onCo2 === void 0 ? void 0 : _collider2Events$onCo2.call(collider2Events, {
418
- rigidBody: rigidBody1,
419
- collider: collider1
456
+ (_source2$collider$eve3 = source2.collider.events) === null || _source2$collider$eve3 === void 0 ? void 0 : (_source2$collider$eve4 = _source2$collider$eve3.onCollisionExit) === null || _source2$collider$eve4 === void 0 ? void 0 : _source2$collider$eve4.call(_source2$collider$eve3, {
457
+ rigidBody: source1.rigidBody.object,
458
+ collider: source1.collider.object
420
459
  });
421
460
  } // Sensor Intersections
422
461
 
423
462
 
424
463
  if (started) {
425
- if (world.intersectionPair(collider1, collider2)) {
426
- var _rigidBody1Events$onI, _rigidBody2Events$onI, _collider1Events$onIn, _collider2Events$onIn;
427
-
428
- rigidBody1Events === null || rigidBody1Events === void 0 ? void 0 : (_rigidBody1Events$onI = rigidBody1Events.onIntersectionEnter) === null || _rigidBody1Events$onI === void 0 ? void 0 : _rigidBody1Events$onI.call(rigidBody1Events, {
429
- rigidBody: rigidBody2,
430
- collider: collider2,
431
- colliderObject: collider2State === null || collider2State === void 0 ? void 0 : collider2State.object,
432
- rigidBodyObject: rigidBody2State === null || rigidBody2State === void 0 ? void 0 : rigidBody2State.object
464
+ if (world.intersectionPair(source1.collider.object, source2.collider.object)) {
465
+ var _source1$rigidBody$ev5, _source1$rigidBody$ev6, _source2$collider$sta3, _source2$rigidBody$st3, _source2$rigidBody$ev5, _source2$rigidBody$ev6, _source1$collider$sta3, _source1$rigidBody$st3, _source1$collider$eve5, _source1$collider$eve6, _source2$collider$sta4, _source2$rigidBody$st4, _source2$collider$eve5, _source2$collider$eve6, _source1$collider$sta4, _source1$rigidBody$st4;
466
+
467
+ (_source1$rigidBody$ev5 = source1.rigidBody.events) === null || _source1$rigidBody$ev5 === void 0 ? void 0 : (_source1$rigidBody$ev6 = _source1$rigidBody$ev5.onIntersectionEnter) === null || _source1$rigidBody$ev6 === void 0 ? void 0 : _source1$rigidBody$ev6.call(_source1$rigidBody$ev5, {
468
+ rigidBody: source2.rigidBody.object,
469
+ collider: source2.collider.object,
470
+ colliderObject: (_source2$collider$sta3 = source2.collider.state) === null || _source2$collider$sta3 === void 0 ? void 0 : _source2$collider$sta3.object,
471
+ rigidBodyObject: (_source2$rigidBody$st3 = source2.rigidBody.state) === null || _source2$rigidBody$st3 === void 0 ? void 0 : _source2$rigidBody$st3.object
433
472
  });
434
- rigidBody2Events === null || rigidBody2Events === void 0 ? void 0 : (_rigidBody2Events$onI = rigidBody2Events.onIntersectionEnter) === null || _rigidBody2Events$onI === void 0 ? void 0 : _rigidBody2Events$onI.call(rigidBody2Events, {
435
- rigidBody: rigidBody1,
436
- collider: collider1,
437
- colliderObject: collider1State === null || collider1State === void 0 ? void 0 : collider1State.object,
438
- rigidBodyObject: rigidBody1State === null || rigidBody1State === void 0 ? void 0 : rigidBody1State.object
473
+ (_source2$rigidBody$ev5 = source2.rigidBody.events) === null || _source2$rigidBody$ev5 === void 0 ? void 0 : (_source2$rigidBody$ev6 = _source2$rigidBody$ev5.onIntersectionEnter) === null || _source2$rigidBody$ev6 === void 0 ? void 0 : _source2$rigidBody$ev6.call(_source2$rigidBody$ev5, {
474
+ rigidBody: source1.rigidBody.object,
475
+ collider: source1.collider.object,
476
+ colliderObject: (_source1$collider$sta3 = source1.collider.state) === null || _source1$collider$sta3 === void 0 ? void 0 : _source1$collider$sta3.object,
477
+ rigidBodyObject: (_source1$rigidBody$st3 = source1.rigidBody.state) === null || _source1$rigidBody$st3 === void 0 ? void 0 : _source1$rigidBody$st3.object
439
478
  });
440
- collider1Events === null || collider1Events === void 0 ? void 0 : (_collider1Events$onIn = collider1Events.onIntersectionEnter) === null || _collider1Events$onIn === void 0 ? void 0 : _collider1Events$onIn.call(collider1Events, {
441
- rigidBody: rigidBody2,
442
- collider: collider2,
443
- colliderObject: collider2State === null || collider2State === void 0 ? void 0 : collider2State.object,
444
- rigidBodyObject: rigidBody2State === null || rigidBody2State === void 0 ? void 0 : rigidBody2State.object
479
+ (_source1$collider$eve5 = source1.collider.events) === null || _source1$collider$eve5 === void 0 ? void 0 : (_source1$collider$eve6 = _source1$collider$eve5.onIntersectionEnter) === null || _source1$collider$eve6 === void 0 ? void 0 : _source1$collider$eve6.call(_source1$collider$eve5, {
480
+ rigidBody: source2.rigidBody.object,
481
+ collider: source2.collider.object,
482
+ colliderObject: (_source2$collider$sta4 = source2.collider.state) === null || _source2$collider$sta4 === void 0 ? void 0 : _source2$collider$sta4.object,
483
+ rigidBodyObject: (_source2$rigidBody$st4 = source2.rigidBody.state) === null || _source2$rigidBody$st4 === void 0 ? void 0 : _source2$rigidBody$st4.object
445
484
  });
446
- collider2Events === null || collider2Events === void 0 ? void 0 : (_collider2Events$onIn = collider2Events.onIntersectionEnter) === null || _collider2Events$onIn === void 0 ? void 0 : _collider2Events$onIn.call(collider2Events, {
447
- rigidBody: rigidBody1,
448
- collider: collider1,
449
- colliderObject: collider1State === null || collider1State === void 0 ? void 0 : collider1State.object,
450
- rigidBodyObject: rigidBody1State === null || rigidBody1State === void 0 ? void 0 : rigidBody1State.object
485
+ (_source2$collider$eve5 = source2.collider.events) === null || _source2$collider$eve5 === void 0 ? void 0 : (_source2$collider$eve6 = _source2$collider$eve5.onIntersectionEnter) === null || _source2$collider$eve6 === void 0 ? void 0 : _source2$collider$eve6.call(_source2$collider$eve5, {
486
+ rigidBody: source1.rigidBody.object,
487
+ collider: source1.collider.object,
488
+ colliderObject: (_source1$collider$sta4 = source1.collider.state) === null || _source1$collider$sta4 === void 0 ? void 0 : _source1$collider$sta4.object,
489
+ rigidBodyObject: (_source1$rigidBody$st4 = source1.rigidBody.state) === null || _source1$rigidBody$st4 === void 0 ? void 0 : _source1$rigidBody$st4.object
451
490
  });
452
491
  }
453
492
  } else {
454
- var _rigidBody1Events$onI2, _rigidBody2Events$onI2, _collider1Events$onIn2, _collider2Events$onIn2;
493
+ var _source1$rigidBody$ev7, _source1$rigidBody$ev8, _source2$rigidBody$ev7, _source2$rigidBody$ev8, _source1$collider$eve7, _source1$collider$eve8, _source2$collider$eve7, _source2$collider$eve8;
455
494
 
456
- rigidBody1Events === null || rigidBody1Events === void 0 ? void 0 : (_rigidBody1Events$onI2 = rigidBody1Events.onIntersectionExit) === null || _rigidBody1Events$onI2 === void 0 ? void 0 : _rigidBody1Events$onI2.call(rigidBody1Events, {
457
- rigidBody: rigidBody2,
458
- collider: collider2
495
+ (_source1$rigidBody$ev7 = source1.rigidBody.events) === null || _source1$rigidBody$ev7 === void 0 ? void 0 : (_source1$rigidBody$ev8 = _source1$rigidBody$ev7.onIntersectionExit) === null || _source1$rigidBody$ev8 === void 0 ? void 0 : _source1$rigidBody$ev8.call(_source1$rigidBody$ev7, {
496
+ rigidBody: source2.rigidBody.object,
497
+ collider: source2.collider.object
459
498
  });
460
- rigidBody2Events === null || rigidBody2Events === void 0 ? void 0 : (_rigidBody2Events$onI2 = rigidBody2Events.onIntersectionExit) === null || _rigidBody2Events$onI2 === void 0 ? void 0 : _rigidBody2Events$onI2.call(rigidBody2Events, {
461
- rigidBody: rigidBody1,
462
- collider: collider1
499
+ (_source2$rigidBody$ev7 = source2.rigidBody.events) === null || _source2$rigidBody$ev7 === void 0 ? void 0 : (_source2$rigidBody$ev8 = _source2$rigidBody$ev7.onIntersectionExit) === null || _source2$rigidBody$ev8 === void 0 ? void 0 : _source2$rigidBody$ev8.call(_source2$rigidBody$ev7, {
500
+ rigidBody: source1.rigidBody.object,
501
+ collider: source1.collider.object
463
502
  });
464
- collider1Events === null || collider1Events === void 0 ? void 0 : (_collider1Events$onIn2 = collider1Events.onIntersectionExit) === null || _collider1Events$onIn2 === void 0 ? void 0 : _collider1Events$onIn2.call(collider1Events, {
465
- rigidBody: rigidBody2,
466
- collider: collider2
503
+ (_source1$collider$eve7 = source1.collider.events) === null || _source1$collider$eve7 === void 0 ? void 0 : (_source1$collider$eve8 = _source1$collider$eve7.onIntersectionExit) === null || _source1$collider$eve8 === void 0 ? void 0 : _source1$collider$eve8.call(_source1$collider$eve7, {
504
+ rigidBody: source2.rigidBody.object,
505
+ collider: source2.collider.object
467
506
  });
468
- collider2Events === null || collider2Events === void 0 ? void 0 : (_collider2Events$onIn2 = collider2Events.onIntersectionExit) === null || _collider2Events$onIn2 === void 0 ? void 0 : _collider2Events$onIn2.call(collider2Events, {
469
- rigidBody: rigidBody1,
470
- collider: collider1
507
+ (_source2$collider$eve7 = source2.collider.events) === null || _source2$collider$eve7 === void 0 ? void 0 : (_source2$collider$eve8 = _source2$collider$eve7.onIntersectionExit) === null || _source2$collider$eve8 === void 0 ? void 0 : _source2$collider$eve8.call(_source2$collider$eve7, {
508
+ rigidBody: source1.rigidBody.object,
509
+ collider: source1.collider.object
471
510
  });
472
511
  }
473
512
  });
513
+ eventQueue.drainContactForceEvents(event => {
514
+ var _source1$rigidBody$ev9, _source1$rigidBody$ev10, _source2$collider$sta5, _source2$rigidBody$st5, _source2$rigidBody$ev9, _source2$rigidBody$ev10, _source1$collider$sta5, _source1$rigidBody$st5, _source1$collider$eve9, _source1$collider$eve10, _source2$collider$sta6, _source2$rigidBody$st6, _source2$collider$eve9, _source2$collider$eve10, _source1$collider$sta6, _source1$rigidBody$st6;
515
+
516
+ const source1 = getSourceFromColliderHandle(event.collider1());
517
+ const source2 = getSourceFromColliderHandle(event.collider2()); // Collision Events
518
+
519
+ if (!(source1 !== null && source1 !== void 0 && source1.collider.object) || !(source2 !== null && source2 !== void 0 && source2.collider.object)) {
520
+ return;
521
+ }
522
+
523
+ (_source1$rigidBody$ev9 = source1.rigidBody.events) === null || _source1$rigidBody$ev9 === void 0 ? void 0 : (_source1$rigidBody$ev10 = _source1$rigidBody$ev9.onContactForce) === null || _source1$rigidBody$ev10 === void 0 ? void 0 : _source1$rigidBody$ev10.call(_source1$rigidBody$ev9, {
524
+ rigidBody: source2.rigidBody.object,
525
+ collider: source2.collider.object,
526
+ colliderObject: (_source2$collider$sta5 = source2.collider.state) === null || _source2$collider$sta5 === void 0 ? void 0 : _source2$collider$sta5.object,
527
+ rigidBodyObject: (_source2$rigidBody$st5 = source2.rigidBody.state) === null || _source2$rigidBody$st5 === void 0 ? void 0 : _source2$rigidBody$st5.object,
528
+ totalForce: event.totalForce(),
529
+ totalForceMagnitude: event.totalForceMagnitude(),
530
+ maxForceDirection: event.maxForceDirection(),
531
+ maxForceMagnitude: event.maxForceMagnitude()
532
+ });
533
+ (_source2$rigidBody$ev9 = source2.rigidBody.events) === null || _source2$rigidBody$ev9 === void 0 ? void 0 : (_source2$rigidBody$ev10 = _source2$rigidBody$ev9.onContactForce) === null || _source2$rigidBody$ev10 === void 0 ? void 0 : _source2$rigidBody$ev10.call(_source2$rigidBody$ev9, {
534
+ rigidBody: source1.rigidBody.object,
535
+ collider: source1.collider.object,
536
+ colliderObject: (_source1$collider$sta5 = source1.collider.state) === null || _source1$collider$sta5 === void 0 ? void 0 : _source1$collider$sta5.object,
537
+ rigidBodyObject: (_source1$rigidBody$st5 = source1.rigidBody.state) === null || _source1$rigidBody$st5 === void 0 ? void 0 : _source1$rigidBody$st5.object,
538
+ totalForce: event.totalForce(),
539
+ totalForceMagnitude: event.totalForceMagnitude(),
540
+ maxForceDirection: event.maxForceDirection(),
541
+ maxForceMagnitude: event.maxForceMagnitude()
542
+ });
543
+ (_source1$collider$eve9 = source1.collider.events) === null || _source1$collider$eve9 === void 0 ? void 0 : (_source1$collider$eve10 = _source1$collider$eve9.onContactForce) === null || _source1$collider$eve10 === void 0 ? void 0 : _source1$collider$eve10.call(_source1$collider$eve9, {
544
+ rigidBody: source2.rigidBody.object,
545
+ collider: source2.collider.object,
546
+ colliderObject: (_source2$collider$sta6 = source2.collider.state) === null || _source2$collider$sta6 === void 0 ? void 0 : _source2$collider$sta6.object,
547
+ rigidBodyObject: (_source2$rigidBody$st6 = source2.rigidBody.state) === null || _source2$rigidBody$st6 === void 0 ? void 0 : _source2$rigidBody$st6.object,
548
+ totalForce: event.totalForce(),
549
+ totalForceMagnitude: event.totalForceMagnitude(),
550
+ maxForceDirection: event.maxForceDirection(),
551
+ maxForceMagnitude: event.maxForceMagnitude()
552
+ });
553
+ (_source2$collider$eve9 = source2.collider.events) === null || _source2$collider$eve9 === void 0 ? void 0 : (_source2$collider$eve10 = _source2$collider$eve9.onContactForce) === null || _source2$collider$eve10 === void 0 ? void 0 : _source2$collider$eve10.call(_source2$collider$eve9, {
554
+ rigidBody: source1.rigidBody.object,
555
+ collider: source1.collider.object,
556
+ colliderObject: (_source1$collider$sta6 = source1.collider.state) === null || _source1$collider$sta6 === void 0 ? void 0 : _source1$collider$sta6.object,
557
+ rigidBodyObject: (_source1$rigidBody$st6 = source1.rigidBody.state) === null || _source1$rigidBody$st6 === void 0 ? void 0 : _source1$rigidBody$st6.object,
558
+ totalForce: event.totalForce(),
559
+ totalForceMagnitude: event.totalForceMagnitude(),
560
+ maxForceDirection: event.maxForceDirection(),
561
+ maxForceMagnitude: event.maxForceMagnitude()
562
+ });
563
+ });
474
564
  }, updatePriority);
475
565
  const api = useMemo(() => createWorldApi(getWorldRef), []);
476
566
  const context = useMemo(() => ({
@@ -583,148 +673,6 @@ function _objectSpread2(target) {
583
673
  return target;
584
674
  }
585
675
 
586
- const rigidBodyDescFromOptions = options => {
587
- const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
588
- const desc = new RigidBodyDesc(type);
589
- return desc;
590
- };
591
- const createRigidBodyState = ({
592
- rigidBody,
593
- object,
594
- setMatrix,
595
- getMatrix,
596
- worldScale
597
- }) => {
598
- object.updateWorldMatrix(true, false);
599
- const invertedWorldMatrix = object.parent.matrixWorld.clone().invert();
600
- return {
601
- object,
602
- rigidBody,
603
- invertedWorldMatrix,
604
- setMatrix: setMatrix ? setMatrix : matrix => {
605
- object.matrix.copy(matrix);
606
- },
607
- getMatrix: getMatrix ? getMatrix : matrix => matrix.copy(object.matrix),
608
- scale: worldScale || object.getWorldScale(_scale).clone(),
609
- isSleeping: false
610
- };
611
- };
612
- const mutableRigidBodyOptions = {
613
- gravityScale: (rb, value) => {
614
- rb.setGravityScale(value, true);
615
- },
616
- linearDamping: (rb, value) => {
617
- rb.setLinearDamping(value);
618
- },
619
- angularDamping: (rb, value) => {
620
- rb.setAngularDamping(value);
621
- },
622
- enabledRotations: (rb, [x, y, z]) => {
623
- rb.setEnabledRotations(x, y, z, true);
624
- },
625
- enabledTranslations: (rb, [x, y, z]) => {
626
- rb.setEnabledTranslations(x, y, z, true);
627
- },
628
- angularVelocity: (rb, [x, y, z]) => {
629
- rb.setAngvel({
630
- x,
631
- y,
632
- z
633
- }, true);
634
- },
635
- linearVelocity: (rb, [x, y, z]) => {
636
- rb.setLinvel({
637
- x,
638
- y,
639
- z
640
- }, true);
641
- },
642
- ccd: (rb, value) => {
643
- rb.enableCcd(value);
644
- },
645
- position: () => {},
646
- rotation: () => {},
647
- quaternion: () => {},
648
- scale: () => {}
649
- };
650
- const mutableRigidBodyOptionKeys = Object.keys(mutableRigidBodyOptions);
651
- const setRigidBodyOptions = (rigidBody, options, states, updateTranslations = true) => {
652
- if (!rigidBody) {
653
- return;
654
- }
655
-
656
- const state = states.get(rigidBody.handle);
657
-
658
- if (state) {
659
- if (updateTranslations) {
660
- state.object.updateWorldMatrix(true, false);
661
-
662
- _matrix4.copy(state.object.matrixWorld).decompose(_position, _rotation, _scale);
663
-
664
- rigidBody.setTranslation(_position, false);
665
- rigidBody.setRotation(_rotation, false);
666
- }
667
-
668
- mutableRigidBodyOptionKeys.forEach(key => {
669
- if (key in options) {
670
- mutableRigidBodyOptions[key](rigidBody, options[key]);
671
- }
672
- });
673
- }
674
- };
675
- const useUpdateRigidBodyOptions = (rigidBodyRef, props, states, updateTranslations = true) => {
676
- // TODO: Improve this, split each prop into its own effect
677
- const mutablePropsAsFlatArray = useMemo(() => mutableRigidBodyOptionKeys.flatMap(key => {
678
- return vectorToTuple(props[key]);
679
- }), [props]);
680
- useEffect(() => {
681
- if (Array.isArray(rigidBodyRef.current)) {
682
- for (const rigidBody of rigidBodyRef.current) {
683
- setRigidBodyOptions(rigidBody, props, states, updateTranslations);
684
- }
685
- } else if (rigidBodyRef.current) {
686
- setRigidBodyOptions(rigidBodyRef.current, props, states, updateTranslations);
687
- }
688
- }, mutablePropsAsFlatArray);
689
- };
690
- const useRigidBodyEvents = (rigidBodyRef, props, events) => {
691
- const {
692
- onWake,
693
- onSleep,
694
- onCollisionEnter,
695
- onCollisionExit,
696
- onIntersectionEnter,
697
- onIntersectionExit
698
- } = props;
699
- const eventHandlers = {
700
- onWake,
701
- onSleep,
702
- onCollisionEnter,
703
- onCollisionExit,
704
- onIntersectionEnter,
705
- onIntersectionExit
706
- };
707
- useEffect(() => {
708
- if (Array.isArray(rigidBodyRef.current)) {
709
- for (const rigidBody of rigidBodyRef.current) {
710
- events.set(rigidBody.handle, eventHandlers);
711
- }
712
- } else if (rigidBodyRef.current) {
713
- events.set(rigidBodyRef.current.handle, eventHandlers);
714
- }
715
-
716
- return () => {
717
- if (Array.isArray(rigidBodyRef.current)) {
718
- for (const rigidBody of rigidBodyRef.current) {
719
- events.delete(rigidBody.handle);
720
- }
721
- } else if (rigidBodyRef.current) {
722
- events.delete(rigidBodyRef.current.handle);
723
- }
724
- };
725
- }, [onWake, onSleep, onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit]);
726
- };
727
-
728
676
  const scaleColliderArgs = (shape, args, scale) => {
729
677
  const newArgs = args.slice(); // Heightfield uses a vector
730
678
 
@@ -981,21 +929,30 @@ const useColliderEvents = (collidersRef, props, events) => {
981
929
  onCollisionEnter,
982
930
  onCollisionExit,
983
931
  onIntersectionEnter,
984
- onIntersectionExit
932
+ onIntersectionExit,
933
+ onContactForce
985
934
  } = props;
986
935
  useEffect(() => {
987
936
  var _collidersRef$current;
988
937
 
989
938
  (_collidersRef$current = collidersRef.current) === null || _collidersRef$current === void 0 ? void 0 : _collidersRef$current.forEach(collider => {
990
- if (onCollisionEnter || onCollisionExit || onIntersectionEnter || onIntersectionExit) {
939
+ const hasCollisionEvent = !!(onCollisionEnter || onCollisionExit || onIntersectionEnter || onIntersectionExit);
940
+ const hasContactForceEvent = !!onContactForce;
941
+
942
+ if (hasCollisionEvent && hasContactForceEvent) {
943
+ collider.setActiveEvents(ActiveEvents.COLLISION_EVENTS | ActiveEvents.CONTACT_FORCE_EVENTS);
944
+ } else if (hasCollisionEvent) {
991
945
  collider.setActiveEvents(ActiveEvents.COLLISION_EVENTS);
946
+ } else if (hasContactForceEvent) {
947
+ collider.setActiveEvents(ActiveEvents.CONTACT_FORCE_EVENTS);
992
948
  }
993
949
 
994
950
  events.set(collider.handle, {
995
951
  onCollisionEnter,
996
952
  onCollisionExit,
997
953
  onIntersectionEnter,
998
- onIntersectionExit
954
+ onIntersectionExit,
955
+ onContactForce
999
956
  });
1000
957
  });
1001
958
  return () => {
@@ -1003,7 +960,152 @@ const useColliderEvents = (collidersRef, props, events) => {
1003
960
 
1004
961
  (_collidersRef$current2 = collidersRef.current) === null || _collidersRef$current2 === void 0 ? void 0 : _collidersRef$current2.forEach(collider => events.delete(collider.handle));
1005
962
  };
1006
- }, [onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit]);
963
+ }, [onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit, onContactForce]);
964
+ };
965
+
966
+ const rigidBodyDescFromOptions = options => {
967
+ const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
968
+ const desc = new RigidBodyDesc(type);
969
+ return desc;
970
+ };
971
+ const createRigidBodyState = ({
972
+ rigidBody,
973
+ object,
974
+ setMatrix,
975
+ getMatrix,
976
+ worldScale
977
+ }) => {
978
+ object.updateWorldMatrix(true, false);
979
+ const invertedWorldMatrix = object.parent.matrixWorld.clone().invert();
980
+ return {
981
+ object,
982
+ rigidBody,
983
+ invertedWorldMatrix,
984
+ setMatrix: setMatrix ? setMatrix : matrix => {
985
+ object.matrix.copy(matrix);
986
+ },
987
+ getMatrix: getMatrix ? getMatrix : matrix => matrix.copy(object.matrix),
988
+ scale: worldScale || object.getWorldScale(_scale).clone(),
989
+ isSleeping: false
990
+ };
991
+ };
992
+ const mutableRigidBodyOptions = {
993
+ gravityScale: (rb, value) => {
994
+ rb.setGravityScale(value, true);
995
+ },
996
+ linearDamping: (rb, value) => {
997
+ rb.setLinearDamping(value);
998
+ },
999
+ angularDamping: (rb, value) => {
1000
+ rb.setAngularDamping(value);
1001
+ },
1002
+ enabledRotations: (rb, [x, y, z]) => {
1003
+ rb.setEnabledRotations(x, y, z, true);
1004
+ },
1005
+ enabledTranslations: (rb, [x, y, z]) => {
1006
+ rb.setEnabledTranslations(x, y, z, true);
1007
+ },
1008
+ angularVelocity: (rb, [x, y, z]) => {
1009
+ rb.setAngvel({
1010
+ x,
1011
+ y,
1012
+ z
1013
+ }, true);
1014
+ },
1015
+ linearVelocity: (rb, [x, y, z]) => {
1016
+ rb.setLinvel({
1017
+ x,
1018
+ y,
1019
+ z
1020
+ }, true);
1021
+ },
1022
+ ccd: (rb, value) => {
1023
+ rb.enableCcd(value);
1024
+ },
1025
+ userData: (rb, value) => {
1026
+ rb.userData = value;
1027
+ },
1028
+ position: () => {},
1029
+ rotation: () => {},
1030
+ quaternion: () => {},
1031
+ scale: () => {}
1032
+ };
1033
+ const mutableRigidBodyOptionKeys = Object.keys(mutableRigidBodyOptions);
1034
+ const setRigidBodyOptions = (rigidBody, options, states, updateTranslations = true) => {
1035
+ if (!rigidBody) {
1036
+ return;
1037
+ }
1038
+
1039
+ const state = states.get(rigidBody.handle);
1040
+
1041
+ if (state) {
1042
+ if (updateTranslations) {
1043
+ state.object.updateWorldMatrix(true, false);
1044
+
1045
+ _matrix4.copy(state.object.matrixWorld).decompose(_position, _rotation, _scale);
1046
+
1047
+ rigidBody.setTranslation(_position, false);
1048
+ rigidBody.setRotation(_rotation, false);
1049
+ }
1050
+
1051
+ mutableRigidBodyOptionKeys.forEach(key => {
1052
+ if (key in options) {
1053
+ mutableRigidBodyOptions[key](rigidBody, options[key]);
1054
+ }
1055
+ });
1056
+ }
1057
+ };
1058
+ const useUpdateRigidBodyOptions = (rigidBodyRef, props, states, updateTranslations = true) => {
1059
+ // TODO: Improve this, split each prop into its own effect
1060
+ const mutablePropsAsFlatArray = useMemo(() => mutableRigidBodyOptionKeys.flatMap(key => {
1061
+ return vectorToTuple(props[key]);
1062
+ }), [props]);
1063
+ useEffect(() => {
1064
+ if (Array.isArray(rigidBodyRef.current)) {
1065
+ for (const rigidBody of rigidBodyRef.current) {
1066
+ setRigidBodyOptions(rigidBody, props, states, updateTranslations);
1067
+ }
1068
+ } else if (rigidBodyRef.current) {
1069
+ setRigidBodyOptions(rigidBodyRef.current, props, states, updateTranslations);
1070
+ }
1071
+ }, mutablePropsAsFlatArray);
1072
+ };
1073
+ const useRigidBodyEvents = (rigidBodyRef, props, events) => {
1074
+ const {
1075
+ onWake,
1076
+ onSleep,
1077
+ onCollisionEnter,
1078
+ onCollisionExit,
1079
+ onIntersectionEnter,
1080
+ onIntersectionExit
1081
+ } = props;
1082
+ const eventHandlers = {
1083
+ onWake,
1084
+ onSleep,
1085
+ onCollisionEnter,
1086
+ onCollisionExit,
1087
+ onIntersectionEnter,
1088
+ onIntersectionExit
1089
+ };
1090
+ useEffect(() => {
1091
+ if (Array.isArray(rigidBodyRef.current)) {
1092
+ for (const rigidBody of rigidBodyRef.current) {
1093
+ events.set(rigidBody.handle, eventHandlers);
1094
+ }
1095
+ } else if (rigidBodyRef.current) {
1096
+ events.set(rigidBodyRef.current.handle, eventHandlers);
1097
+ }
1098
+
1099
+ return () => {
1100
+ if (Array.isArray(rigidBodyRef.current)) {
1101
+ for (const rigidBody of rigidBodyRef.current) {
1102
+ events.delete(rigidBody.handle);
1103
+ }
1104
+ } else if (rigidBodyRef.current) {
1105
+ events.delete(rigidBodyRef.current.handle);
1106
+ }
1107
+ };
1108
+ }, [onWake, onSleep, onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit]);
1007
1109
  };
1008
1110
 
1009
1111
  const useRapier = () => {
@@ -1056,10 +1158,8 @@ const useRigidBody = (options = {}) => {
1056
1158
 
1057
1159
  if (!ref.current) {
1058
1160
  ref.current = new Object3D();
1059
- } // isSleeping used for onSleep and onWake events
1060
-
1161
+ }
1061
1162
 
1062
- ref.current.userData.isSleeping = false;
1063
1163
  rigidBodyStates.set(rigidBody.handle, createRigidBodyState({
1064
1164
  rigidBody,
1065
1165
  object: ref.current
@@ -1170,7 +1270,8 @@ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/React.forwardRef((props, for
1170
1270
  position,
1171
1271
  rotation,
1172
1272
  quaternion,
1173
- scale
1273
+ scale,
1274
+ name
1174
1275
  } = props;
1175
1276
  const {
1176
1277
  world,
@@ -1230,7 +1331,8 @@ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/React.forwardRef((props, for
1230
1331
  rotation: rotation,
1231
1332
  quaternion: quaternion,
1232
1333
  scale: scale,
1233
- ref: ref
1334
+ ref: ref,
1335
+ name: name
1234
1336
  }, children);
1235
1337
  }));
1236
1338
  const CuboidCollider = /*#__PURE__*/React.forwardRef((props, ref) => {