@react-three/rapier 0.5.1 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,15 @@
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
14
  const vectorArrayToObject = arr => {
9
15
  const [x, y, z] = arr;
@@ -13,6 +19,20 @@ const vectorArrayToObject = arr => {
13
19
  z
14
20
  };
15
21
  };
22
+ const vector3ToQuaternion = v => {
23
+ return _quaternion.setFromEuler(_euler.setFromVector3(v));
24
+ };
25
+ const rapierVector3ToVector3 = ({
26
+ x,
27
+ y,
28
+ z
29
+ }) => _vector3.set(x, y, z).clone();
30
+ const rapierQuaternionToQuaternion = ({
31
+ x,
32
+ y,
33
+ z,
34
+ w
35
+ }) => _quaternion.set(x, y, z, w);
16
36
  const rigidBodyTypeMap = {
17
37
  fixed: 1,
18
38
  dynamic: 0,
@@ -20,6 +40,17 @@ const rigidBodyTypeMap = {
20
40
  kinematicVelocity: 3
21
41
  };
22
42
  const rigidBodyTypeFromString = type => rigidBodyTypeMap[type];
43
+ const decomposeMatrix4 = m => {
44
+ const position = new Vector3();
45
+ const rotation = new Quaternion();
46
+ const scale = new Vector3();
47
+ m.decompose(position, rotation, scale);
48
+ return {
49
+ position,
50
+ rotation,
51
+ scale
52
+ };
53
+ };
23
54
  const scaleColliderArgs = (shape, args, scale) => {
24
55
  // Heightfield only scales the last arg
25
56
  const newArgs = args.slice();
@@ -38,11 +69,13 @@ const scaleColliderArgs = (shape, args, scale) => {
38
69
  const scaleArray = [scale.x, scale.y, scale.z];
39
70
  return newArgs.map((arg, index) => scaleArray[index] * arg);
40
71
  };
41
- const createColliderFromOptions = (options, world, rigidBody, scale = {
42
- x: 1,
43
- y: 1,
44
- z: 1
45
- }, hasCollisionEvents = false) => {
72
+ const createColliderFromOptions = ({
73
+ options,
74
+ world,
75
+ rigidBody,
76
+ scale,
77
+ hasCollisionEvents
78
+ }) => {
46
79
  var _options$shape, _options$args, _options$restitution, _options$restitutionC, _options$friction, _options$frictionComb;
47
80
 
48
81
  const mass = (options === null || options === void 0 ? void 0 : options.mass) || 1;
@@ -51,15 +84,16 @@ const createColliderFromOptions = (options, world, rigidBody, scale = {
51
84
  const [cmx, cmy, cmz] = (options === null || options === void 0 ? void 0 : options.centerOfMass) || [0, 0, 0];
52
85
  const [pix, piy, piz] = (options === null || options === void 0 ? void 0 : options.principalAngularInertia) || [mass * 0.2, mass * 0.2, mass * 0.2];
53
86
  const [x, y, z] = (options === null || options === void 0 ? void 0 : options.position) || [0, 0, 0];
54
- const [rx, ry, rz] = (options === null || options === void 0 ? void 0 : options.rotation) || [0, 0, 0]; // @ts-ignore
87
+ const [rx, ry, rz] = (options === null || options === void 0 ? void 0 : options.rotation) || [0, 0, 0];
88
+ const qRotation = vector3ToQuaternion(new Vector3(rx, ry, rz)); // @ts-ignore
55
89
 
56
90
  const scaledArgs = scaleColliderArgs(options.shape, colliderArgs, scale);
57
91
  let colliderDesc = ColliderDesc[colliderShape]( // @ts-ignore
58
92
  ...scaledArgs).setTranslation(x * scale.x, y * scale.y, z * scale.z).setRotation({
59
- x: rx,
60
- y: ry,
61
- z: rz,
62
- w: 1
93
+ x: qRotation.x,
94
+ y: qRotation.y,
95
+ z: qRotation.z,
96
+ w: qRotation.w
63
97
  }).setRestitution((_options$restitution = options === null || options === void 0 ? void 0 : options.restitution) !== null && _options$restitution !== void 0 ? _options$restitution : 0).setRestitutionCombineRule((_options$restitutionC = options === null || options === void 0 ? void 0 : options.restitutionCombineRule) !== null && _options$restitutionC !== void 0 ? _options$restitutionC : CoefficientCombineRule.Average).setFriction((_options$friction = options === null || options === void 0 ? void 0 : options.friction) !== null && _options$friction !== void 0 ? _options$friction : 0.7).setFrictionCombineRule((_options$frictionComb = options === null || options === void 0 ? void 0 : options.frictionCombineRule) !== null && _options$frictionComb !== void 0 ? _options$frictionComb : CoefficientCombineRule.Average);
64
98
 
65
99
  if (hasCollisionEvents) {
@@ -67,6 +101,8 @@ const createColliderFromOptions = (options, world, rigidBody, scale = {
67
101
  } // If any of the mass properties are specified, add mass properties
68
102
 
69
103
 
104
+ const qMassRot = vector3ToQuaternion(new Vector3(0, 0, 0));
105
+
70
106
  if (options !== null && options !== void 0 && options.mass || options !== null && options !== void 0 && options.centerOfMass || options !== null && options !== void 0 && options.principalAngularInertia) {
71
107
  colliderDesc.setDensity(0);
72
108
  colliderDesc.setMassProperties(mass, {
@@ -78,10 +114,10 @@ const createColliderFromOptions = (options, world, rigidBody, scale = {
78
114
  y: piy,
79
115
  z: piz
80
116
  }, {
81
- x: 0,
82
- y: 0,
83
- z: 0,
84
- w: 1
117
+ x: qMassRot.x,
118
+ y: qMassRot.y,
119
+ z: qMassRot.z,
120
+ w: qMassRot.w
85
121
  });
86
122
  }
87
123
 
@@ -100,8 +136,7 @@ const isChildOfMeshCollider = child => {
100
136
  const createCollidersFromChildren = (object, rigidBody, options, world, ignoreMeshColliders = true) => {
101
137
  const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
102
138
  const colliders = [];
103
- let desc;
104
- let offset = new Vector3();
139
+ new Vector3();
105
140
  object.traverse(child => {
106
141
  if ("isMesh" in child) {
107
142
  if (ignoreMeshColliders && isChildOfMeshCollider(child)) return;
@@ -119,62 +154,32 @@ const createCollidersFromChildren = (object, rigidBody, options, world, ignoreMe
119
154
  z: rz,
120
155
  w: rw
121
156
  } = new Quaternion().setFromEuler(child.rotation);
122
- const scale = child.getWorldScale(new Vector3());
123
-
124
- switch (options.colliders) {
125
- case "cuboid":
126
- {
127
- geometry.computeBoundingBox();
128
- const {
129
- boundingBox
130
- } = geometry;
131
- const size = boundingBox.getSize(new Vector3());
132
- boundingBox.getCenter(offset);
133
- desc = ColliderDesc.cuboid(size.x / 2 * scale.x, size.y / 2 * scale.y, size.z / 2 * scale.z);
134
- }
135
- break;
157
+ const scale = child.getWorldScale(new Vector3()); // We translate the colliders based on the parent's world scale
136
158
 
137
- case "ball":
138
- {
139
- geometry.computeBoundingSphere();
140
- const {
141
- boundingSphere
142
- } = geometry;
143
- const radius = boundingSphere.radius * scale.x;
144
- offset.copy(boundingSphere.center);
145
- desc = ColliderDesc.ball(radius);
146
- }
147
- break;
148
-
149
- case "trimesh":
150
- {
151
- var _g$index;
159
+ const parentWorldScale = child.parent.getWorldScale(new Vector3());
160
+ const desc = colliderDescFromGeometry(geometry, options.colliders, scale, hasCollisionEvents);
161
+ const offset = new Vector3(0, 0, 0);
152
162
 
153
- const _g = geometry.clone().scale(scale.x, scale.y, scale.z);
163
+ if (options.colliders === "cuboid") {
164
+ var _geometry$boundingBox;
154
165
 
155
- desc = ColliderDesc.trimesh(_g.attributes.position.array, (_g$index = _g.index) === null || _g$index === void 0 ? void 0 : _g$index.array);
156
- }
157
- break;
158
-
159
- case "hull":
160
- const g = geometry.clone().scale(scale.x, scale.y, scale.z);
161
- {
162
- desc = ColliderDesc.convexHull(g.attributes.position.array);
163
- }
164
- break;
165
- } // We translate the colliders based on the parent's world scale
166
+ geometry.computeBoundingBox();
167
+ (_geometry$boundingBox = geometry.boundingBox) === null || _geometry$boundingBox === void 0 ? void 0 : _geometry$boundingBox.getCenter(offset);
168
+ }
166
169
 
170
+ if (options.colliders === "ball") {
171
+ geometry.computeBoundingSphere();
172
+ offset.copy(geometry.boundingSphere.center);
173
+ }
167
174
 
168
- const parentWorldScale = child.parent.getWorldScale(new Vector3());
175
+ if (Number.isFinite(options.friction)) desc.setFriction(options.friction);
176
+ if (Number.isFinite(options.restitution)) desc.setRestitution(options.restitution);
169
177
  desc.setTranslation((x + offset.x) * parentWorldScale.x, (y + offset.y) * parentWorldScale.y, (z + offset.z) * parentWorldScale.z).setRotation({
170
178
  x: rx,
171
179
  y: ry,
172
180
  z: rz,
173
181
  w: rw
174
182
  });
175
- if (hasCollisionEvents) desc.setActiveEvents(ActiveEvents.COLLISION_EVENTS);
176
- if (Number.isFinite(options.friction)) desc.setFriction(options.friction);
177
- if (Number.isFinite(options.restitution)) desc.setRestitution(options.restitution);
178
183
  const actualRigidBody = world.getRigidBody(rigidBody === null || rigidBody === void 0 ? void 0 : rigidBody.handle);
179
184
  const collider = world.createCollider(desc, actualRigidBody);
180
185
  colliders.push(collider);
@@ -182,6 +187,53 @@ const createCollidersFromChildren = (object, rigidBody, options, world, ignoreMe
182
187
  });
183
188
  return colliders;
184
189
  };
190
+ const colliderDescFromGeometry = (geometry, colliders, scale, hasCollisionEvents) => {
191
+ let desc;
192
+
193
+ switch (colliders) {
194
+ case "cuboid":
195
+ {
196
+ geometry.computeBoundingBox();
197
+ const {
198
+ boundingBox
199
+ } = geometry;
200
+ const size = boundingBox.getSize(new Vector3());
201
+ desc = ColliderDesc.cuboid(size.x / 2 * scale.x, size.y / 2 * scale.y, size.z / 2 * scale.z);
202
+ }
203
+ break;
204
+
205
+ case "ball":
206
+ {
207
+ geometry.computeBoundingSphere();
208
+ const {
209
+ boundingSphere
210
+ } = geometry;
211
+ const radius = boundingSphere.radius * scale.x;
212
+ desc = ColliderDesc.ball(radius);
213
+ }
214
+ break;
215
+
216
+ case "trimesh":
217
+ {
218
+ var _g$index;
219
+
220
+ const _g = geometry.clone().scale(scale.x, scale.y, scale.z);
221
+
222
+ desc = ColliderDesc.trimesh(_g.attributes.position.array, (_g$index = _g.index) === null || _g$index === void 0 ? void 0 : _g$index.array);
223
+ }
224
+ break;
225
+
226
+ case "hull":
227
+ const g = geometry.clone().scale(scale.x, scale.y, scale.z);
228
+ {
229
+ desc = ColliderDesc.convexHull(g.attributes.position.array);
230
+ }
231
+ break;
232
+ }
233
+
234
+ if (hasCollisionEvents) desc.setActiveEvents(ActiveEvents.COLLISION_EVENTS);
235
+ return desc;
236
+ };
185
237
  const scaleVertices = (vertices, scale) => {
186
238
  const scaledVerts = Array.from(vertices);
187
239
 
@@ -193,10 +245,25 @@ const scaleVertices = (vertices, scale) => {
193
245
 
194
246
  return scaledVerts;
195
247
  };
196
- const quaternion = new Quaternion();
197
- const euler = new Euler();
198
- const vector3ToQuaternion = v => {
199
- return quaternion.setFromEuler(euler.setFromVector3(v));
248
+ const rigidBodyDescFromOptions = options => {
249
+ var _options$linearVeloci, _options$angularVeloc, _options$gravityScale, _options$canSleep, _options$ccd, _options$enabledRotat, _options$enabledTrans;
250
+
251
+ const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
252
+ 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];
253
+ 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];
254
+ const gravityScale = (_options$gravityScale = options === null || options === void 0 ? void 0 : options.gravityScale) !== null && _options$gravityScale !== void 0 ? _options$gravityScale : 1;
255
+ const canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
256
+ const ccdEnabled = (_options$ccd = options === null || options === void 0 ? void 0 : options.ccd) !== null && _options$ccd !== void 0 ? _options$ccd : false;
257
+ 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];
258
+ 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];
259
+ const desc = new RigidBodyDesc(type).setLinvel(lvx, lvy, lvz).setAngvel({
260
+ x: avx,
261
+ y: avy,
262
+ z: avz
263
+ }).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled).enabledRotations(erx, ery, erz).enabledTranslations(etx, ety, etz);
264
+ if (options.lockRotations) desc.lockRotations();
265
+ if (options.lockTranslations) desc.lockTranslations();
266
+ return desc;
200
267
  };
201
268
 
202
269
  const createRigidBodyApi = ref => {
@@ -299,18 +366,19 @@ const createRigidBodyApi = ref => {
299
366
  setEnabledRotations: (x, y, z) => ref.current().setEnabledRotations(x, y, z, true),
300
367
  setEnabledTranslations: (x, y, z) => ref.current().setEnabledTranslations(x, y, z, true)
301
368
  };
302
- }; // TODO: Flesh this out
369
+ };
370
+ const createInstancedRigidBodiesApi = bodiesGetter => ({
371
+ at: index => bodiesGetter.current()[index].api,
303
372
 
304
- const createColliderApi = ref => {
305
- return {
306
- raw: () => ref.current(),
373
+ forEach(callback) {
374
+ return bodiesGetter.current().map(b => b.api).forEach(callback);
375
+ },
307
376
 
308
- get handle() {
309
- return ref.current().handle;
310
- }
377
+ get count() {
378
+ return bodiesGetter.current().length;
379
+ }
311
380
 
312
- };
313
- };
381
+ }); // TODO: Flesh this out
314
382
  const createWorldApi = ref => {
315
383
  return {
316
384
  raw: () => ref.current(),
@@ -357,10 +425,10 @@ const importRapier = async () => {
357
425
  };
358
426
 
359
427
  const Physics = ({
360
- colliders: _colliders = 'cuboid',
428
+ colliders: _colliders = "cuboid",
361
429
  gravity: _gravity = [0, -9.81, 0],
362
430
  children,
363
- timeStep: _timeStep = 'vary'
431
+ timeStep: _timeStep = "vary"
364
432
  }) => {
365
433
  const rapier = useAsset(importRapier);
366
434
  const worldRef = useRef();
@@ -373,7 +441,7 @@ const Physics = ({
373
441
  return worldRef.current;
374
442
  });
375
443
  const [colliderMeshes] = useState(() => new Map());
376
- const [rigidBodyMeshes] = useState(() => new Map());
444
+ const [rigidBodyStates] = useState(() => new Map());
377
445
  const [rigidBodyEvents] = useState(() => new Map());
378
446
  const [eventQueue] = useState(() => new EventQueue(false)); // Init world
379
447
 
@@ -403,7 +471,7 @@ const Physics = ({
403
471
  const now = performance.now();
404
472
  const delta = Math.min(100, now - time.current);
405
473
 
406
- if (_timeStep === 'vary') {
474
+ if (_timeStep === "vary") {
407
475
  world.timestep = delta / 1000;
408
476
  } else {
409
477
  world.timestep = _timeStep;
@@ -411,52 +479,35 @@ const Physics = ({
411
479
 
412
480
  world.step(eventQueue); // Update meshes
413
481
 
414
- rigidBodyMeshes.forEach((mesh, handle) => {
482
+ rigidBodyStates.forEach((state, handle) => {
415
483
  const rigidBody = world.getRigidBody(handle);
416
484
  const events = rigidBodyEvents.get(handle);
417
485
 
418
486
  if (events !== null && events !== void 0 && events.onSleep || events !== null && events !== void 0 && events.onWake) {
419
- if (rigidBody.isSleeping() && !mesh.userData.isSleeping) {
487
+ if (rigidBody.isSleeping() && !state.isSleeping) {
420
488
  var _events$onSleep;
421
489
 
422
490
  events === null || events === void 0 ? void 0 : (_events$onSleep = events.onSleep) === null || _events$onSleep === void 0 ? void 0 : _events$onSleep.call(events);
423
491
  }
424
492
 
425
- if (!rigidBody.isSleeping() && mesh.userData.isSleeping) {
493
+ if (!rigidBody.isSleeping() && state.isSleeping) {
426
494
  var _events$onWake;
427
495
 
428
496
  events === null || events === void 0 ? void 0 : (_events$onWake = events.onWake) === null || _events$onWake === void 0 ? void 0 : _events$onWake.call(events);
429
497
  }
430
498
 
431
- mesh.userData.isSleeping = rigidBody.isSleeping();
499
+ state.isSleeping = rigidBody.isSleeping();
432
500
  }
433
501
 
434
- if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !mesh.parent) {
502
+ if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !state.setMatrix) {
435
503
  return;
436
504
  }
437
505
 
438
- const {
439
- x,
440
- y,
441
- z
442
- } = rigidBody.translation();
443
- const {
444
- x: rx,
445
- y: ry,
446
- z: rz,
447
- w: rw
448
- } = rigidBody.rotation();
449
- const scale = mesh.getWorldScale(new Vector3()); // haha matrixes I have no idea what I'm doing :)
450
-
451
- const o = new Object3D();
452
- o.position.set(x, y, z);
453
- o.rotation.setFromQuaternion(new Quaternion(rx, ry, rz, rw));
454
- o.scale.set(scale.x, scale.y, scale.z);
455
- o.updateMatrix();
456
- o.applyMatrix4(mesh.parent.matrixWorld.clone().invert());
457
- o.updateMatrix();
458
- mesh.position.setFromMatrixPosition(o.matrix);
459
- mesh.rotation.setFromRotationMatrix(o.matrix);
506
+ state.setMatrix(_matrix4.compose(rapierVector3ToVector3(rigidBody.translation()), rapierQuaternionToQuaternion(rigidBody.rotation()), state.worldScale).premultiply(state.invertedMatrixWorld));
507
+
508
+ if (state.mesh instanceof InstancedMesh) {
509
+ state.mesh.instanceMatrix.needsUpdate = true;
510
+ }
460
511
  }); // Collision events
461
512
 
462
513
  eventQueue.drainCollisionEvents((handle1, handle2, started) => {
@@ -513,7 +564,7 @@ const Physics = ({
513
564
  gravity: _gravity
514
565
  },
515
566
  colliderMeshes,
516
- rigidBodyMeshes,
567
+ rigidBodyStates,
517
568
  rigidBodyEvents
518
569
  }), []);
519
570
  return /*#__PURE__*/React.createElement(RapierContext.Provider, {
@@ -521,6 +572,40 @@ const Physics = ({
521
572
  }, children);
522
573
  };
523
574
 
575
+ function _objectWithoutPropertiesLoose(source, excluded) {
576
+ if (source == null) return {};
577
+ var target = {};
578
+ var sourceKeys = Object.keys(source);
579
+ var key, i;
580
+
581
+ for (i = 0; i < sourceKeys.length; i++) {
582
+ key = sourceKeys[i];
583
+ if (excluded.indexOf(key) >= 0) continue;
584
+ target[key] = source[key];
585
+ }
586
+
587
+ return target;
588
+ }
589
+
590
+ function _objectWithoutProperties(source, excluded) {
591
+ if (source == null) return {};
592
+ var target = _objectWithoutPropertiesLoose(source, excluded);
593
+ var key, i;
594
+
595
+ if (Object.getOwnPropertySymbols) {
596
+ var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
597
+
598
+ for (i = 0; i < sourceSymbolKeys.length; i++) {
599
+ key = sourceSymbolKeys[i];
600
+ if (excluded.indexOf(key) >= 0) continue;
601
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
602
+ target[key] = source[key];
603
+ }
604
+ }
605
+
606
+ return target;
607
+ }
608
+
524
609
  function _defineProperty(obj, key, value) {
525
610
  if (key in obj) {
526
611
  Object.defineProperty(obj, key, {
@@ -567,9 +652,8 @@ const useRapier = () => {
567
652
  };
568
653
  const useRigidBody = (options = {}) => {
569
654
  const {
570
- rapier,
571
655
  world,
572
- rigidBodyMeshes,
656
+ rigidBodyStates,
573
657
  physicsOptions,
574
658
  rigidBodyEvents
575
659
  } = useRapier();
@@ -578,23 +662,7 @@ const useRigidBody = (options = {}) => {
578
662
  const rigidBodyRef = useRef();
579
663
  const getRigidBodyRef = useRef(() => {
580
664
  if (!rigidBodyRef.current) {
581
- var _options$linearVeloci, _options$angularVeloc, _options$gravityScale, _options$canSleep, _options$ccd, _options$enabledRotat, _options$enabledTrans;
582
-
583
- const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
584
- 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];
585
- 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];
586
- const gravityScale = (_options$gravityScale = options === null || options === void 0 ? void 0 : options.gravityScale) !== null && _options$gravityScale !== void 0 ? _options$gravityScale : 1;
587
- const canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
588
- const ccdEnabled = (_options$ccd = options === null || options === void 0 ? void 0 : options.ccd) !== null && _options$ccd !== void 0 ? _options$ccd : false;
589
- 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];
590
- 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];
591
- const desc = new rapier.RigidBodyDesc(type).setLinvel(lvx, lvy, lvz).setAngvel({
592
- x: avx,
593
- y: avy,
594
- z: avz
595
- }).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled).enabledRotations(erx, ery, erz).enabledTranslations(etx, ety, etz);
596
- if (options.lockRotations) desc.lockRotations();
597
- if (options.lockTranslations) desc.lockTranslations();
665
+ const desc = rigidBodyDescFromOptions(options);
598
666
  const rigidBody = world.createRigidBody(desc);
599
667
  rigidBodyRef.current = world.getRigidBody(rigidBody.handle);
600
668
  }
@@ -631,8 +699,7 @@ const useRigidBody = (options = {}) => {
631
699
  y: worldPosition.y + y * scale.y,
632
700
  z: worldPosition.z + z * scale.z
633
701
  }, false);
634
- const eulerAngles = new Euler(rx, ry, rz, 'XYZ');
635
- const rotation = new Quaternion().setFromEuler(eulerAngles).multiply(worldRotation);
702
+ const rotation = vector3ToQuaternion(new Vector3(rx, ry, rz)).multiply(worldRotation);
636
703
  rigidBody.setRotation({
637
704
  x: rotation.x,
638
705
  y: rotation.y,
@@ -645,12 +712,19 @@ const useRigidBody = (options = {}) => {
645
712
  const autoColliders = colliderSetting !== false ? createCollidersFromChildren(ref.current, rigidBody, _objectSpread2(_objectSpread2({}, options), {}, {
646
713
  colliders: colliderSetting
647
714
  }), world) : [];
648
- rigidBodyMeshes.set(rigidBody.handle, ref.current);
715
+ rigidBodyStates.set(rigidBody.handle, {
716
+ mesh: ref.current,
717
+ invertedMatrixWorld: ref.current.parent.matrixWorld.clone().invert(),
718
+ isSleeping: false,
719
+ worldScale: ref.current.getWorldScale(_vector3).clone(),
720
+ setMatrix: mat => ref.current.matrix.copy(mat)
721
+ });
722
+ ref.current.matrixAutoUpdate = false;
649
723
  return () => {
650
724
  world.removeRigidBody(rigidBody);
651
725
  autoColliders.forEach(collider => world.removeCollider(collider));
652
726
  rigidBodyRef.current = undefined;
653
- rigidBodyMeshes.delete(rigidBody.handle);
727
+ rigidBodyStates.delete(rigidBody.handle);
654
728
  };
655
729
  }, []); // Events
656
730
 
@@ -668,29 +742,6 @@ const useRigidBody = (options = {}) => {
668
742
  }, [options.onCollisionEnter, options.onCollisionExit]);
669
743
  const api = useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
670
744
  return [ref, api];
671
- };
672
- const useCollider = (body, options = {}) => {
673
- const {
674
- world
675
- } = useRapier();
676
- const colliderRef = useRef();
677
- const objectRef = useRef();
678
- const getColliderRef = useRef(() => {
679
- if (!colliderRef.current) {
680
- colliderRef.current = createColliderFromOptions(options, world, world.getRigidBody(body.handle));
681
- }
682
-
683
- return colliderRef.current;
684
- });
685
- useEffect(() => {
686
- const collider = getColliderRef.current();
687
- return () => {
688
- if (collider) world.removeCollider(collider);
689
- colliderRef.current = undefined;
690
- };
691
- }, []);
692
- const api = useMemo(() => createColliderApi(getColliderRef), []);
693
- return [objectRef, api];
694
745
  }; // Joints
695
746
 
696
747
  const useImpulseJoint = (body1, body2, params) => {
@@ -703,7 +754,7 @@ const useImpulseJoint = (body1, body2, params) => {
703
754
  let rb1;
704
755
  let rb2;
705
756
 
706
- if ('current' in body1 && body1.current && 'current' in body2 && body2.current) {
757
+ if ("current" in body1 && body1.current && "current" in body2 && body2.current) {
707
758
  rb1 = world.getRigidBody(body1.current.handle);
708
759
  rb2 = world.getRigidBody(body2.current.handle);
709
760
  const newJoint = world.createImpulseJoint(params, rb1, rb2);
@@ -780,79 +831,30 @@ const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
780
831
  return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor), vectorArrayToObject(axis)));
781
832
  };
782
833
 
783
- function _extends() {
784
- _extends = Object.assign || function (target) {
785
- for (var i = 1; i < arguments.length; i++) {
786
- var source = arguments[i];
787
-
788
- for (var key in source) {
789
- if (Object.prototype.hasOwnProperty.call(source, key)) {
790
- target[key] = source[key];
791
- }
792
- }
793
- }
794
-
795
- return target;
796
- };
797
-
798
- return _extends.apply(this, arguments);
799
- }
800
-
801
- function _objectWithoutPropertiesLoose(source, excluded) {
802
- if (source == null) return {};
803
- var target = {};
804
- var sourceKeys = Object.keys(source);
805
- var key, i;
806
-
807
- for (i = 0; i < sourceKeys.length; i++) {
808
- key = sourceKeys[i];
809
- if (excluded.indexOf(key) >= 0) continue;
810
- target[key] = source[key];
811
- }
812
-
813
- return target;
814
- }
815
-
816
- function _objectWithoutProperties(source, excluded) {
817
- if (source == null) return {};
818
- var target = _objectWithoutPropertiesLoose(source, excluded);
819
- var key, i;
820
-
821
- if (Object.getOwnPropertySymbols) {
822
- var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
823
-
824
- for (i = 0; i < sourceSymbolKeys.length; i++) {
825
- key = sourceSymbolKeys[i];
826
- if (excluded.indexOf(key) >= 0) continue;
827
- if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
828
- target[key] = source[key];
829
- }
830
- }
831
-
832
- return target;
833
- }
834
-
835
- const _excluded = ["children"],
836
- _excluded2 = ["children"];
834
+ const _excluded$1 = ["children"];
837
835
  const RigidBodyContext = /*#__PURE__*/createContext(undefined);
838
-
839
836
  const useRigidBodyContext = () => useContext(RigidBodyContext); // RigidBody
840
837
 
841
-
842
838
  const RigidBody = /*#__PURE__*/forwardRef((_ref, ref) => {
843
839
  let {
844
840
  children
845
841
  } = _ref,
846
- props = _objectWithoutProperties(_ref, _excluded);
842
+ props = _objectWithoutProperties(_ref, _excluded$1);
847
843
 
848
- const [object, rigidBody] = useRigidBody(props);
849
- useImperativeHandle(ref, () => rigidBody);
844
+ const [object, api] = useRigidBody(props);
845
+ useImperativeHandle(ref, () => api);
850
846
  return /*#__PURE__*/React.createElement(RigidBodyContext.Provider, {
851
- value: [object, rigidBody, !!(props.onCollisionEnter || props.onCollisionExit), props]
847
+ value: {
848
+ ref: object,
849
+ api,
850
+ hasCollisionEvents: !!(props.onCollisionEnter || props.onCollisionExit),
851
+ options: props
852
+ }
852
853
  }, /*#__PURE__*/React.createElement("object3D", {
853
854
  ref: object
854
855
  }, children));
855
856
  });
857
+
856
858
  const MeshCollider = ({
857
859
  children,
858
860
  type
@@ -862,15 +864,18 @@ const MeshCollider = ({
862
864
  world
863
865
  } = useRapier();
864
866
  const object = useRef(null);
865
- const [, rigidBody, hasCollisionEvents, rigidBodyOptions] = useRigidBodyContext();
867
+ const {
868
+ api,
869
+ options
870
+ } = useRigidBodyContext();
866
871
  useEffect(() => {
867
872
  let autoColliders = [];
868
873
 
869
874
  if (object.current) {
870
- var _ref2;
875
+ var _ref;
871
876
 
872
- const colliderSetting = (_ref2 = type !== null && type !== void 0 ? type : physicsOptions.colliders) !== null && _ref2 !== void 0 ? _ref2 : false;
873
- autoColliders = colliderSetting !== false ? createCollidersFromChildren(object.current, rigidBody, _objectSpread2(_objectSpread2({}, rigidBodyOptions), {}, {
877
+ const colliderSetting = (_ref = type !== null && type !== void 0 ? type : physicsOptions.colliders) !== null && _ref !== void 0 ? _ref : false;
878
+ autoColliders = colliderSetting !== false ? createCollidersFromChildren(object.current, api, _objectSpread2(_objectSpread2({}, options), {}, {
874
879
  colliders: colliderSetting
875
880
  }), world, false) : [];
876
881
  }
@@ -884,78 +889,9 @@ const MeshCollider = ({
884
889
  return /*#__PURE__*/React.createElement("object3D", {
885
890
  ref: object,
886
891
  userData: {
887
- r3RapierType: 'MeshCollider'
892
+ r3RapierType: "MeshCollider"
888
893
  }
889
894
  }, children);
890
- }; // Colliders
891
-
892
- const AnyCollider = _ref3 => {
893
- let {
894
- children
895
- } = _ref3,
896
- props = _objectWithoutProperties(_ref3, _excluded2);
897
-
898
- const {
899
- world
900
- } = useRapier();
901
- const [, rigidBody, hasCollisionEvents] = useRigidBodyContext();
902
- const ref = useRef(null);
903
- useEffect(() => {
904
- const scale = ref.current.getWorldScale(new Vector3());
905
- const collider = createColliderFromOptions(props, world, rigidBody.raw(), scale, hasCollisionEvents);
906
- return () => {
907
- world.removeCollider(collider);
908
- };
909
- }, []);
910
- return /*#__PURE__*/React.createElement("object3D", {
911
- ref: ref
912
- }, children);
913
- };
914
-
915
- const CuboidCollider = props => {
916
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
917
- shape: "cuboid"
918
- }));
919
- };
920
- const RoundCuboidCollider = props => {
921
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
922
- shape: "roundCuboid"
923
- }));
924
- };
925
- const BallCollider = props => {
926
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
927
- shape: "ball"
928
- }));
929
- };
930
- const CapsuleCollider = props => {
931
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
932
- shape: "capsule"
933
- }));
934
- };
935
- const HeightfieldCollider = props => {
936
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
937
- shape: "heightfield"
938
- }));
939
- };
940
- const TrimeshCollider = props => {
941
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
942
- shape: "trimesh"
943
- }));
944
- };
945
- const ConeCollider = props => {
946
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
947
- shape: "cone"
948
- }));
949
- };
950
- const CylinderCollider = props => {
951
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
952
- shape: "cylinder"
953
- }));
954
- };
955
- const ConvexHullCollider = props => {
956
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
957
- shape: "convexHull"
958
- }));
959
895
  };
960
896
 
961
897
  const geometryFromCollider = collider => {
@@ -1073,4 +1009,198 @@ const Debug = () => {
1073
1009
  })));
1074
1010
  };
1075
1011
 
1076
- export { BallCollider, CapsuleCollider, ConeCollider, ConvexHullCollider, CuboidCollider, CylinderCollider, Debug, HeightfieldCollider, MeshCollider, Physics, RigidBody, RoundCuboidCollider, TrimeshCollider, useCollider, useFixedJoint, useImpulseJoint, usePrismaticJoint, useRapier, useRevoluteJoint, useRigidBody, useSphericalJoint };
1012
+ const InstancedRigidBodies = /*#__PURE__*/forwardRef((props, ref) => {
1013
+ const {
1014
+ world,
1015
+ rigidBodyStates,
1016
+ physicsOptions
1017
+ } = useRapier();
1018
+ const object = useRef(null);
1019
+ const instancesRef = useRef();
1020
+ const instancesRefGetter = useRef(() => {
1021
+ if (!instancesRef.current) {
1022
+ instancesRef.current = [];
1023
+ }
1024
+
1025
+ return instancesRef.current;
1026
+ });
1027
+ useEffect(() => {
1028
+ const colliders = [];
1029
+ const rigidBodies = instancesRefGetter.current();
1030
+
1031
+ if (object.current) {
1032
+ const scale = object.current.getWorldScale(new Vector3());
1033
+ let hasOneMesh = false;
1034
+ object.current.traverse(mesh => {
1035
+ if (mesh instanceof InstancedMesh) {
1036
+ if (hasOneMesh) {
1037
+ console.warn("Can only use a single InstancedMesh inside <InstancedRigidBodies />, more InstancedMeshes will be ignored.");
1038
+ return;
1039
+ }
1040
+
1041
+ hasOneMesh = true;
1042
+ mesh.instanceMatrix.setUsage(DynamicDrawUsage);
1043
+ const rigidBodyDesc = rigidBodyDescFromOptions(props);
1044
+ const colliderDesc = colliderDescFromGeometry(mesh.geometry, props.colliders || physicsOptions.colliders, scale, false // Collisions currently not enabled for instances
1045
+ );
1046
+
1047
+ for (let index = 0; index < mesh.count; index++) {
1048
+ const rigidBody = world.createRigidBody(rigidBodyDesc);
1049
+ const matrix = new Matrix4();
1050
+ mesh.getMatrixAt(index, matrix);
1051
+ const {
1052
+ position,
1053
+ rotation
1054
+ } = decomposeMatrix4(matrix); // Set positions
1055
+
1056
+ if (props.positions && props.positions[index]) {
1057
+ rigidBody.setTranslation(vectorArrayToObject(props.positions[index]), true);
1058
+ } else {
1059
+ rigidBody.setTranslation(position, true);
1060
+ } // Set rotations
1061
+
1062
+
1063
+ if (props.rotations && props.rotations[index]) {
1064
+ const [x, y, z] = props.rotations[index];
1065
+ rigidBody.setRotation(vector3ToQuaternion(new Vector3(x, y, z)), true);
1066
+ } else {
1067
+ rigidBody.setRotation(rotation, true);
1068
+ }
1069
+
1070
+ const collider = world.createCollider(colliderDesc, rigidBody);
1071
+ rigidBodyStates.set(rigidBody.handle, {
1072
+ mesh: mesh,
1073
+ isSleeping: false,
1074
+ invertedMatrixWorld: object.current.matrixWorld.clone().invert(),
1075
+ setMatrix: matrix => mesh.setMatrixAt(index, matrix),
1076
+ worldScale: object.current.getWorldScale(new Vector3())
1077
+ });
1078
+ const api = createRigidBodyApi({
1079
+ current() {
1080
+ return rigidBody;
1081
+ }
1082
+
1083
+ });
1084
+ colliders.push(collider);
1085
+ rigidBodies.push({
1086
+ rigidBody,
1087
+ api
1088
+ });
1089
+ }
1090
+ }
1091
+
1092
+ if (mesh.type === "Mesh" && !("isInstancedMesh" in mesh)) {
1093
+ console.warn("Can only use InstancedMesh inside <InstancedRigidBodies />, Mesh will be ignored.");
1094
+ }
1095
+ });
1096
+ return () => {
1097
+ rigidBodies.forEach(rb => world.removeRigidBody(rb.rigidBody));
1098
+ colliders.forEach(coll => world.removeCollider(coll));
1099
+ instancesRef.current = undefined;
1100
+ };
1101
+ }
1102
+ }, []);
1103
+ useImperativeHandle(ref, () => createInstancedRigidBodiesApi(instancesRefGetter));
1104
+ return /*#__PURE__*/React.createElement("object3D", {
1105
+ ref: object
1106
+ }, props.children);
1107
+ });
1108
+
1109
+ function _extends() {
1110
+ _extends = Object.assign || function (target) {
1111
+ for (var i = 1; i < arguments.length; i++) {
1112
+ var source = arguments[i];
1113
+
1114
+ for (var key in source) {
1115
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
1116
+ target[key] = source[key];
1117
+ }
1118
+ }
1119
+ }
1120
+
1121
+ return target;
1122
+ };
1123
+
1124
+ return _extends.apply(this, arguments);
1125
+ }
1126
+
1127
+ const _excluded = ["children"];
1128
+
1129
+ const AnyCollider = _ref => {
1130
+ let {
1131
+ children
1132
+ } = _ref,
1133
+ props = _objectWithoutProperties(_ref, _excluded);
1134
+
1135
+ const {
1136
+ world
1137
+ } = useRapier();
1138
+ const rigidBodyContext = useRigidBodyContext();
1139
+ const ref = useRef(null);
1140
+ useEffect(() => {
1141
+ var _rigidBodyContext$api;
1142
+
1143
+ const scale = ref.current.getWorldScale(new Vector3());
1144
+ const collider = createColliderFromOptions({
1145
+ options: props,
1146
+ world,
1147
+ rigidBody: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : (_rigidBodyContext$api = rigidBodyContext.api) === null || _rigidBodyContext$api === void 0 ? void 0 : _rigidBodyContext$api.raw(),
1148
+ scale,
1149
+ hasCollisionEvents: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.hasCollisionEvents
1150
+ });
1151
+ return () => {
1152
+ world.removeCollider(collider);
1153
+ };
1154
+ }, []);
1155
+ return /*#__PURE__*/React.createElement("object3D", {
1156
+ ref: ref
1157
+ }, children);
1158
+ };
1159
+
1160
+ const CuboidCollider = props => {
1161
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1162
+ shape: "cuboid"
1163
+ }));
1164
+ };
1165
+ const RoundCuboidCollider = props => {
1166
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1167
+ shape: "roundCuboid"
1168
+ }));
1169
+ };
1170
+ const BallCollider = props => {
1171
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1172
+ shape: "ball"
1173
+ }));
1174
+ };
1175
+ const CapsuleCollider = props => {
1176
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1177
+ shape: "capsule"
1178
+ }));
1179
+ };
1180
+ const HeightfieldCollider = props => {
1181
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1182
+ shape: "heightfield"
1183
+ }));
1184
+ };
1185
+ const TrimeshCollider = props => {
1186
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1187
+ shape: "trimesh"
1188
+ }));
1189
+ };
1190
+ const ConeCollider = props => {
1191
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1192
+ shape: "cone"
1193
+ }));
1194
+ };
1195
+ const CylinderCollider = props => {
1196
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1197
+ shape: "cylinder"
1198
+ }));
1199
+ };
1200
+ const ConvexHullCollider = props => {
1201
+ return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1202
+ shape: "convexHull"
1203
+ }));
1204
+ };
1205
+
1206
+ export { BallCollider, CapsuleCollider, ConeCollider, ConvexHullCollider, CuboidCollider, CylinderCollider, Debug, HeightfieldCollider, InstancedRigidBodies, MeshCollider, Physics, RigidBody, RoundCuboidCollider, TrimeshCollider, useFixedJoint, useImpulseJoint, usePrismaticJoint, useRapier, useRevoluteJoint, useRigidBody, useSphericalJoint };