@react-three/rapier 0.2.0 → 0.4.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.
@@ -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
 
@@ -63,11 +63,11 @@ const scaleColliderArgs = (shape, args, scale) => {
63
63
  const scaleArray = [scale.x, scale.y, scale.z];
64
64
  return newArgs.map((arg, index) => scaleArray[index] * arg);
65
65
  };
66
- const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
66
+ const createColliderFromOptions = (options, world, rigidBody, 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);
@@ -105,10 +110,10 @@ const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
105
110
  });
106
111
  }
107
112
 
108
- const collider = world.createCollider(colliderDesc, rigidBodyHandle);
113
+ const collider = world.createCollider(colliderDesc, rigidBody);
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,7 +186,12 @@ const createCollidersFromChildren = (object, rigidBody, type, world) => {
181
186
  z: rz,
182
187
  w: rw
183
188
  });
184
- const collider = world.createCollider(desc, rigidBody.handle);
189
+
190
+ if (hasCollisionEvents) {
191
+ desc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
192
+ }
193
+
194
+ const collider = world.createCollider(desc, rigidBody);
185
195
  colliders.push(collider);
186
196
  }
187
197
  });
@@ -249,6 +259,31 @@ const createRigidBodyApi = ref => {
249
259
  w
250
260
  } = ref.current().rotation();
251
261
  return new three.Quaternion(x, y, z, w);
262
+ },
263
+
264
+ setNextKinematicRotation({
265
+ x,
266
+ y,
267
+ z
268
+ }) {
269
+ ref.current().setNextKinematicRotation({
270
+ x,
271
+ y,
272
+ z,
273
+ w: 1
274
+ });
275
+ },
276
+
277
+ setNextKinematicTranslation({
278
+ x,
279
+ y,
280
+ z
281
+ }) {
282
+ ref.current().setNextKinematicTranslation({
283
+ x,
284
+ y,
285
+ z
286
+ });
252
287
  }
253
288
 
254
289
  };
@@ -270,10 +305,10 @@ const createWorldApi = ref => {
270
305
  getCollider: handle => ref.current().getCollider(handle),
271
306
  getRigidBody: handle => ref.current().getRigidBody(handle),
272
307
  createRigidBody: desc => ref.current().createRigidBody(desc),
273
- createCollider: (desc, rigidBodyHandle) => ref.current().createCollider(desc, rigidBodyHandle),
308
+ createCollider: (desc, rigidBody) => ref.current().createCollider(desc, rigidBody),
274
309
  removeRigidBody: rigidBody => ref.current().removeRigidBody(rigidBody),
275
310
  removeCollider: collider => ref.current().removeCollider(collider, true),
276
- createImpulseJoint: (params, rigidBodyA, rigidBodyB) => ref.current().createImpulseJoint(params, rigidBodyA, rigidBodyB),
311
+ createImpulseJoint: (params, rigidBodyA, rigidBodyB) => ref.current().createImpulseJoint(params, rigidBodyA, rigidBodyB, true),
277
312
  removeImpulseJoint: joint => ref.current().removeImpulseJoint(joint, true),
278
313
  forEachCollider: callback => ref.current().forEachCollider(callback)
279
314
  };
@@ -316,9 +351,11 @@ const Physics = ({
316
351
  return worldRef.current;
317
352
  });
318
353
  const [colliderMeshes] = React.useState(() => new Map());
319
- const [rigidBodyMeshes] = React.useState(() => new Map()); // Init world
354
+ const [rigidBodyMeshes] = React.useState(() => new Map());
355
+ const [rigidBodyEvents] = React.useState(() => new Map());
356
+ const [eventQueue] = React.useState(() => new rapier3dCompat.EventQueue(false)); // Init world
320
357
 
