@react-three/rapier 0.5.2 → 0.6.2

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.
@@ -2,10 +2,10 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var rapier3dCompat = require('@dimforge/rapier3d-compat');
5
6
  var React = require('react');
6
7
  var useAsset = require('use-asset');
7
8
  var fiber = require('@react-three/fiber');
8
- var rapier3dCompat = require('@dimforge/rapier3d-compat');
9
9
  var three = require('three');
10
10
 
11
11
  function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
@@ -30,19 +30,30 @@ function _interopNamespace(e) {
30
30
 
31
31
  var React__default = /*#__PURE__*/_interopDefault(React);
32
32
 
33
- const vectorArrayToObject = arr => {
33
+ const _quaternion = new three.Quaternion();
34
+ const _euler = new three.Euler();
35
+ const _vector3 = new three.Vector3();
36
+ new three.Object3D();
37
+ const _matrix4 = new three.Matrix4();
38
+
39
+ const vectorArrayToVector3 = arr => {
34
40
  const [x, y, z] = arr;
35
- return {
36
- x,
37
- y,
38
- z
39
- };
41
+ return new three.Vector3(x, y, z);
40
42
  };
41
- const quaternion = new three.Quaternion();
42
- const euler = new three.Euler();
43
43
  const vector3ToQuaternion = v => {
44
- return quaternion.setFromEuler(euler.setFromVector3(v));
44
+ return _quaternion.setFromEuler(_euler.setFromVector3(v));
45
45
  };
46
+ const rapierVector3ToVector3 = ({
47
+ x,
48
+ y,
49
+ z
50
+ }) => _vector3.set(x, y, z).clone();
51
+ const rapierQuaternionToQuaternion = ({
52
+ x,
53
+ y,
54
+ z,
55
+ w
56
+ }) => _quaternion.set(x, y, z, w);
46
57
  const rigidBodyTypeMap = {
47
58
  fixed: 1,
48
59
  dynamic: 0,
@@ -50,6 +61,17 @@ const rigidBodyTypeMap = {
50
61
  kinematicVelocity: 3
51
62
  };
52
63
  const rigidBodyTypeFromString = type => rigidBodyTypeMap[type];
64
+ const decomposeMatrix4 = m => {
65
+ const position = new three.Vector3();
66
+ const rotation = new three.Quaternion();
67
+ const scale = new three.Vector3();
68
+ m.decompose(position, rotation, scale);
69
+ return {
70
+ position,
71
+ rotation,
72
+ scale
73
+ };
74
+ };
53
75
  const scaleColliderArgs = (shape, args, scale) => {
54
76
  // Heightfield only scales the last arg
55
77
  const newArgs = args.slice();
@@ -135,8 +157,7 @@ const isChildOfMeshCollider = child => {
135
157
  const createCollidersFromChildren = (object, rigidBody, options, world, ignoreMeshColliders = true) => {
136
158
  const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
137
159
  const colliders = [];
138
- let desc;
139
- let offset = new three.Vector3();
160
+ new three.Vector3();
140
161
  object.traverse(child => {
141
162
  if ("isMesh" in child) {
142
163
  if (ignoreMeshColliders && isChildOfMeshCollider(child)) return;
@@ -154,62 +175,32 @@ const createCollidersFromChildren = (object, rigidBody, options, world, ignoreMe
154
175
  z: rz,
155
176
  w: rw
156
177
  } = new three.Quaternion().setFromEuler(child.rotation);
157
- const scale = child.getWorldScale(new three.Vector3());
158
-
159
- switch (options.colliders) {
160
- case "cuboid":
161
- {
162
- geometry.computeBoundingBox();
163
- const {
164
- boundingBox
165
- } = geometry;
166
- const size = boundingBox.getSize(new three.Vector3());
167
- boundingBox.getCenter(offset);
168
- desc = rapier3dCompat.ColliderDesc.cuboid(size.x / 2 * scale.x, size.y / 2 * scale.y, size.z / 2 * scale.z);
169
- }
170
- break;
178
+ const scale = child.getWorldScale(new three.Vector3()); // We translate the colliders based on the parent's world scale
171
179
 
172
- case "ball":
173
- {
174
- geometry.computeBoundingSphere();
175
- const {
176
- boundingSphere
177
- } = geometry;
178
- const radius = boundingSphere.radius * scale.x;
179
- offset.copy(boundingSphere.center);
180
- desc = rapier3dCompat.ColliderDesc.ball(radius);
181
- }
182
- break;
183
-
184
- case "trimesh":
185
- {
186
- var _g$index;
187
-
188
- const _g = geometry.clone().scale(scale.x, scale.y, scale.z);
180
+ const parentWorldScale = child.parent.getWorldScale(new three.Vector3());
181
+ const desc = colliderDescFromGeometry(geometry, options.colliders, scale, hasCollisionEvents);
182
+ const offset = new three.Vector3(0, 0, 0);
189
183
 
190
- desc = rapier3dCompat.ColliderDesc.trimesh(_g.attributes.position.array, (_g$index = _g.index) === null || _g$index === void 0 ? void 0 : _g$index.array);
191
- }
192
- break;
184
+ if (options.colliders === "cuboid") {
185
+ var _geometry$boundingBox;
193
186
 
194
- case "hull":
195
- const g = geometry.clone().scale(scale.x, scale.y, scale.z);
196
- {
197
- desc = rapier3dCompat.ColliderDesc.convexHull(g.attributes.position.array);
198
- }
199
- break;
200
- } // We translate the colliders based on the parent's world scale
187
+ geometry.computeBoundingBox();
188
+ (_geometry$boundingBox = geometry.boundingBox) === null || _geometry$boundingBox === void 0 ? void 0 : _geometry$boundingBox.getCenter(offset);
189
+ }
201
190
 
191
+ if (options.colliders === "ball") {
192
+ geometry.computeBoundingSphere();
193
+ offset.copy(geometry.boundingSphere.center);
194
+ }
202
195
 
203
- const parentWorldScale = child.parent.getWorldScale(new three.Vector3());
196
+ if (Number.isFinite(options.friction)) desc.setFriction(options.friction);
197
+ if (Number.isFinite(options.restitution)) desc.setRestitution(options.restitution);
204
198
  desc.setTranslation((x + offset.x) * parentWorldScale.x, (y + offset.y) * parentWorldScale.y, (z + offset.z) * parentWorldScale.z).setRotation({
205
199
  x: rx,
206
200
  y: ry,
207
201
  z: rz,
208
202
  w: rw
209
203
  });
210
- if (hasCollisionEvents) desc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
211
- if (Number.isFinite(options.friction)) desc.setFriction(options.friction);
212
- if (Number.isFinite(options.restitution)) desc.setRestitution(options.restitution);
213
204
  const actualRigidBody = world.getRigidBody(rigidBody === null || rigidBody === void 0 ? void 0 : rigidBody.handle);
214
205
  const collider = world.createCollider(desc, actualRigidBody);
215
206
  colliders.push(collider);
@@ -217,6 +208,53 @@ const createCollidersFromChildren = (object, rigidBody, options, world, ignoreMe
217
208
  });
218
209
  return colliders;
219
210
  };
211
+ const colliderDescFromGeometry = (geometry, colliders, scale, hasCollisionEvents) => {
212
+ let desc;
213
+
214
+ switch (colliders) {
215
+ case "cuboid":
216
+ {
217
+ geometry.computeBoundingBox();
218
+ const {
219
+ boundingBox
220
+ } = geometry;
221
+ const size = boundingBox.getSize(new three.Vector3());
222
+ desc = rapier3dCompat.ColliderDesc.cuboid(size.x / 2 * scale.x, size.y / 2 * scale.y, size.z / 2 * scale.z);
223
+ }
224
+ break;
225
+
226
+ case "ball":
227
+ {
228
+ geometry.computeBoundingSphere();
229
+ const {
230
+ boundingSphere
231
+ } = geometry;
232
+ const radius = boundingSphere.radius * scale.x;
233
+ desc = rapier3dCompat.ColliderDesc.ball(radius);
234
+ }
235
+ break;
236
+
237
+ case "trimesh":
238
+ {
239
+ var _g$index;
240
+
241
+ const _g = geometry.clone().scale(scale.x, scale.y, scale.z);
242
+
243
+ desc = rapier3dCompat.ColliderDesc.trimesh(_g.attributes.position.array, (_g$index = _g.index) === null || _g$index === void 0 ? void 0 : _g$index.array);
244
+ }
245
+ break;
246
+
247
+ case "hull":
248
+ const g = geometry.clone().scale(scale.x, scale.y, scale.z);
249
+ {
250
+ desc = rapier3dCompat.ColliderDesc.convexHull(g.attributes.position.array);
251
+ }
252
+ break;
253
+ }
254
+
255
+ if (hasCollisionEvents) desc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
256
+ return desc;
257
+ };
220
258
  const scaleVertices = (vertices, scale) => {
221
259
  const scaledVerts = Array.from(vertices);
222
260
 
@@ -228,6 +266,26 @@ const scaleVertices = (vertices, scale) => {
228
266
 
229
267
  return scaledVerts;
230
268
  };
269
+ const rigidBodyDescFromOptions = options => {
270
+ var _options$linearVeloci, _options$angularVeloc, _options$gravityScale, _options$canSleep, _options$ccd, _options$enabledRotat, _options$enabledTrans;
271
+
272
+ const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
273
+ const [lvx, lvy, lvz] = (_options$linearVeloci = options === null || options === void 0 ? void 0 : options.linearVelocity) !== null && _options$linearVeloci !== void 0 ? _options$linearVeloci : [0, 0, 0];
274
+ const [avx, avy, avz] = (_options$angularVeloc = options === null || options === void 0 ? void 0 : options.angularVelocity) !== null && _options$angularVeloc !== void 0 ? _options$angularVeloc : [0, 0, 0];
275
+ const gravityScale = (_options$gravityScale = options === null || options === void 0 ? void 0 : options.gravityScale) !== null && _options$gravityScale !== void 0 ? _options$gravityScale : 1;
276
+ const canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
277
+ const ccdEnabled = (_options$ccd = options === null || options === void 0 ? void 0 : options.ccd) !== null && _options$ccd !== void 0 ? _options$ccd : false;
278
+ const [erx, ery, erz] = (_options$enabledRotat = options === null || options === void 0 ? void 0 : options.enabledRotations) !== null && _options$enabledRotat !== void 0 ? _options$enabledRotat : [true, true, true];
279
+ const [etx, ety, etz] = (_options$enabledTrans = options === null || options === void 0 ? void 0 : options.enabledTranslations) !== null && _options$enabledTrans !== void 0 ? _options$enabledTrans : [true, true, true];
280
+ const desc = new rapier3dCompat.RigidBodyDesc(type).setLinvel(lvx, lvy, lvz).setAngvel({
281
+ x: avx,
282
+ y: avy,
283
+ z: avz
284
+ }).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled).enabledRotations(erx, ery, erz).enabledTranslations(etx, ety, etz);
285
+ if (options.lockRotations) desc.lockRotations();
286
+ if (options.lockTranslations) desc.lockTranslations();
287
+ return desc;
288
+ };
231
289
 
232
290
  const createRigidBodyApi = ref => {
233
291
  return {
@@ -329,18 +387,19 @@ const createRigidBodyApi = ref => {
329
387
  setEnabledRotations: (x, y, z) => ref.current().setEnabledRotations(x, y, z, true),
330
388
  setEnabledTranslations: (x, y, z) => ref.current().setEnabledTranslations(x, y, z, true)
331
389
  };
332
- }; // TODO: Flesh this out
390
+ };
391
+ const createInstancedRigidBodiesApi = bodiesGetter => ({
392
+ at: index => bodiesGetter.current()[index].api,
333
393
 
334
- const createColliderApi = ref => {
335
- return {
336
- raw: () => ref.current(),
394
+ forEach(callback) {
395
+ return bodiesGetter.current().map(b => b.api).forEach(callback);
396
+ },
337
397
 
338
- get handle() {
339
- return ref.current().handle;
340
- }
398
+ get count() {
399
+ return bodiesGetter.current().length;
400
+ }
341
401
 
342
- };
343
- };
402
+ }); // TODO: Flesh this out
344
403
  const createWorldApi = ref => {
345
404
  return {
346
405
  raw: () => ref.current(),
@@ -387,23 +446,23 @@ const importRapier = async () => {
387
446
  };
388
447
 
389
448
  const Physics = ({
390
- colliders: _colliders = 'cuboid',
449
+ colliders: _colliders = "cuboid",
391
450
  gravity: _gravity = [0, -9.81, 0],
392
451
  children,
393
- timeStep: _timeStep = 'vary'
452
+ timeStep: _timeStep = "vary"
394
453
  }) => {
395
454
  const rapier = useAsset.useAsset(importRapier);
396
455
  const worldRef = React.useRef();
397
456
  const getWorldRef = React.useRef(() => {
398
457
  if (!worldRef.current) {
399
- const world = new rapier.World(vectorArrayToObject(_gravity));
458
+ const world = new rapier.World(vectorArrayToVector3(_gravity));
400
459
  worldRef.current = world;
401
460
  }
402
461
 
403
462
  return worldRef.current;
404
463
  });
405
464
  const [colliderMeshes] = React.useState(() => new Map());
406
- const [rigidBodyMeshes] = React.useState(() => new Map());
465
+ const [rigidBodyStates] = React.useState(() => new Map());
407
466
  const [rigidBodyEvents] = React.useState(() => new Map());
408
467
  const [eventQueue] = React.useState(() => new rapier3dCompat.EventQueue(false)); // Init world
409
468
 
@@ -421,7 +480,7 @@ const Physics = ({
421
480
  const world = worldRef.current;
422
481
 
423
482
  if (world) {
424
- world.gravity = vectorArrayToObject(_gravity);
483
+ world.gravity = vectorArrayToVector3(_gravity);
425
484
  }
426
485
  }, [_gravity]);
427
486
  const time = React.useRef(performance.now());
@@ -433,7 +492,7 @@ const Physics = ({
433
492
  const now = performance.now();
434
493
  const delta = Math.min(100, now - time.current);
435
494
 
436
- if (_timeStep === 'vary') {
495
+ if (_timeStep === "vary") {
437
496
  world.timestep = delta / 1000;
438
497
  } else {
439
498
  world.timestep = _timeStep;
@@ -441,52 +500,35 @@ const Physics = ({
441
500
 
442
501
  world.step(eventQueue); // Update meshes
443
502
 
444
- rigidBodyMeshes.forEach((mesh, handle) => {
503
+ rigidBodyStates.forEach((state, handle) => {
445
504
  const rigidBody = world.getRigidBody(handle);
446
505
  const events = rigidBodyEvents.get(handle);
447
506
 
448
507
  if (events !== null && events !== void 0 && events.onSleep || events !== null && events !== void 0 && events.onWake) {
449
- if (rigidBody.isSleeping() && !mesh.userData.isSleeping) {
508
+ if (rigidBody.isSleeping() && !state.isSleeping) {
450
509
  var _events$onSleep;
451
510
 
452
511
  events === null || events === void 0 ? void 0 : (_events$onSleep = events.onSleep) === null || _events$onSleep === void 0 ? void 0 : _events$onSleep.call(events);
453
512
  }
454
513
 
455
- if (!rigidBody.isSleeping() && mesh.userData.isSleeping) {
514
+ if (!rigidBody.isSleeping() && state.isSleeping) {
456
515
  var _events$onWake;
457
516
 
458
517
  events === null || events === void 0 ? void 0 : (_events$onWake = events.onWake) === null || _events$onWake === void 0 ? void 0 : _events$onWake.call(events);
459
518
  }
460
519
 
461
- mesh.userData.isSleeping = rigidBody.isSleeping();
520
+ state.isSleeping = rigidBody.isSleeping();
462
521
  }
463
522
 
464
- if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !mesh.parent) {
523
+ if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !state.setMatrix) {
465
524
  return;
466
525
  }
467
526
 
468
- const {
469
- x,
470
- y,
471
- z
472
- } = rigidBody.translation();
473
- const {
474
- x: rx,
475
- y: ry,
476
- z: rz,
477
- w: rw
478
- } = rigidBody.rotation();
479
- const scale = mesh.getWorldScale(new three.Vector3()); // haha matrixes I have no idea what I'm doing :)
480
-
481
- const o = new three.Object3D();
482
- o.position.set(x, y, z);
483
- o.rotation.setFromQuaternion(new three.Quaternion(rx, ry, rz, rw));
484
- o.scale.set(scale.x, scale.y, scale.z);
485
- o.updateMatrix();
486
- o.applyMatrix4(mesh.parent.matrixWorld.clone().invert());
487
- o.updateMatrix();
488
- mesh.position.setFromMatrixPosition(o.matrix);
489
- mesh.rotation.setFromRotationMatrix(o.matrix);
527
+ state.setMatrix(_matrix4.compose(rapierVector3ToVector3(rigidBody.translation()), rapierQuaternionToQuaternion(rigidBody.rotation()), state.worldScale).premultiply(state.invertedMatrixWorld));
528
+
529
+ if (state.mesh instanceof three.InstancedMesh) {
530
+ state.mesh.instanceMatrix.needsUpdate = true;
531
+ }
490
532
  }); // Collision events
491
533
 
492
534
  eventQueue.drainCollisionEvents((handle1, handle2, started) => {
@@ -543,7 +585,7 @@ const Physics = ({
543
585
  gravity: _gravity
544
586
  },
545
587
  colliderMeshes,
546
- rigidBodyMeshes,
588
+ rigidBodyStates,
547
589
  rigidBodyEvents
548
590
  }), []);
549
591
  return /*#__PURE__*/React__default["default"].createElement(RapierContext.Provider, {
@@ -551,6 +593,40 @@ const Physics = ({
551
593
  }, children);
552
594
  };
553
595
 
596
+ function _objectWithoutPropertiesLoose(source, excluded) {
597
+ if (source == null) return {};
598
+ var target = {};
599
+ var sourceKeys = Object.keys(source);
600
+ var key, i;
601
+
602
+ for (i = 0; i < sourceKeys.length; i++) {
603
+ key = sourceKeys[i];
604
+ if (excluded.indexOf(key) >= 0) continue;
605
+ target[key] = source[key];
606
+ }
607
+
608
+ return target;
609
+ }
610
+
611
+ function _objectWithoutProperties(source, excluded) {
612
+ if (source == null) return {};
613
+ var target = _objectWithoutPropertiesLoose(source, excluded);
614
+ var key, i;
615
+
616
+ if (Object.getOwnPropertySymbols) {
617
+ var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
618
+
619
+ for (i = 0; i < sourceSymbolKeys.length; i++) {
620
+ key = sourceSymbolKeys[i];
621
+ if (excluded.indexOf(key) >= 0) continue;
622
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
623
+ target[key] = source[key];
624
+ }
625
+ }
626
+
627
+ return target;
628
+ }
629
+
554
630
  function _defineProperty(obj, key, value) {
555
631
  if (key in obj) {
556
632
  Object.defineProperty(obj, key, {
@@ -597,9 +673,8 @@ const useRapier = () => {
597
673
  };
598
674
  const useRigidBody = (options = {}) => {
599
675
  const {
600
- rapier,
601
676
  world,
602
- rigidBodyMeshes,
677
+ rigidBodyStates,
603
678
  physicsOptions,
604
679
  rigidBodyEvents
605
680
  } = useRapier();
@@ -608,23 +683,7 @@ const useRigidBody = (options = {}) => {
608
683
  const rigidBodyRef = React.useRef();
609
684
  const getRigidBodyRef = React.useRef(() => {
610
685
  if (!rigidBodyRef.current) {
611
- var _options$linearVeloci, _options$angularVeloc, _options$gravityScale, _options$canSleep, _options$ccd, _options$enabledRotat, _options$enabledTrans;
612
-
613
- const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
614
- const [lvx, lvy, lvz] = (_options$linearVeloci = options === null || options === void 0 ? void 0 : options.linearVelocity) !== null && _options$linearVeloci !== void 0 ? _options$linearVeloci : [0, 0, 0];
615
- const [avx, avy, avz] = (_options$angularVeloc = options === null || options === void 0 ? void 0 : options.angularVelocity) !== null && _options$angularVeloc !== void 0 ? _options$angularVeloc : [0, 0, 0];
616
- const gravityScale = (_options$gravityScale = options === null || options === void 0 ? void 0 : options.gravityScale) !== null && _options$gravityScale !== void 0 ? _options$gravityScale : 1;
617
- const canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
618
- const ccdEnabled = (_options$ccd = options === null || options === void 0 ? void 0 : options.ccd) !== null && _options$ccd !== void 0 ? _options$ccd : false;
619
- const [erx, ery, erz] = (_options$enabledRotat = options === null || options === void 0 ? void 0 : options.enabledRotations) !== null && _options$enabledRotat !== void 0 ? _options$enabledRotat : [true, true, true];
620
- const [etx, ety, etz] = (_options$enabledTrans = options === null || options === void 0 ? void 0 : options.enabledTranslations) !== null && _options$enabledTrans !== void 0 ? _options$enabledTrans : [true, true, true];
621
- const desc = new rapier.RigidBodyDesc(type).setLinvel(lvx, lvy, lvz).setAngvel({
622
- x: avx,
623
- y: avy,
624
- z: avz
625
- }).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled).enabledRotations(erx, ery, erz).enabledTranslations(etx, ety, etz);
626
- if (options.lockRotations) desc.lockRotations();
627
- if (options.lockTranslations) desc.lockTranslations();
686
+ const desc = rigidBodyDescFromOptions(options);
628
687
  const rigidBody = world.createRigidBody(desc);
629
688
  rigidBodyRef.current = world.getRigidBody(rigidBody.handle);
630
689
  }
@@ -661,8 +720,7 @@ const useRigidBody = (options = {}) => {
661
720
  y: worldPosition.y + y * scale.y,
662
721
  z: worldPosition.z + z * scale.z
663
722
  }, false);
664
- const eulerAngles = new three.Euler(rx, ry, rz, 'XYZ');
665
- const rotation = new three.Quaternion().setFromEuler(eulerAngles).multiply(worldRotation);
723
+ const rotation = vector3ToQuaternion(new three.Vector3(rx, ry, rz)).multiply(worldRotation);
666
724
  rigidBody.setRotation({
667
725
  x: rotation.x,
668
726
  y: rotation.y,
@@ -675,12 +733,20 @@ const useRigidBody = (options = {}) => {
675
733
  const autoColliders = colliderSetting !== false ? createCollidersFromChildren(ref.current, rigidBody, _objectSpread2(_objectSpread2({}, options), {}, {
676
734
  colliders: colliderSetting
677
735
  }), world) : [];
678
- rigidBodyMeshes.set(rigidBody.handle, ref.current);
736
+ rigidBodyStates.set(rigidBody.handle, {
737
+ mesh: ref.current,
738
+ invertedMatrixWorld: ref.current.parent.matrixWorld.clone().invert(),
739
+ isSleeping: false,
740
+ worldScale: ref.current.getWorldScale(_vector3).clone(),
741
+ setMatrix: mat => ref.current.matrix.copy(mat),
742
+ getMatrix: () => ref.current.matrix
743
+ });
744
+ ref.current.matrixAutoUpdate = false;
679
745
  return () => {
680
746
  world.removeRigidBody(rigidBody);
681
747
  autoColliders.forEach(collider => world.removeCollider(collider));
682
748
  rigidBodyRef.current = undefined;
683
- rigidBodyMeshes.delete(rigidBody.handle);
749
+ rigidBodyStates.delete(rigidBody.handle);
684
750
  };
685
751
  }, []); // Events
686
752
 
@@ -698,29 +764,6 @@ const useRigidBody = (options = {}) => {
698
764
  }, [options.onCollisionEnter, options.onCollisionExit]);
699
765
  const api = React.useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
700
766
  return [ref, api];
701
- };
702
- const useCollider = (body, options = {}) => {
703
- const {
704
- world
705
- } = useRapier();
706
- const colliderRef = React.useRef();
707
- const objectRef = React.useRef();
708
- const getColliderRef = React.useRef(() => {
709
- if (!colliderRef.current) {
710
- colliderRef.current = createColliderFromOptions(options, world, world.getRigidBody(body.handle));
711
- }
712
-
713
- return colliderRef.current;
714
- });
715
- React.useEffect(() => {
716
- const collider = getColliderRef.current();
717
- return () => {
718
- if (collider) world.removeCollider(collider);
719
- colliderRef.current = undefined;
720
- };
721
- }, []);
722
- const api = React.useMemo(() => createColliderApi(getColliderRef), []);
723
- return [objectRef, api];
724
767
  }; // Joints
725
768
 
726
769
  const useImpulseJoint = (body1, body2, params) => {
@@ -733,7 +776,7 @@ const useImpulseJoint = (body1, body2, params) => {
733
776
  let rb1;
734
777
  let rb2;
735
778
 
736
- if ('current' in body1 && body1.current && 'current' in body2 && body2.current) {
779
+ if ("current" in body1 && body1.current && "current" in body2 && body2.current) {
737
780
  rb1 = world.getRigidBody(body1.current.handle);
738
781
  rb2 = world.getRigidBody(body2.current.handle);
739
782
  const newJoint = world.createImpulseJoint(params, rb1, rb2);
@@ -766,9 +809,9 @@ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor,
766
809
  const {
767
810
  rapier
768
811
  } = useRapier();
769
- return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToObject(body1Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToObject(body1LocalFrame)), {}, {
812
+ return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToVector3(body1Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body1LocalFrame)), {}, {
770
813
  w: 1
771
- }), vectorArrayToObject(body2Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToObject(body2LocalFrame)), {}, {
814
+ }), vectorArrayToVector3(body2Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body2LocalFrame)), {}, {
772
815
  w: 1
773
816
  })));
774
817
  };
@@ -783,7 +826,7 @@ const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
783
826
  const {
784
827
  rapier
785
828
  } = useRapier();
786
- return useImpulseJoint(body1, body2, rapier.JointData.spherical(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor)));
829
+ return useImpulseJoint(body1, body2, rapier.JointData.spherical(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor)));
787
830
  };
788
831
  /**
789
832
  * The revolute joint prevents any relative movement between two rigid-bodies, except for relative
@@ -795,7 +838,7 @@ const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
795
838
  const {
796
839
  rapier
797
840
  } = useRapier();
798
- return useImpulseJoint(body1, body2, rapier.JointData.revolute(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor), vectorArrayToObject(axis)));
841
+ return useImpulseJoint(body1, body2, rapier.JointData.revolute(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
799
842
  };
800
843
  /**
801
844
  * The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
@@ -807,73 +850,18 @@ const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
807
850
  const {
808
851
  rapier
809
852
  } = useRapier();
810
- return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor), vectorArrayToObject(axis)));
853
+ return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
811
854
  };
812
855
 
813
- function _extends() {
814
- _extends = Object.assign || function (target) {
815
- for (var i = 1; i < arguments.length; i++) {
816
- var source = arguments[i];
817
-
818
- for (var key in source) {
819
- if (Object.prototype.hasOwnProperty.call(source, key)) {
820
- target[key] = source[key];
821
- }
822
- }
823
- }
824
-
825
- return target;
826
- };
827
-
828
- return _extends.apply(this, arguments);
829
- }
830
-
831
- function _objectWithoutPropertiesLoose(source, excluded) {
832
- if (source == null) return {};
833
- var target = {};
834
- var sourceKeys = Object.keys(source);
835
- var key, i;
836
-
837
- for (i = 0; i < sourceKeys.length; i++) {
838
- key = sourceKeys[i];
839
- if (excluded.indexOf(key) >= 0) continue;
840
- target[key] = source[key];
841
- }
842
-
843
- return target;
844
- }
845
-
846
- function _objectWithoutProperties(source, excluded) {
847
- if (source == null) return {};
848
- var target = _objectWithoutPropertiesLoose(source, excluded);
849
- var key, i;
850
-
851
- if (Object.getOwnPropertySymbols) {
852
- var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
853
-
854
- for (i = 0; i < sourceSymbolKeys.length; i++) {
855
- key = sourceSymbolKeys[i];
856
- if (excluded.indexOf(key) >= 0) continue;
857
- if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
858
- target[key] = source[key];
859
- }
860
- }
861
-
862
- return target;
863
- }
864
-
865
- const _excluded = ["children"],
866
- _excluded2 = ["children"];
856
+ const _excluded$1 = ["children"];
867
857
  const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
868
-
869
858
  const useRigidBodyContext = () => React.useContext(RigidBodyContext); // RigidBody
870
859
 
871
-
872
860
  const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
873
861
  let {
874
862
  children
875
863
  } = _ref,
876
- props = _objectWithoutProperties(_ref, _excluded);
864
+ props = _objectWithoutProperties(_ref, _excluded$1);
877
865
 
878
866
  const [object, api] = useRigidBody(props);
879
867
  React.useImperativeHandle(ref, () => api);
@@ -888,6 +876,7 @@ const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
888
876
  ref: object
889
877
  }, children));
890
878
  });
879
+
891
880
  const MeshCollider = ({
892
881
  children,
893
882
  type
@@ -905,9 +894,9 @@ const MeshCollider = ({
905
894
  let autoColliders = [];
906
895
 
907
896
  if (object.current) {
908
- var _ref2;
897
+ var _ref;
909
898
 
910
- const colliderSetting = (_ref2 = type !== null && type !== void 0 ? type : physicsOptions.colliders) !== null && _ref2 !== void 0 ? _ref2 : false;
899
+ const colliderSetting = (_ref = type !== null && type !== void 0 ? type : physicsOptions.colliders) !== null && _ref !== void 0 ? _ref : false;
911
900
  autoColliders = colliderSetting !== false ? createCollidersFromChildren(object.current, api, _objectSpread2(_objectSpread2({}, options), {}, {
912
901
  colliders: colliderSetting
913
902
  }), world, false) : [];
@@ -925,83 +914,6 @@ const MeshCollider = ({
925
914
  r3RapierType: "MeshCollider"
926
915
  }
927
916
  }, children);
928
- }; // Colliders
929
-
930
- const AnyCollider = _ref3 => {
931
- let {
932
- children
933
- } = _ref3,
934
- props = _objectWithoutProperties(_ref3, _excluded2);
935
-
936
- const {
937
- world
938
- } = useRapier();
939
- const rigidBodyContext = useRigidBodyContext();
940
- const ref = React.useRef(null);
941
- React.useEffect(() => {
942
- var _rigidBodyContext$api;
943
-
944
- const scale = ref.current.getWorldScale(new three.Vector3());
945
- const collider = createColliderFromOptions({
946
- options: props,
947
- world,
948
- rigidBody: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : (_rigidBodyContext$api = rigidBodyContext.api) === null || _rigidBodyContext$api === void 0 ? void 0 : _rigidBodyContext$api.raw(),
949
- scale,
950
- hasCollisionEvents: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.hasCollisionEvents
951
- });
952
- return () => {
953
- world.removeCollider(collider);
954
- };
955
- }, []);
956
- return /*#__PURE__*/React__default["default"].createElement("object3D", {
957
- ref: ref
958
- }, children);
959
- };
960
-
961
- const CuboidCollider = props => {
962
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
963
- shape: "cuboid"
964
- }));
965
- };
966
- const RoundCuboidCollider = props => {
967
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
968
- shape: "roundCuboid"
969
- }));
970
- };
971
- const BallCollider = props => {
972
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
973
- shape: "ball"
974
- }));
975
- };
976
- const CapsuleCollider = props => {
977
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
978
- shape: "capsule"
979
- }));
980
- };
981
- const HeightfieldCollider = props => {
982
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
983
- shape: "heightfield"
984
- }));
985
- };
986
- const TrimeshCollider = props => {
987
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
988
- shape: "trimesh"
989
- }));
990
- };
991
- const ConeCollider = props => {
992
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
993
- shape: "cone"
994
- }));
995
- };
996
- const CylinderCollider = props => {
997
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
998
- shape: "cylinder"
999
- }));
1000
- };
1001
- const ConvexHullCollider = props => {
1002
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1003
- shape: "convexHull"
1004
- }));
1005
917
  };
