@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.
@@ -1,23 +1,34 @@
1
+ import { ColliderDesc, ActiveEvents, RigidBodyDesc, CoefficientCombineRule, EventQueue, ShapeType } from '@dimforge/rapier3d-compat';
2
+ export { CoefficientCombineRule, Collider as RapierCollider, RigidBody as RapierRigidBody } from '@dimforge/rapier3d-compat';
1
3
  import React, { useRef, useState, useEffect, useMemo, createContext, useContext, forwardRef, useImperativeHandle, memo } from 'react';
2
4
  import { useAsset } from 'use-asset';
3
5
  import { useFrame } from '@react-three/fiber';
4
- import { ColliderDesc, CoefficientCombineRule, ActiveEvents, EventQueue, ShapeType } from '@dimforge/rapier3d-compat';
5
- export { CoefficientCombineRule, Collider as RapierCollider, RigidBody as RapierRigidBody } from '@dimforge/rapier3d-compat';
6
- import { Quaternion, Euler, Vector3, Object3D, CylinderBufferGeometry, BufferGeometry, BufferAttribute, SphereBufferGeometry, BoxBufferGeometry } from 'three';
6
+ import { Quaternion, Euler, Vector3, Object3D, Matrix4, InstancedMesh, CylinderBufferGeometry, BufferGeometry, BufferAttribute, SphereBufferGeometry, BoxBufferGeometry, DynamicDrawUsage } from 'three';
7
+
8
+ const _quaternion = new Quaternion();
9
+ const _euler = new Euler();
10
+ const _vector3 = new Vector3();
11
+ new Object3D();
12
+ const _matrix4 = new Matrix4();
7
13
 