321
- React.useLayoutEffect(() => {
358
+ React.useEffect(() => {
322
359
  const world = getWorldRef.current();
323
360
  return () => {
324
361
  if (world) {
@@ -336,10 +373,27 @@ const Physics = ({
336
373
  const now = performance.now();
337
374
  const delta = Math.min(100, now - time.current);
338
375
  world.timestep = delta / 1000;
339
- world.step(); // Update meshes
376
+ world.step(eventQueue); // Update meshes
340
377
 
341
378
  rigidBodyMeshes.forEach((mesh, handle) => {
342
379
  const rigidBody = world.getRigidBody(handle);
380
+ const events = rigidBodyEvents.get(handle);
381
+
382
+ if (events !== null && events !== void 0 && events.onSleep || events !== null && events !== void 0 && events.onWake) {
383
+ if (rigidBody.isSleeping() && !mesh.userData.isSleeping) {
384
+ var _events$onSleep;
385
+
386
+ events === null || events === void 0 ? void 0 : (_events$onSleep = events.onSleep) === null || _events$onSleep === void 0 ? void 0 : _events$onSleep.call(events);
387
+ }
388
+
389
+ if (!rigidBody.isSleeping() && mesh.userData.isSleeping) {
390
+ var _events$onWake;
391
+
392
+ events === null || events === void 0 ? void 0 : (_events$onWake = events.onWake) === null || _events$onWake === void 0 ? void 0 : _events$onWake.call(events);
393
+ }
394
+
395
+ mesh.userData.isSleeping = rigidBody.isSleeping();
396
+ }
343
397
 
344
398
  if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !mesh.parent) {
345
399
  return;
@@ -367,6 +421,50 @@ const Physics = ({
367
421
  o.updateMatrix();
368
422
  mesh.position.setFromMatrixPosition(o.matrix);
369
423
  mesh.rotation.setFromRotationMatrix(o.matrix);
424
+ }); // Collision events
425
+
426
+ eventQueue.drainCollisionEvents((handle1, handle2, started) => {
427
+ var _collider1$parent, _collider2$parent;
428
+
429
+ const collider1 = world.getCollider(handle1);
430
+ const collider2 = world.getCollider(handle2);
431
+ const rigidBodyHandle1 = (_collider1$parent = collider1.parent()) === null || _collider1$parent === void 0 ? void 0 : _collider1$parent.handle;
432
+ const rigidBodyHandle2 = (_collider2$parent = collider2.parent()) === null || _collider2$parent === void 0 ? void 0 : _collider2$parent.handle;
433
+
434
+ if (!collider1 || !collider2 || !rigidBodyHandle1 || !rigidBodyHandle2) {
435
+ return;
436
+ }
437
+
438
+ const rigidBody1 = world.getRigidBody(rigidBodyHandle1);
439
+ const rigidBody2 = world.getRigidBody(rigidBodyHandle2);
440
+ const events1 = rigidBodyEvents.get(rigidBodyHandle1);
441
+ const events2 = rigidBodyEvents.get(rigidBodyHandle2);
442
+
443
+ if (started) {
444
+ world.contactPair(collider1, collider2, (manifold, flipped) => {
445
+ var _events1$onCollisionE, _events2$onCollisionE;
446
+
447
+ events1 === null || events1 === void 0 ? void 0 : (_events1$onCollisionE = events1.onCollisionEnter) === null || _events1$onCollisionE === void 0 ? void 0 : _events1$onCollisionE.call(events1, {
448
+ target: rigidBody2,
449
+ manifold,
450
+ flipped
451
+ });
452
+ events2 === null || events2 === void 0 ? void 0 : (_events2$onCollisionE = events2.onCollisionEnter) === null || _events2$onCollisionE === void 0 ? void 0 : _events2$onCollisionE.call(events2, {
453
+ target: rigidBody1,
454
+ manifold,
455
+ flipped
456
+ });
457
+ });
458
+ } else {
459
+ var _events1$onCollisionE2, _events2$onCollisionE2;
460
+
461
+ events1 === null || events1 === void 0 ? void 0 : (_events1$onCollisionE2 = events1.onCollisionExit) === null || _events1$onCollisionE2 === void 0 ? void 0 : _events1$onCollisionE2.call(events1, {
462
+ target: rigidBody2
463
+ });
464
+ events2 === null || events2 === void 0 ? void 0 : (_events2$onCollisionE2 = events2.onCollisionExit) === null || _events2$onCollisionE2 === void 0 ? void 0 : _events2$onCollisionE2.call(events2, {
465
+ target: rigidBody1
466
+ });
467
+ }
370
468
  });
371
469
  time.current = now;
372
470
  });
@@ -379,7 +477,8 @@ const Physics = ({
379
477
  gravity: _gravity
380
478
  },
381
479
  colliderMeshes,
382
- rigidBodyMeshes
480
+ rigidBodyMeshes,
481
+ rigidBodyEvents
383
482
  }), []);
384
483
  return /*#__PURE__*/React__default["default"].createElement(RapierContext.Provider, {
385
484
  value: context
@@ -435,7 +534,8 @@ const useRigidBody = (options = {}) => {
435
534
  rapier,
436
535
  world,
437
536
  rigidBodyMeshes,
438
- physicsOptions
537
+ physicsOptions,
538
+ rigidBodyEvents
439
539
  } = useRapier();
440
540
  const ref = React.useRef(); // Create rigidbody
441
541
 
@@ -456,7 +556,7 @@ const useRigidBody = (options = {}) => {
456
556
  z: avz
457
557
  }).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled);
458
558
  const rigidBody = world.createRigidBody(desc);
459
- rigidBodyRef.current = rigidBody;
559
+ rigidBodyRef.current = world.getRigidBody(rigidBody.handle);
460
560
  }
461
561
 
462
562
  return rigidBodyRef.current;
@@ -470,9 +570,11 @@ const useRigidBody = (options = {}) => {
470
570
 
471
571
  if (!ref.current) {
472
572
  ref.current = new three.Object3D();
473
- } // Get intitial world transforms
573
+ } // isSleeping used for onSleep and onWake events
474
574
 
475
575
 
576
+ ref.current.userData.isSleeping = false; // Get intitial world transforms
577
+
476
578
  const worldPosition = ref.current.getWorldPosition(new three.Vector3());
477
579
  const worldRotation = ref.current.getWorldQuaternion(new three.Quaternion());
478
580
  const scale = ((_ref$current$parent = ref.current.parent) === null || _ref$current$parent === void 0 ? void 0 : _ref$current$parent.getWorldScale(new three.Vector3())) || {
@@ -489,6 +591,7 @@ const useRigidBody = (options = {}) => {
489
591
  y: worldPosition.y + y * scale.y,
490
592
  z: worldPosition.z + z * scale.z
491
593
  }, false);
594
+ console.log(rigidBody.isKinematic());
492
595
  const eulerAngles = new three.Euler(rx, ry, rz, 'XYZ');
493
596
  const rotation = new three.Quaternion().setFromEuler(eulerAngles).multiply(worldRotation);
494
597
  rigidBody.setRotation({
@@ -500,16 +603,31 @@ const useRigidBody = (options = {}) => {
500
603
  rigidBody.resetForces(false);
501
604
  rigidBody.resetTorques(false);
502
605
  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) : [];
606
+ const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
607
+ const autoColliders = colliderSetting !== false ? createCollidersFromChildren(ref.current, rigidBody, colliderSetting, world, hasCollisionEvents) : [];
504
608
  rigidBody.wakeUp();
505
609
  rigidBodyMeshes.set(rigidBody.handle, ref.current);
506
610
  return () => {
611
+ const actualBody = world.getRigidBody(rigidBody.handle);
612
+ world.removeRigidBody(actualBody);
507
613
  autoColliders.forEach(collider => world.removeCollider(collider));
508
- world.removeRigidBody(rigidBody);
509
614
  rigidBodyRef.current = undefined;
510
615
  rigidBodyMeshes.delete(rigidBody.handle);
511
616
  };
512
- }, []);
617
+ }, []); // Events
618
+
619
+ React.useEffect(() => {
620
+ const rigidBody = getRigidBodyRef.current();
621
+ rigidBodyEvents.set(rigidBody.handle, {
622
+ onCollisionEnter: options === null || options === void 0 ? void 0 : options.onCollisionEnter,
623
+ onCollisionExit: options === null || options === void 0 ? void 0 : options.onCollisionExit,
624
+ onSleep: options === null || options === void 0 ? void 0 : options.onSleep,
625
+ onWake: options === null || options === void 0 ? void 0 : options.onWake
626
+ });
627
+ return () => {
628
+ rigidBodyEvents.delete(rigidBody.handle);
629
+ };
630
+ }, [options.onCollisionEnter, options.onCollisionExit]);
513
631
  const api = React.useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
514
632
  return [ref, api];
515
633
  };
@@ -521,7 +639,7 @@ const useCollider = (body, options = {}) => {
521
639
  const objectRef = React.useRef();
522
640
  const getColliderRef = React.useRef(() => {
523
641
  if (!colliderRef.current) {
524
- colliderRef.current = createColliderFromOptions(options, world, body.handle);
642
+ colliderRef.current = createColliderFromOptions(options, world, world.getRigidBody(body.handle));
525
643
  }
526
644
 
527
645
  return colliderRef.current;
@@ -547,7 +665,7 @@ const useRigidBodyWithCollider = (rigidBodyOptions, colliderOptions) => {
547
665
  }
548
666
 
549
667
  const scale = ref.current.getWorldScale(new three.Vector3());
550
- const collider = createColliderFromOptions(colliderOptions, world, rigidBody.handle, scale);
668
+ const collider = createColliderFromOptions(colliderOptions, world, world.getRigidBody(rigidBody.handle), scale);
551
669
  return () => {
552
670
  world.removeCollider(collider);
553
671
  };
@@ -703,7 +821,6 @@ const useImpulseJoint = (body1, body2, params) => {
703
821
  const joint = getJointRef.current();
704
822
  return () => {
705
823
  if (joint) {
706
- console.log('remove joint', joint);
707
824
  world.removeImpulseJoint(joint);
708
825
  jointRef.current = undefined;
709
826
  }
@@ -823,7 +940,7 @@ const _excluded = ["children"],
823
940
  _excluded2 = ["children"];
824
941
  const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
825
942
 
826
- const useParentRigidBody = () => React.useContext(RigidBodyContext); // RigidBody
943
+ const useRigidBodyContext = () => React.useContext(RigidBodyContext); // RigidBody
827
944
 
828
945
 
829
946
  const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
@@ -835,7 +952,7 @@ const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
835
952
  const [object, rigidBody] = useRigidBody(props);
836
953
  React.useImperativeHandle(ref, () => rigidBody);
837
954
  return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
838
- value: [object, rigidBody]
955
+ value: [object, rigidBody, !!(props.onCollisionEnter || props.onCollisionExit)]
839
956
  }, /*#__PURE__*/React__default["default"].createElement("object3D", {
840
957
  ref: object
841
958
  }, children));
@@ -850,11 +967,11 @@ const AnyCollider = _ref2 => {
850
967
  const {
851
968
  world
852
969
  } = useRapier();
853
- const [, rigidBody] = useParentRigidBody();
970
+ const [, rigidBody, hasCollisionEvents] = useRigidBodyContext();
854
971
  const ref = React.useRef(null);
855
972
  React.useEffect(() => {
856
973
  const scale = ref.current.getWorldScale(new three.Vector3());
857
- const collider = createColliderFromOptions(props, world, rigidBody.handle, scale);
974
+ const collider = createColliderFromOptions(props, world, world.getRigidBody(rigidBody.handle), scale, hasCollisionEvents);
858
975
  return () => {
859
976
  world.removeCollider(collider);
860
977
  };
@@ -911,20 +1028,20 @@ const ConvexHullCollider = props => {
911
1028
  };
912
1029
 
913
1030
  const geometryFromCollider = collider => {
914
- switch (collider.shapeType()) {
1031
+ switch (collider.shape.type) {
915
1032
  case rapier3dCompat.ShapeType.Cuboid:
916
1033
  {
917
1034
  const {
918
1035
  x,
919
1036
  y,
920
1037
  z
921
- } = collider.halfExtents();
1038
+ } = collider.shape.halfExtents;
922
1039
  return new three.BoxBufferGeometry(x * 2 + 0.01, y * 2 + 0.01, z * 2 + 0.01);
923
1040
  }
924
1041
 
925
1042
  case rapier3dCompat.ShapeType.Ball:
926
1043
  {
927
- const r = collider.radius();
1044
+ const r = collider.shape.radius;
928
1045
  return new three.SphereBufferGeometry(r + +0.01, 8, 8);
929
1046
  }
930
1047
 
@@ -932,10 +1049,12 @@ const geometryFromCollider = collider => {
932
1049
  {
933
1050
  var _g$index;
934
1051
 
935
- const v = collider.vertices();
936
- const i = collider.indices();
937
- const g = new three.BufferGeometry();
938
- g.setAttribute("position", new three.BufferAttribute(v, 3));
1052
+ const v = collider.shape.vertices;
1053
+ const i = collider.shape.indices;
1054
+ const g = new three.BufferGeometry(); // Vertices are not always a float3darray (???), so we need to convert them
1055
+
1056
+ const safeVerts = Float32Array.from(v);
1057
+ g.setAttribute("position", new three.BufferAttribute(safeVerts, 3));
939
1058
  (_g$index = g.index) === null || _g$index === void 0 ? void 0 : _g$index.set(i);
940
1059
  g.setDrawRange(0, g.attributes.position.array.length / 3 - 1);
941
1060
  return g;
@@ -943,16 +1062,18 @@ const geometryFromCollider = collider => {
943
1062
 
944
1063
  case rapier3dCompat.ShapeType.ConvexPolyhedron:
945
1064
  {
946
- const cv = collider.vertices();
1065
+ const cv = collider.shape.vertices; // Vertices are not always a float3darray (???), so we need to convert them
1066
+
1067
+ const safeVerts = Float32Array.from(cv);
947
1068
  const cg = new three.BufferGeometry();
948
- cg.setAttribute("position", new three.BufferAttribute(cv, 3));
1069
+ cg.setAttribute("position", new three.BufferAttribute(safeVerts, 3));
949
1070
  return cg;
950
1071
  }
951
1072
 
952
1073
  case rapier3dCompat.ShapeType.Cylinder:
953
1074
  {
954
- const r = collider.radius();
955
- const h = collider.halfHeight();
1075
+ const r = collider.shape.radius;
1076
+ const h = collider.shape.halfHeight;
956
1077
  const g = new three.CylinderBufferGeometry(r, r, h);
957
1078
  return g;
958
1079
  }