1006
918
 
1007
919
  const geometryFromCollider = collider => {
@@ -1119,6 +1031,214 @@ const Debug = () => {
1119
1031
  })));
1120
1032
  };
1121
1033
 
1034
+ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
1035
+ const {
1036
+ world,
1037
+ rigidBodyStates,
1038
+ physicsOptions
1039
+ } = useRapier();
1040
+ const object = React.useRef(null);
1041
+ const instancesRef = React.useRef();
1042
+ const instancesRefGetter = React.useRef(() => {
1043
+ if (!instancesRef.current) {
1044
+ instancesRef.current = [];
1045
+ }
1046
+
1047
+ return instancesRef.current;
1048
+ });
1049
+ React.useEffect(() => {
1050
+ const colliders = [];
1051
+ const rigidBodies = instancesRefGetter.current();
1052
+
1053
+ if (object.current) {
1054
+ const worldScale = object.current.getWorldScale(new three.Vector3());
1055
+ let hasOneMesh = false;
1056
+ object.current.traverse(mesh => {
1057
+ if (mesh instanceof three.InstancedMesh) {
1058
+ if (hasOneMesh) {
1059
+ console.warn("Can only use a single InstancedMesh inside <InstancedRigidBodies />, more InstancedMeshes will be ignored.");
1060
+ return;
1061
+ }
1062
+
1063
+ hasOneMesh = true;
1064
+ mesh.instanceMatrix.setUsage(three.DynamicDrawUsage);
1065
+
1066
+ for (let index = 0; index < mesh.count; index++) {
1067
+ const scale = worldScale.clone();
1068
+ const rigidBodyDesc = rigidBodyDescFromOptions(props);
1069
+
1070
+ if (props.scales && props.scales[index]) {
1071
+ const s = vectorArrayToVector3(props.scales[index]);
1072
+ scale.multiply(s);
1073
+ }
1074
+
1075
+ const colliderDesc = colliderDescFromGeometry(mesh.geometry, props.colliders || physicsOptions.colliders, scale, false // Collisions currently not enabled for instances
1076
+ );
1077
+ const rigidBody = world.createRigidBody(rigidBodyDesc);
1078
+ const matrix = new three.Matrix4();
1079
+ mesh.getMatrixAt(index, matrix);
1080
+ const {
1081
+ position,
1082
+ rotation
1083
+ } = decomposeMatrix4(matrix); // Set positions
1084
+
1085
+ if (props.positions && props.positions[index]) {
1086
+ rigidBody.setTranslation(vectorArrayToVector3(props.positions[index]), true);
1087
+ } else {
1088
+ rigidBody.setTranslation(position, true);
1089
+ } // Set rotations
1090
+
1091
+
1092
+ if (props.rotations && props.rotations[index]) {
1093
+ const [x, y, z] = props.rotations[index];
1094
+ rigidBody.setRotation(vector3ToQuaternion(new three.Vector3(x, y, z)), true);
1095
+ } else {
1096
+ rigidBody.setRotation(rotation, true);
1097
+ }
1098
+
1099
+ const collider = world.createCollider(colliderDesc, rigidBody);
1100
+ rigidBodyStates.set(rigidBody.handle, {
1101
+ mesh: mesh,
1102
+ isSleeping: false,
1103
+ invertedMatrixWorld: object.current.matrixWorld.clone().invert(),
1104
+ setMatrix: matrix => mesh.setMatrixAt(index, matrix),
1105
+ getMatrix: () => {
1106
+ const m = new three.Matrix4();
1107
+ mesh.getMatrixAt(index, m);
1108
+ return m;
1109
+ },
1110
+ // Setting the world scale to the scale here, because
1111
+ // we want the scales to be reflected by instance
1112
+ worldScale: scale
1113
+ });
1114
+ const api = createRigidBodyApi({
1115
+ current() {
1116
+ return rigidBody;
1117
+ }
1118
+
1119
+ });
1120
+ colliders.push(collider);
1121
+ rigidBodies.push({
1122
+ rigidBody,
1123
+ api
1124
+ });
1125
+ }
1126
+ }
1127
+
1128
+ if (mesh.type === "Mesh" && !("isInstancedMesh" in mesh)) {
1129
+ console.warn("Can only use InstancedMesh inside <InstancedRigidBodies />, Mesh will be ignored.");
1130
+ }
1131
+ });
1132
+ return () => {
1133
+ rigidBodies.forEach(rb => world.removeRigidBody(rb.rigidBody));
1134
+ colliders.forEach(coll => world.removeCollider(coll));
1135
+ instancesRef.current = undefined;
1136
+ };
1137
+ }
1138
+ }, []);
1139
+ React.useImperativeHandle(ref, () => createInstancedRigidBodiesApi(instancesRefGetter));
1140
+ return /*#__PURE__*/React__default["default"].createElement("object3D", {
1141
+ ref: object
1142
+ }, props.children);
1143
+ });
1144
+
1145
+ function _extends() {
1146
+ _extends = Object.assign || function (target) {
1147
+ for (var i = 1; i < arguments.length; i++) {
1148
+ var source = arguments[i];
1149
+
1150
+ for (var key in source) {
1151
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
1152
+ target[key] = source[key];
1153
+ }
1154
+ }
1155
+ }
1156
+
1157
+ return target;
1158
+ };
1159
+
1160
+ return _extends.apply(this, arguments);
1161
+ }
1162
+
1163
+ const _excluded = ["children"];
1164
+
1165
+ const AnyCollider = _ref => {
1166
+ let {
1167
+ children
1168
+ } = _ref,
1169
+ props = _objectWithoutProperties(_ref, _excluded);
1170
+
1171
+ const {
1172
+ world
1173
+ } = useRapier();
1174
+ const rigidBodyContext = useRigidBodyContext();
1175
+ const ref = React.useRef(null);
1176
+ React.useEffect(() => {
1177
+ var _rigidBodyContext$api;
1178
+
1179
+ const scale = ref.current.getWorldScale(new three.Vector3());
1180
+ const collider = createColliderFromOptions({
1181
+ options: props,
1182
+ world,
1183
+ rigidBody: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : (_rigidBodyContext$api = rigidBodyContext.api) === null || _rigidBodyContext$api === void 0 ? void 0 : _rigidBodyContext$api.raw(),
1184
+ scale,
1185
+ hasCollisionEvents: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.hasCollisionEvents
1186
+ });
1187
+ return () => {
1188
+ world.removeCollider(collider);
1189
+ };
1190
+ }, []);
1191
+ return /*#__PURE__*/React__default["default"].createElement("object3D", {
1192
+ ref: ref
1193
+ }, children);
1194
+ };
1195
+
1196
+ const CuboidCollider = props => {
1197
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1198
+ shape: "cuboid"
1199
+ }));
1200
+ };
1201
+ const RoundCuboidCollider = props => {
1202
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1203
+ shape: "roundCuboid"
1204
+ }));
1205
+ };
1206
+ const BallCollider = props => {
1207
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1208
+ shape: "ball"
1209
+ }));
1210
+ };
1211
+ const CapsuleCollider = props => {
1212
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1213
+ shape: "capsule"
1214
+ }));
1215
+ };
1216
+ const HeightfieldCollider = props => {
1217
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1218
+ shape: "heightfield"
1219
+ }));
1220
+ };
1221
+ const TrimeshCollider = props => {
1222
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1223
+ shape: "trimesh"
1224
+ }));
1225
+ };
1226
+ const ConeCollider = props => {
1227
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1228
+ shape: "cone"
1229
+ }));
1230
+ };
1231
+ const CylinderCollider = props => {
1232
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1233
+ shape: "cylinder"
1234
+ }));
1235
+ };
1236
+ const ConvexHullCollider = props => {
1237
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1238
+ shape: "convexHull"
1239
+ }));
1240
+ };
1241
+
1122
1242
  Object.defineProperty(exports, 'CoefficientCombineRule', {
1123
1243
  enumerable: true,
1124
1244
  get: function () { return rapier3dCompat.CoefficientCombineRule; }
@@ -1139,12 +1259,12 @@ exports.CuboidCollider = CuboidCollider;
1139
1259
  exports.CylinderCollider = CylinderCollider;
1140
1260
  exports.Debug = Debug;
1141
1261
  exports.HeightfieldCollider = HeightfieldCollider;
1262
+ exports.InstancedRigidBodies = InstancedRigidBodies;
1142
1263
  exports.MeshCollider = MeshCollider;
1143
1264
  exports.Physics = Physics;
1144
1265
  exports.RigidBody = RigidBody;
1145
1266
  exports.RoundCuboidCollider = RoundCuboidCollider;
1146
1267
  exports.TrimeshCollider = TrimeshCollider;
1147
- exports.useCollider = useCollider;
1148
1268
  exports.useFixedJoint = useFixedJoint;
1149
1269
  exports.useImpulseJoint = useImpulseJoint;
1150
1270
  exports.usePrismaticJoint = usePrismaticJoint;