8
- const vectorArrayToObject = arr => {
14
+ const vectorArrayToVector3 = arr => {
9
15
  const [x, y, z] = arr;
10
- return {
11
- x,
12
- y,
13
- z
14
- };
16
+ return new Vector3(x, y, z);
15
17
  };
16
- const quaternion = new Quaternion();
17
- const euler = new Euler();
18
18
  const vector3ToQuaternion = v => {
19
- return quaternion.setFromEuler(euler.setFromVector3(v));
19
+ return _quaternion.setFromEuler(_euler.setFromVector3(v));
20
20
  };
21
+ const rapierVector3ToVector3 = ({
22
+ x,
23
+ y,
24
+ z
25
+ }) => _vector3.set(x, y, z).clone();
26
+ const rapierQuaternionToQuaternion = ({
27
+ x,
28
+ y,
29
+ z,
30
+ w
31
+ }) => _quaternion.set(x, y, z, w);
21
32
  const rigidBodyTypeMap = {
22
33
  fixed: 1,
23
34
  dynamic: 0,
@@ -25,6 +36,17 @@ const rigidBodyTypeMap = {
25
36
  kinematicVelocity: 3
26
37
  };
27
38
  const rigidBodyTypeFromString = type => rigidBodyTypeMap[type];
39
+ const decomposeMatrix4 = m => {
40
+ const position = new Vector3();
41
+ const rotation = new Quaternion();
42
+ const scale = new Vector3();
43
+ m.decompose(position, rotation, scale);
44
+ return {
45
+ position,
46
+ rotation,
47
+ scale
48
+ };
49
+ };
28
50
  const scaleColliderArgs = (shape, args, scale) => {
29
51
  // Heightfield only scales the last arg
30
52
  const newArgs = args.slice();
@@ -110,8 +132,7 @@ const isChildOfMeshCollider = child => {
110
132
  const createCollidersFromChildren = (object, rigidBody, options, world, ignoreMeshColliders = true) => {
111
133
  const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
112
134
  const colliders = [];
113
- let desc;
114
- let offset = new Vector3();
135
+ new Vector3();
115
136
  object.traverse(child => {
116
137
  if ("isMesh" in child) {
117
138
  if (ignoreMeshColliders && isChildOfMeshCollider(child)) return;
@@ -129,62 +150,32 @@ const createCollidersFromChildren = (object, rigidBody, options, world, ignoreMe
129
150
  z: rz,
130
151
  w: rw
131
152
  } = new Quaternion().setFromEuler(child.rotation);
132
- const scale = child.getWorldScale(new Vector3());
133
-
134
- switch (options.colliders) {
135
- case "cuboid":
136
- {
137
- geometry.computeBoundingBox();
138
- const {
139
- boundingBox
140
- } = geometry;
141
- const size = boundingBox.getSize(new Vector3());
142
- boundingBox.getCenter(offset);
143
- desc = ColliderDesc.cuboid(size.x / 2 * scale.x, size.y / 2 * scale.y, size.z / 2 * scale.z);
144
- }
145
- break;
153
+ const scale = child.getWorldScale(new Vector3()); // We translate the colliders based on the parent's world scale
146
154
 
147
- case "ball":
148
- {
149
- geometry.computeBoundingSphere();
150
- const {
151
- boundingSphere
152
- } = geometry;
153
- const radius = boundingSphere.radius * scale.x;
154
- offset.copy(boundingSphere.center);
155
- desc = ColliderDesc.ball(radius);
156
- }
157
- break;
158
-
159
- case "trimesh":
160
- {
161
- var _g$index;
162
-
163
- const _g = geometry.clone().scale(scale.x, scale.y, scale.z);
155
+ const parentWorldScale = child.parent.getWorldScale(new Vector3());
156
+ const desc = colliderDescFromGeometry(geometry, options.colliders, scale, hasCollisionEvents);
157
+ const offset = new Vector3(0, 0, 0);
164
158
 
165
- desc = ColliderDesc.trimesh(_g.attributes.position.array, (_g$index = _g.index) === null || _g$index === void 0 ? void 0 : _g$index.array);
166
- }
167
- break;
159
+ if (options.colliders === "cuboid") {
160
+ var _geometry$boundingBox;
168
161
 
169
- case "hull":
170
- const g = geometry.clone().scale(scale.x, scale.y, scale.z);
171
- {
172
- desc = ColliderDesc.convexHull(g.attributes.position.array);
173
- }
174
- break;
175
- } // We translate the colliders based on the parent's world scale
162
+ geometry.computeBoundingBox();
163
+ (_geometry$boundingBox = geometry.boundingBox) === null || _geometry$boundingBox === void 0 ? void 0 : _geometry$boundingBox.getCenter(offset);
164
+ }
176
165
 
166
+ if (options.colliders === "ball") {
167
+ geometry.computeBoundingSphere();
168
+ offset.copy(geometry.boundingSphere.center);
169
+ }
177
170
 
178
- const parentWorldScale = child.parent.getWorldScale(new Vector3());
171
+ if (Number.isFinite(options.friction)) desc.setFriction(options.friction);
172
+ if (Number.isFinite(options.restitution)) desc.setRestitution(options.restitution);
179
173
  desc.setTranslation((x + offset.x) * parentWorldScale.x, (y + offset.y) * parentWorldScale.y, (z + offset.z) * parentWorldScale.z).setRotation({
180
174
  x: rx,
181
175
  y: ry,
182
176
  z: rz,
183
177
  w: rw
184
178
  });
185
- if (hasCollisionEvents) desc.setActiveEvents(ActiveEvents.COLLISION_EVENTS);
186
- if (Number.isFinite(options.friction)) desc.setFriction(options.friction);
187
- if (Number.isFinite(options.restitution)) desc.setRestitution(options.restitution);
188
179
  const actualRigidBody = world.getRigidBody(rigidBody === null || rigidBody === void 0 ? void 0 : rigidBody.handle);
189
180
  const collider = world.createCollider(desc, actualRigidBody);
190
181
  colliders.push(collider);
@@ -192,6 +183,53 @@ const createCollidersFromChildren = (object, rigidBody, options, world, ignoreMe
192
183
  });
193
184
  return colliders;
194
185
  };
186
+ const colliderDescFromGeometry = (geometry, colliders, scale, hasCollisionEvents) => {
187
+ let desc;
188
+
189
+ switch (colliders) {
190
+ case "cuboid":
191
+ {
192
+ geometry.computeBoundingBox();
193
+ const {
194
+ boundingBox
195
+ } = geometry;
196
+ const size = boundingBox.getSize(new Vector3());
197
+ desc = ColliderDesc.cuboid(size.x / 2 * scale.x, size.y / 2 * scale.y, size.z / 2 * scale.z);
198
+ }
199
+ break;
200
+
201
+ case "ball":
202
+ {
203
+ geometry.computeBoundingSphere();
204
+ const {
205
+ boundingSphere
206
+ } = geometry;
207
+ const radius = boundingSphere.radius * scale.x;
208
+ desc = ColliderDesc.ball(radius);
209
+ }
210
+ break;
211
+
212
+ case "trimesh":
213
+ {
214
+ var _g$index;
215
+
216
+ const _g = geometry.clone().scale(scale.x, scale.y, scale.z);
217
+
218
+ desc = ColliderDesc.trimesh(_g.attributes.position.array, (_g$index = _g.index) === null || _g$index === void 0 ? void 0 : _g$index.array);
219
+ }
220
+ break;
221
+
222
+ case "hull":
223
+ const g = geometry.clone().scale(scale.x, scale.y, scale.z);
224
+ {
225
+ desc = ColliderDesc.convexHull(g.attributes.position.array);
226
+ }
227
+ break;
228
+ }
229
+
230
+ if (hasCollisionEvents) desc.setActiveEvents(ActiveEvents.COLLISION_EVENTS);
231
+ return desc;
232
+ };
195
233
  const scaleVertices = (vertices, scale) => {
196
234
  const scaledVerts = Array.from(vertices);
197
235
 
@@ -203,6 +241,26 @@ const scaleVertices = (vertices, scale) => {
203
241
 
204
242
  return scaledVerts;
205
243
  };
244
+ const rigidBodyDescFromOptions = options => {
245
+ var _options$linearVeloci, _options$angularVeloc, _options$gravityScale, _options$canSleep, _options$ccd, _options$enabledRotat, _options$enabledTrans;
246
+
247
+ const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
248
+ 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];
249
+ 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];
250
+ const gravityScale = (_options$gravityScale = options === null || options === void 0 ? void 0 : options.gravityScale) !== null && _options$gravityScale !== void 0 ? _options$gravityScale : 1;
251
+ const canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
252
+ const ccdEnabled = (_options$ccd = options === null || options === void 0 ? void 0 : options.ccd) !== null && _options$ccd !== void 0 ? _options$ccd : false;
253
+ 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];
254
+ 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];
255
+ const desc = new RigidBodyDesc(type).setLinvel(lvx, lvy, lvz).setAngvel({
256
+ x: avx,
257
+ y: avy,
258
+ z: avz
259
+ }).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled).enabledRotations(erx, ery, erz).enabledTranslations(etx, ety, etz);
260
+ if (options.lockRotations) desc.lockRotations();
261
+ if (options.lockTranslations) desc.lockTranslations();
262
+ return desc;
263
+ };
206
264
 
207
265
  const createRigidBodyApi = ref => {
208
266
  return {
@@ -304,18 +362,19 @@ const createRigidBodyApi = ref => {
304
362
  setEnabledRotations: (x, y, z) => ref.current().setEnabledRotations(x, y, z, true),
305
363
  setEnabledTranslations: (x, y, z) => ref.current().setEnabledTranslations(x, y, z, true)
306
364
  };
307
- }; // TODO: Flesh this out
365
+ };
366
+ const createInstancedRigidBodiesApi = bodiesGetter => ({
367
+ at: index => bodiesGetter.current()[index].api,
308
368
 
309
- const createColliderApi = ref => {
310
- return {
311
- raw: () => ref.current(),
369
+ forEach(callback) {
370
+ return bodiesGetter.current().map(b => b.api).forEach(callback);
371
+ },
312
372
 
313
- get handle() {
314
- return ref.current().handle;
315
- }
373
+ get count() {
374
+ return bodiesGetter.current().length;
375
+ }
316
376
 
317
- };
318
- };
377
+ }); // TODO: Flesh this out
319
378
  const createWorldApi = ref => {
320
379
  return {
321
380
  raw: () => ref.current(),
@@ -362,23 +421,23 @@ const importRapier = async () => {
362
421
  };
363
422
 
364
423
  const Physics = ({
365
- colliders: _colliders = 'cuboid',
424
+ colliders: _colliders = "cuboid",
366
425
  gravity: _gravity = [0, -9.81, 0],
367
426
  children,
368
- timeStep: _timeStep = 'vary'
427
+ timeStep: _timeStep = "vary"
369
428
  }) => {
370
429
  const rapier = useAsset(importRapier);
371
430
  const worldRef = useRef();
372
431
  const getWorldRef = useRef(() => {
373
432
  if (!worldRef.current) {
374
- const world = new rapier.World(vectorArrayToObject(_gravity));
433
+ const world = new rapier.World(vectorArrayToVector3(_gravity));
375
434
  worldRef.current = world;
376
435
  }
377
436
 
378
437
  return worldRef.current;
379
438
  });
380
439
  const [colliderMeshes] = useState(() => new Map());
381
- const [rigidBodyMeshes] = useState(() => new Map());
440
+ const [rigidBodyStates] = useState(() => new Map());
382
441
  const [rigidBodyEvents] = useState(() => new Map());
383
442
  const [eventQueue] = useState(() => new EventQueue(false)); // Init world
384
443
 
@@ -396,7 +455,7 @@ const Physics = ({
396
455
  const world = worldRef.current;
397
456
 
398
457
  if (world) {
399
- world.gravity = vectorArrayToObject(_gravity);
458
+ world.gravity = vectorArrayToVector3(_gravity);
400
459
  }
401
460
  }, [_gravity]);
402
461
  const time = useRef(performance.now());
@@ -408,7 +467,7 @@ const Physics = ({
408
467
  const now = performance.now();
409
468
  const delta = Math.min(100, now - time.current);
410
469
 
411
- if (_timeStep === 'vary') {
470
+ if (_timeStep === "vary") {
412
471
  world.timestep = delta / 1000;
413
472
  } else {
414
473
  world.timestep = _timeStep;
@@ -416,52 +475,35 @@ const Physics = ({
416
475
 
417
476
  world.step(eventQueue); // Update meshes
418
477
 
419
- rigidBodyMeshes.forEach((mesh, handle) => {
478
+ rigidBodyStates.forEach((state, handle) => {
420
479
  const rigidBody = world.getRigidBody(handle);
421
480
  const events = rigidBodyEvents.get(handle);
422
481
 
423
482
  if (events !== null && events !== void 0 && events.onSleep || events !== null && events !== void 0 && events.onWake) {
424
- if (rigidBody.isSleeping() && !mesh.userData.isSleeping) {
483
+ if (rigidBody.isSleeping() && !state.isSleeping) {
425
484
  var _events$onSleep;
426
485
 
427
486
  events === null || events === void 0 ? void 0 : (_events$onSleep = events.onSleep) === null || _events$onSleep === void 0 ? void 0 : _events$onSleep.call(events);
428
487
  }
429
488
 
430
- if (!rigidBody.isSleeping() && mesh.userData.isSleeping) {
489
+ if (!rigidBody.isSleeping() && state.isSleeping) {
431
490
  var _events$onWake;
432
491
 
433
492
  events === null || events === void 0 ? void 0 : (_events$onWake = events.onWake) === null || _events$onWake === void 0 ? void 0 : _events$onWake.call(events);
434
493
  }
435
494
 
436
- mesh.userData.isSleeping = rigidBody.isSleeping();
495
+ state.isSleeping = rigidBody.isSleeping();
437
496
  }
438
497
 
439
- if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !mesh.parent) {
498
+ if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !state.setMatrix) {
440
499
  return;
441
500
  }
442
501
 
443
- const {
444
- x,
445
- y,
446
- z
447
- } = rigidBody.translation();
448
- const {
449
- x: rx,
450
- y: ry,
451
- z: rz,
452
- w: rw
453
- } = rigidBody.rotation();
454
- const scale = mesh.getWorldScale(new Vector3()); // haha matrixes I have no idea what I'm doing :)
455
-
456
- const o = new Object3D();
457
- o.position.set(x, y, z);
458
- o.rotation.setFromQuaternion(new Quaternion(rx, ry, rz, rw));
459
- o.scale.set(scale.x, scale.y, scale.z);
460
- o.updateMatrix();
461
- o.applyMatrix4(mesh.parent.matrixWorld.clone().invert());
462
- o.updateMatrix();
463
- mesh.position.setFromMatrixPosition(o.matrix);
464
- mesh.rotation.setFromRotationMatrix(o.matrix);
502
+ state.setMatrix(_matrix4.compose(rapierVector3ToVector3(rigidBody.translation()), rapierQuaternionToQuaternion(rigidBody.rotation()), state.worldScale).premultiply(state.invertedMatrixWorld));
503
+
504
+ if (state.mesh instanceof InstancedMesh) {
505
+ state.mesh.instanceMatrix.needsUpdate = true;
506
+ }
465
507
  }); // Collision events
466
508
 
467
509
  eventQueue.drainCollisionEvents((handle1, handle2, started) => {
@@ -518,7 +560,7 @@ const Physics = ({
518
560
  gravity: _gravity
519
561
  },
520
562
  colliderMeshes,
521
- rigidBodyMeshes,
563
+ rigidBodyStates,
522
564
  rigidBodyEvents
523
565
  }), []);
524
566
  return /*#__PURE__*/React.createElement(RapierContext.Provider, {
@@ -526,6 +568,40 @@ const Physics = ({
526
568
  }, children);
527
569
  };
528
570
 
571
+ function _objectWithoutPropertiesLoose(source, excluded) {
572
+ if (source == null) return {};
573
+ var target = {};
574
+ var sourceKeys = Object.keys(source);
575
+ var key, i;
576
+
577
+ for (i = 0; i < sourceKeys.length; i++) {
578
+ key = sourceKeys[i];
579
+ if (excluded.indexOf(key) >= 0) continue;
580
+ target[key] = source[key];
581
+ }
582
+
583
+ return target;
584
+ }
585
+
586
+ function _objectWithoutProperties(source, excluded) {
587
+ if (source == null) return {};
588
+ var target = _objectWithoutPropertiesLoose(source, excluded);
589
+ var key, i;
590
+
591
+ if (Object.getOwnPropertySymbols) {
592
+ var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
593
+
594
+ for (i = 0; i < sourceSymbolKeys.length; i++) {
595
+ key = sourceSymbolKeys[i];
596
+ if (excluded.indexOf(key) >= 0) continue;
597
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
598
+ target[key] = source[key];
599
+ }
600
+ }
601
+
602
+ return target;
603
+ }
604
+
529
605
  function _defineProperty(obj, key, value) {
530
606
  if (key in obj) {
531
607
  Object.defineProperty(obj, key, {
@@ -572,9 +648,8 @@ const useRapier = () => {
572
648
  };
573
649
  const useRigidBody = (options = {}) => {
574
650
  const {
575
- rapier,
576
651
  world,
577
- rigidBodyMeshes,
652
+ rigidBodyStates,
578
653
  physicsOptions,
579
654
  rigidBodyEvents
580
655
  } = useRapier();
@@ -583,23 +658,7 @@ const useRigidBody = (options = {}) => {
583
658
  const rigidBodyRef = useRef();
584
659
  const getRigidBodyRef = useRef(() => {
585
660
  if (!rigidBodyRef.current) {
586
- var _options$linearVeloci, _options$angularVeloc, _options$gravityScale, _options$canSleep, _options$ccd, _options$enabledRotat, _options$enabledTrans;
587
-
588
- const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
589
- 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];
590
- 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];
591
- const gravityScale = (_options$gravityScale = options === null || options === void 0 ? void 0 : options.gravityScale) !== null && _options$gravityScale !== void 0 ? _options$gravityScale : 1;
592
- const canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
593
- const ccdEnabled = (_options$ccd = options === null || options === void 0 ? void 0 : options.ccd) !== null && _options$ccd !== void 0 ? _options$ccd : false;
594
- 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];
595
- 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];
596
- const desc = new rapier.RigidBodyDesc(type).setLinvel(lvx, lvy, lvz).setAngvel({
597
- x: avx,
598
- y: avy,
599
- z: avz
600
- }).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled).enabledRotations(erx, ery, erz).enabledTranslations(etx, ety, etz);
601
- if (options.lockRotations) desc.lockRotations();
602
- if (options.lockTranslations) desc.lockTranslations();
661
+ const desc = rigidBodyDescFromOptions(options);
603
662
  const rigidBody = world.createRigidBody(desc);
604
663
  rigidBodyRef.current = world.getRigidBody(rigidBody.handle);
605
664
  }
@@ -636,8 +695,7 @@ const useRigidBody = (options = {}) => {
636
695
  y: worldPosition.y + y * scale.y,
637
696
  z: worldPosition.z + z * scale.z
638
697
  }, false);
639
- const eulerAngles = new Euler(rx, ry, rz, 'XYZ');
640
- const rotation = new Quaternion().setFromEuler(eulerAngles).multiply(worldRotation);
698
+ const rotation = vector3ToQuaternion(new Vector3(rx, ry, rz)).multiply(worldRotation);
641
699
  rigidBody.setRotation({
642
700
  x: rotation.x,
643
701
  y: rotation.y,
@@ -650,12 +708,20 @@ const useRigidBody = (options = {}) => {
650
708
  const autoColliders = colliderSetting !== false ? createCollidersFromChildren(ref.current, rigidBody, _objectSpread2(_objectSpread2({}, options), {}, {
651
709
  colliders: colliderSetting
652
710
  }), world) : [];
653
- rigidBodyMeshes.set(rigidBody.handle, ref.current);
711
+ rigidBodyStates.set(rigidBody.handle, {
712
+ mesh: ref.current,
713
+ invertedMatrixWorld: ref.current.parent.matrixWorld.clone().invert(),
714
+ isSleeping: false,
715
+ worldScale: ref.current.getWorldScale(_vector3).clone(),
716
+ setMatrix: mat => ref.current.matrix.copy(mat),
717
+ getMatrix: () => ref.current.matrix
718
+ });
719
+ ref.current.matrixAutoUpdate = false;
654
720
  return () => {
655
721
  world.removeRigidBody(rigidBody);
656
722
  autoColliders.forEach(collider => world.removeCollider(collider));
657
723
  rigidBodyRef.current = undefined;
658
- rigidBodyMeshes.delete(rigidBody.handle);
724
+ rigidBodyStates.delete(rigidBody.handle);
659
725
  };
660
726
  }, []); // Events
661
727
 
@@ -673,29 +739,6 @@ const useRigidBody = (options = {}) => {
673
739
  }, [options.onCollisionEnter, options.onCollisionExit]);
674
740
  const api = useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
675
741
  return [ref, api];
676
- };
677
- const useCollider = (body, options = {}) => {
678
- const {
679
- world
680
- } = useRapier();
681
- const colliderRef = useRef();
682
- const objectRef = useRef();
683
- const getColliderRef = useRef(() => {
684
- if (!colliderRef.current) {
685
- colliderRef.current = createColliderFromOptions(options, world, world.getRigidBody(body.handle));
686
- }
687
-
688
- return colliderRef.current;
689
- });
690
- useEffect(() => {
691
- const collider = getColliderRef.current();
692
- return () => {
693
- if (collider) world.removeCollider(collider);
694
- colliderRef.current = undefined;
695
- };
696
- }, []);
697
- const api = useMemo(() => createColliderApi(getColliderRef), []);
698
- return [objectRef, api];
699
742
  }; // Joints
700
743
 
701
744
  const useImpulseJoint = (body1, body2, params) => {
@@ -708,7 +751,7 @@ const useImpulseJoint = (body1, body2, params) => {
708
751
  let rb1;
709
752
  let rb2;
710
753
 
711
- if ('current' in body1 && body1.current && 'current' in body2 && body2.current) {
754
+ if ("current" in body1 && body1.current && "current" in body2 && body2.current) {
712
755
  rb1 = world.getRigidBody(body1.current.handle);
713
756
  rb2 = world.getRigidBody(body2.current.handle);
714
757
  const newJoint = world.createImpulseJoint(params, rb1, rb2);
@@ -741,9 +784,9 @@ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor,
741
784
  const {
742
785
  rapier
743
786
  } = useRapier();
744
- return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToObject(body1Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToObject(body1LocalFrame)), {}, {
787
+ return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToVector3(body1Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body1LocalFrame)), {}, {
745
788
  w: 1
746
- }), vectorArrayToObject(body2Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToObject(body2LocalFrame)), {}, {
789
+ }), vectorArrayToVector3(body2Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body2LocalFrame)), {}, {
747
790
  w: 1
748
791
  })));
749
792
  };
@@ -758,7 +801,7 @@ const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
758
801
  const {
759
802
  rapier
760
803
  } = useRapier();
761
- return useImpulseJoint(body1, body2, rapier.JointData.spherical(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor)));
804
+ return useImpulseJoint(body1, body2, rapier.JointData.spherical(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor)));
762
805
  };
763
806
  /**
764
807
  * The revolute joint prevents any relative movement between two rigid-bodies, except for relative
@@ -770,7 +813,7 @@ const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
770
813
  const {
771
814
  rapier
772
815
  } = useRapier();
773
- return useImpulseJoint(body1, body2, rapier.JointData.revolute(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor), vectorArrayToObject(axis)));
816
+ return useImpulseJoint(body1, body2, rapier.JointData.revolute(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
774
817
  };
775
818
  /**
776
819
  * The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
@@ -782,73 +825,18 @@ const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
782
825
  const {
783
826
  rapier
784
827
  } = useRapier();
785
- return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor), vectorArrayToObject(axis)));
828
+ return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
786
829
  };
787
830
 
788
- function _extends() {
789
- _extends = Object.assign || function (target) {
790
- for (var i = 1; i < arguments.length; i++) {
791
- var source = arguments[i];
792
-
793
- for (var key in source) {
794
- if (Object.prototype.hasOwnProperty.call(source, key)) {
795
- target[key] = source[key];
796
- }
797
- }
798
- }
799
-
800
- return target;
801
- };
802
-
803
- return _extends.apply(this, arguments);
804
- }
805
-
806
- function _objectWithoutPropertiesLoose(source, excluded) {
807
- if (source == null) return {};
808
- var target = {};
809
- var sourceKeys = Object.keys(source);
810
- var key, i;
811
-
812
- for (i = 0; i < sourceKeys.length; i++) {
813
- key = sourceKeys[i];
814
- if (excluded.indexOf(key) >= 0) continue;
815
- target[key] = source[key];
816
- }
817
-
818
- return target;
819
- }
820
-
821
- function _objectWithoutProperties(source, excluded) {
822
- if (source == null) return {};
823
- var target = _objectWithoutPropertiesLoose(source, excluded);
824
- var key, i;
825
-
826
- if (Object.getOwnPropertySymbols) {
827
- var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
828
-
829
- for (i = 0; i < sourceSymbolKeys.length; i++) {
830
- key = sourceSymbolKeys[i];
831
- if (excluded.indexOf(key) >= 0) continue;
832
- if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
833
- target[key] = source[key];
834
- }
835
- }
836
-
837
- return target;
838
- }
839
-
840
- const _excluded = ["children"],
841
- _excluded2 = ["children"];
831
+ const _excluded$1 = ["children"];
842
832
  const RigidBodyContext = /*#__PURE__*/createContext(undefined);
843
-
844
833
  const useRigidBodyContext = () => useContext(RigidBodyContext); // RigidBody
845
834
 
846
-
847
835
  const RigidBody = /*#__PURE__*/forwardRef((_ref, ref) => {
848
836
  let {
849
837
  children
850
838
  } = _ref,
851
- props = _objectWithoutProperties(_ref, _excluded);
839
+ props = _objectWithoutProperties(_ref, _excluded$1);
852
840
 
853
841
  const [object, api] = useRigidBody(props);
854
842
  useImperativeHandle(ref, () => api);
@@ -863,6 +851,7 @@ const RigidBody = /*#__PURE__*/forwardRef((_ref, ref) => {
863
851
  ref: object
864
852
  }, children));
865
853
  });
854
+
866
855
  const MeshCollider = ({
867
856
  children,
868
857
  type
@@ -880,9 +869,9 @@ const MeshCollider = ({
880
869
  let autoColliders = [];
881
870
 
882
871
  if (object.current) {
883
- var _ref2;
872
+ var _ref;
884
873
 
885
- const colliderSetting = (_ref2 = type !== null && type !== void 0 ? type : physicsOptions.colliders) !== null && _ref2 !== void 0 ? _ref2 : false;
874
+ const colliderSetting = (_ref = type !== null && type !== void 0 ? type : physicsOptions.colliders) !== null && _ref !== void 0 ? _ref : false;
886
875
  autoColliders = colliderSetting !== false ? createCollidersFromChildren(object.current, api, _objectSpread2(_objectSpread2({}, options), {}, {
887
876
  colliders: colliderSetting
888
877
  }), world, false) : [];
@@ -900,83 +889,6 @@ const MeshCollider = ({
900
889
  r3RapierType: "MeshCollider"
901
890
  }
902
891
  }, children);
903
- }; // Colliders
904
-
905
- const AnyCollider = _ref3 => {
906
- let {
907
- children
908
- } = _ref3,
909
- props = _objectWithoutProperties(_ref3, _excluded2);
910
-
911
- const {
912
- world
913
- } = useRapier();
914
- const rigidBodyContext = useRigidBodyContext();
915
- const ref = useRef(null);
916
- useEffect(() => {
917
- var _rigidBodyContext$api;
918
-
919
- const scale = ref.current.getWorldScale(new Vector3());
920
- const collider = createColliderFromOptions({
921
- options: props,
922
- world,
923
- rigidBody: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : (_rigidBodyContext$api = rigidBodyContext.api) === null || _rigidBodyContext$api === void 0 ? void 0 : _rigidBodyContext$api.raw(),
924
- scale,
925
- hasCollisionEvents: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.hasCollisionEvents
926
- });
927
- return () => {
928
- world.removeCollider(collider);
929
- };
930
- }, []);
931
- return /*#__PURE__*/React.createElement("object3D", {
932
- ref: ref
933
- }, children);
934
- };
935
-
936
- const CuboidCollider = props => {
937
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
938
- shape: "cuboid"
939
- }));
940
- };
941
- const RoundCuboidCollider = props => {
942
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
943
- shape: "roundCuboid"
944
- }));
945
- };
946
- const BallCollider = props => {
947
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
948
- shape: "ball"
949
- }));
950
- };
951
- const CapsuleCollider = props => {
952
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
953
- shape: "capsule"
954
- }));
955
- };
956
- const HeightfieldCollider = props => {
957
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
958
- shape: "heightfield"
959
- }));
960
- };
961
- const TrimeshCollider = props => {
962
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
963
- shape: "trimesh"
964
- }));
965
- };
966
- const ConeCollider = props => {
967
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
968
- shape: "cone"
969
- }));
970
- };
971
- const CylinderCollider = props => {
972
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
973
- shape: "cylinder"
974
- }));
975
- };
976
- const ConvexHullCollider = props => {
977
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
978
- shape: "convexHull"
979
- }));
980
892
  };
981
893
 
982
894
  const geometryFromCollider = collider => {
@@ -1094,4 +1006,212 @@ const Debug = () => {
1094
1006
  })));
1095
1007
  };
1096
1008
 
1097
- export { BallCollider, CapsuleCollider, ConeCollider, ConvexHullCollider, CuboidCollider, CylinderCollider, Debug, HeightfieldCollider, MeshCollider, Physics, RigidBody, RoundCuboidCollider, TrimeshCollider, useCollider, useFixedJoint, useImpulseJoint, usePrismaticJoint, useRapier, useRevoluteJoint, useRigidBody, useSphericalJoint };
1009
+ const InstancedRigidBodies = /*#__PURE__*/forwardRef((props, ref) => {
1010
+ const {
1011
+ world,
1012
+ rigidBodyStates,
1013
+ physicsOptions
1014
+ } = useRapier();
1015
+ const object = useRef(null);
1016
+ const instancesRef = useRef();
1017
+ const instancesRefGetter = useRef(() => {
1018
+ if (!instancesRef.current) {
1019
+ instancesRef.current = [];
1020
+ }
1021
+
1022
+ return instancesRef.current;
1023
+ });
1024
+ useEffect(() => {
1025
+ const colliders = [];
1026
+ const rigidBodies = instancesRefGetter.current();
1027
+
1028
+ if (object.current) {
1029
+ const worldScale = object.current.getWorldScale(new Vector3());
1030
+ let hasOneMesh = false;
1031
+ object.current.traverse(mesh => {
1032
+ if (mesh instanceof InstancedMesh) {
1033
+ if (hasOneMesh) {
1034
+ console.warn("Can only use a single InstancedMesh inside <InstancedRigidBodies />, more InstancedMeshes will be ignored.");
1035
+ return;
1036
+ }
1037
+
1038
+ hasOneMesh = true;
1039
+ mesh.instanceMatrix.setUsage(DynamicDrawUsage);
1040
+
1041
+ for (let index = 0; index < mesh.count; index++) {
1042
+ const scale = worldScale.clone();
1043
+ const rigidBodyDesc = rigidBodyDescFromOptions(props);
1044
+
1045
+ if (props.scales && props.scales[index]) {
1046
+ const s = vectorArrayToVector3(props.scales[index]);
1047
+ scale.multiply(s);
1048
+ }
1049
+
1050
+ const colliderDesc = colliderDescFromGeometry(mesh.geometry, props.colliders || physicsOptions.colliders, scale, false // Collisions currently not enabled for instances
1051
+ );
1052
+ const rigidBody = world.createRigidBody(rigidBodyDesc);
1053
+ const matrix = new Matrix4();
1054
+ mesh.getMatrixAt(index, matrix);
1055
+ const {
1056
+ position,
1057
+ rotation
1058
+ } = decomposeMatrix4(matrix); // Set positions
1059
+
1060
+ if (props.positions && props.positions[index]) {
1061
+ rigidBody.setTranslation(vectorArrayToVector3(props.positions[index]), true);
1062
+ } else {
1063
+ rigidBody.setTranslation(position, true);
1064
+ } // Set rotations
1065
+
1066
+
1067
+ if (props.rotations && props.rotations[index]) {
1068
+ const [x, y, z] = props.rotations[index];
1069
+ rigidBody.setRotation(vector3ToQuaternion(new Vector3(x, y, z)), true);
1070
+ } else {
1071
+ rigidBody.setRotation(rotation, true);
1072
+ }
1073
+
1074
+ const collider = world.createCollider(colliderDesc, rigidBody);
1075
+ rigidBodyStates.set(rigidBody.handle, {
1076
+ mesh: mesh,
1077
+ isSleeping: false,
1078
+ invertedMatrixWorld: object.current.matrixWorld.clone().invert(),
1079
+ setMatrix: matrix => mesh.setMatrixAt(index, matrix),
1080
+ getMatrix: () => {
1081
+ const m = new Matrix4();
1082
+ mesh.getMatrixAt(index, m);
1083
+ return m;
1084
+ },
1085
+ // Setting the world scale to the scale here, because
1086
+ // we want the scales to be reflected by instance
1087
+ worldScale: scale
1088
+ });
1089
+ const api = createRigidBodyApi({
1090
+ current() {
1091
+ return rigidBody;
1092
+ }
1093
+
1094
+ });
1095
+ colliders.push(collider);
1096
+ rigidBodies.push({
1097
+ rigidBody,
1098
+ api
1099
+ });
1100
+ }
1101
+ }
1102
+
1103
+ if (mesh.type === "Mesh" && !("isInstancedMesh" in mesh)) {
1104
+ console.warn("Can only use InstancedMesh inside <InstancedRigidBodies />, Mesh will be ignored.");
1105
+ }
1106
+ });
1107
+ return () => {
1108
+ rigidBodies.forEach(rb => world.removeRigidBody(rb.rigidBody));
1109
+ colliders.forEach(coll => world.removeCollider(coll));
1110
+ instancesRef.current = undefined;
1111
+ };
1112
+ }
1113
+ }, []);
1114
+ useImperativeHandle(ref, () => createInstancedRigidBodiesApi(instancesRefGetter));
1115
+ return /*#__PURE__*/React.createElement("object3D", {
1116
+ ref: object
1117
+ }, props.children);
1118
+ });
1119
+
1120
+ function _extends() {
1121
+ _extends = Object.assign || function (target) {
1122
+ for (var i = 1; i < arguments.length; i++) {
1123
+ var source = arguments[i];
1124
+
1125
+ for (var key in source) {
1126
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
1127
+ target[key] = source[key];
1128
+ }
1129
+ }
1130
+ }
1131
+
1132
+ return target;
1133
+ };
1134
+
1135
+ return _extends.apply(this, arguments);
1136
+ }
1137
+
1138
+ const _excluded = ["children"];
1139
+
1140
+ const AnyCollider = _ref => {
1141
+ let {
1142
+ children
1143
+ } = _ref,
1144
+ props = _objectWithoutProperties(_ref, _excluded);
1145
+
1146
+ const {
1147
+ world
1148
+ } = useRapier();
1149
+ const rigidBodyContext = useRigidBodyContext();
1150
+ const ref = useRef(null);
1151
+ useEffect(() => {
1152
+ var _rigidBodyContext$api;
1153
+
1154
+ const scale = ref.current.getWorldScale(new Vector3());
1155
+ const collider = createColliderFromOptions({
1156
+ options: props,
1157
+ world,
1158
+ rigidBody: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : (_rigidBodyContext$api = rigidBodyContext.api) === null || _rigidBodyContext$api === void 0 ? void 0 : _rigidBodyContext$api.raw(),
1159
+ scale,
1160
+ hasCollisionEvents: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.hasCollisionEvents
1161
+ });
1162
+ return () => {
1163
+ world.removeCollider(collider);
1164
+ };
1165
+ }, []);
1166
+ return /*#__PURE__*/React.createElement("object3D", {
1167
+ ref: ref
1168
+ }, children);
1169
+ };
1170
+
1171
+ const CuboidCollider = props => {
1172
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1173
+ shape: "cuboid"
1174
+ }));
1175
+ };
1176
+ const RoundCuboidCollider = props => {
1177
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1178
+ shape: "roundCuboid"
1179
+ }));
1180
+ };
1181
+ const BallCollider = props => {
1182
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1183
+ shape: "ball"
1184
+ }));
1185
+ };
1186
+ const CapsuleCollider = props => {
1187
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1188
+ shape: "capsule"
1189
+ }));
1190
+ };
1191
+ const HeightfieldCollider = props => {
1192
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1193
+ shape: "heightfield"
1194
+ }));
1195
+ };
1196
+ const TrimeshCollider = props => {
1197
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1198
+ shape: "trimesh"
1199
+ }));
1200
+ };
1201
+ const ConeCollider = props => {
1202
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1203
+ shape: "cone"
1204
+ }));
1205
+ };
1206
+ const CylinderCollider = props => {
1207
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1208
+ shape: "cylinder"
1209
+ }));
1210
+ };
1211
+ const ConvexHullCollider = props => {
1212
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1213
+ shape: "convexHull"
1214
+ }));
1215
+ };
1216
+
1217
+ export { BallCollider, CapsuleCollider, ConeCollider, ConvexHullCollider, CuboidCollider, CylinderCollider, Debug, HeightfieldCollider, InstancedRigidBodies, MeshCollider, Physics, RigidBody, RoundCuboidCollider, TrimeshCollider, useFixedJoint, useImpulseJoint, usePrismaticJoint, useRapier, useRevoluteJoint, useRigidBody, useSphericalJoint };