@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.
@@ -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,6 +30,12 @@ function _interopNamespace(e) {
30
30
 
31
31
  var React__default = /*#__PURE__*/_interopDefault(React);
32
32
 
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
+
33
39
  const vectorArrayToObject = arr => {
34
40
  const [x, y, z] = arr;
35
41
  return {
@@ -38,6 +44,20 @@ const vectorArrayToObject = arr => {
38
44
  z
39
45
  };
40
46
  };
47
+ const vector3ToQuaternion = v => {
48
+ return _quaternion.setFromEuler(_euler.setFromVector3(v));
49
+ };
50
+ const rapierVector3ToVector3 = ({
51
+ x,
52
+ y,
53
+ z
54
+ }) => _vector3.set(x, y, z).clone();
55
+ const rapierQuaternionToQuaternion = ({
56
+ x,
57
+ y,
58
+ z,
59
+ w
60
+ }) => _quaternion.set(x, y, z, w);
41
61
  const rigidBodyTypeMap = {
42
62
  fixed: 1,
43
63
  dynamic: 0,
@@ -45,6 +65,17 @@ const rigidBodyTypeMap = {
45
65
  kinematicVelocity: 3
46
66
  };
47
67
  const rigidBodyTypeFromString = type => rigidBodyTypeMap[type];
68
+ const decomposeMatrix4 = m => {
69
+ const position = new three.Vector3();
70
+ const rotation = new three.Quaternion();
71
+ const scale = new three.Vector3();
72
+ m.decompose(position, rotation, scale);
73
+ return {
74
+ position,
75
+ rotation,
76
+ scale
77
+ };
78
+ };
48
79
  const scaleColliderArgs = (shape, args, scale) => {
49
80
  // Heightfield only scales the last arg
50
81
  const newArgs = args.slice();
@@ -63,11 +94,13 @@ const scaleColliderArgs = (shape, args, scale) => {
63
94
  const scaleArray = [scale.x, scale.y, scale.z];
64
95
  return newArgs.map((arg, index) => scaleArray[index] * arg);
65
96
  };
66
- const createColliderFromOptions = (options, world, rigidBody, scale = {
67
- x: 1,
68
- y: 1,
69
- z: 1
70
- }, hasCollisionEvents = false) => {
97
+ const createColliderFromOptions = ({
98
+ options,
99
+ world,
100
+ rigidBody,
101
+ scale,
102
+ hasCollisionEvents
103
+ }) => {
71
104
  var _options$shape, _options$args, _options$restitution, _options$restitutionC, _options$friction, _options$frictionComb;
72
105
 
73
106
  const mass = (options === null || options === void 0 ? void 0 : options.mass) || 1;
@@ -76,15 +109,16 @@ const createColliderFromOptions = (options, world, rigidBody, scale = {
76
109
  const [cmx, cmy, cmz] = (options === null || options === void 0 ? void 0 : options.centerOfMass) || [0, 0, 0];
77
110
  const [pix, piy, piz] = (options === null || options === void 0 ? void 0 : options.principalAngularInertia) || [mass * 0.2, mass * 0.2, mass * 0.2];
78
111
  const [x, y, z] = (options === null || options === void 0 ? void 0 : options.position) || [0, 0, 0];
79
- const [rx, ry, rz] = (options === null || options === void 0 ? void 0 : options.rotation) || [0, 0, 0]; // @ts-ignore
112
+ const [rx, ry, rz] = (options === null || options === void 0 ? void 0 : options.rotation) || [0, 0, 0];
113
+ const qRotation = vector3ToQuaternion(new three.Vector3(rx, ry, rz)); // @ts-ignore
80
114
 
81
115
  const scaledArgs = scaleColliderArgs(options.shape, colliderArgs, scale);
82
116
  let colliderDesc = rapier3dCompat.ColliderDesc[colliderShape]( // @ts-ignore
83
117
  ...scaledArgs).setTranslation(x * scale.x, y * scale.y, z * scale.z).setRotation({
84
- x: rx,
85
- y: ry,
86
- z: rz,
87
- w: 1
118
+ x: qRotation.x,
119
+ y: qRotation.y,
120
+ z: qRotation.z,
121
+ w: qRotation.w
88
122
  }).setRestitution((_options$restitution = options === null || options === void 0 ? void 0 : options.restitution) !== null && _options$restitution !== void 0 ? _options$restitution : 0).setRestitutionCombineRule((_options$restitutionC = options === null || options === void 0 ? void 0 : options.restitutionCombineRule) !== null && _options$restitutionC !== void 0 ? _options$restitutionC : rapier3dCompat.CoefficientCombineRule.Average).setFriction((_options$friction = options === null || options === void 0 ? void 0 : options.friction) !== null && _options$friction !== void 0 ? _options$friction : 0.7).setFrictionCombineRule((_options$frictionComb = options === null || options === void 0 ? void 0 : options.frictionCombineRule) !== null && _options$frictionComb !== void 0 ? _options$frictionComb : rapier3dCompat.CoefficientCombineRule.Average);
89
123
 
90
124
  if (hasCollisionEvents) {
@@ -92,6 +126,8 @@ const createColliderFromOptions = (options, world, rigidBody, scale = {
92
126
  } // If any of the mass properties are specified, add mass properties
93
127
 
94
128
 
129
+ const qMassRot = vector3ToQuaternion(new three.Vector3(0, 0, 0));
130
+
95
131
  if (options !== null && options !== void 0 && options.mass || options !== null && options !== void 0 && options.centerOfMass || options !== null && options !== void 0 && options.principalAngularInertia) {
96
132
  colliderDesc.setDensity(0);
97
133
  colliderDesc.setMassProperties(mass, {
@@ -103,10 +139,10 @@ const createColliderFromOptions = (options, world, rigidBody, scale = {
103
139
  y: piy,
104
140
  z: piz
105
141
  }, {
106
- x: 0,
107
- y: 0,
108
- z: 0,
109
- w: 1
142
+ x: qMassRot.x,
143
+ y: qMassRot.y,
144
+ z: qMassRot.z,
145
+ w: qMassRot.w
110
146
  });
111
147
  }
112
148
 
@@ -125,8 +161,7 @@ const isChildOfMeshCollider = child => {
125
161
  const createCollidersFromChildren = (object, rigidBody, options, world, ignoreMeshColliders = true) => {
126
162
  const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
127
163
  const colliders = [];
128
- let desc;
129
- let offset = new three.Vector3();
164
+ new three.Vector3();
130
165
  object.traverse(child => {
131
166
  if ("isMesh" in child) {
132
167
  if (ignoreMeshColliders && isChildOfMeshCollider(child)) return;
@@ -144,62 +179,32 @@ const createCollidersFromChildren = (object, rigidBody, options, world, ignoreMe
144
179
  z: rz,
145
180
  w: rw
146
181
  } = new three.Quaternion().setFromEuler(child.rotation);
147
- const scale = child.getWorldScale(new three.Vector3());
148
-
149
- switch (options.colliders) {
150
- case "cuboid":
151
- {
152
- geometry.computeBoundingBox();
153
- const {
154
- boundingBox
155
- } = geometry;
156
- const size = boundingBox.getSize(new three.Vector3());
157
- boundingBox.getCenter(offset);
158
- desc = rapier3dCompat.ColliderDesc.cuboid(size.x / 2 * scale.x, size.y / 2 * scale.y, size.z / 2 * scale.z);
159
- }
160
- break;
182
+ const scale = child.getWorldScale(new three.Vector3()); // We translate the colliders based on the parent's world scale
161
183
 
162
- case "ball":
163
- {
164
- geometry.computeBoundingSphere();
165
- const {
166
- boundingSphere
167
- } = geometry;
168
- const radius = boundingSphere.radius * scale.x;
169
- offset.copy(boundingSphere.center);
170
- desc = rapier3dCompat.ColliderDesc.ball(radius);
171
- }
172
- break;
173
-
174
- case "trimesh":
175
- {
176
- var _g$index;
184
+ const parentWorldScale = child.parent.getWorldScale(new three.Vector3());
185
+ const desc = colliderDescFromGeometry(geometry, options.colliders, scale, hasCollisionEvents);
186
+ const offset = new three.Vector3(0, 0, 0);
177
187
 
178
- const _g = geometry.clone().scale(scale.x, scale.y, scale.z);
188
+ if (options.colliders === "cuboid") {
189
+ var _geometry$boundingBox;
179
190
 
180
- desc = rapier3dCompat.ColliderDesc.trimesh(_g.attributes.position.array, (_g$index = _g.index) === null || _g$index === void 0 ? void 0 : _g$index.array);
181
- }
182
- break;
183
-
184
- case "hull":
185
- const g = geometry.clone().scale(scale.x, scale.y, scale.z);
186
- {
187
- desc = rapier3dCompat.ColliderDesc.convexHull(g.attributes.position.array);
188
- }
189
- break;
190
- } // We translate the colliders based on the parent's world scale
191
+ geometry.computeBoundingBox();
192
+ (_geometry$boundingBox = geometry.boundingBox) === null || _geometry$boundingBox === void 0 ? void 0 : _geometry$boundingBox.getCenter(offset);
193
+ }
191
194
 
195
+ if (options.colliders === "ball") {
196
+ geometry.computeBoundingSphere();
197
+ offset.copy(geometry.boundingSphere.center);
198
+ }
192
199
 
193
- const parentWorldScale = child.parent.getWorldScale(new three.Vector3());
200
+ if (Number.isFinite(options.friction)) desc.setFriction(options.friction);
201
+ if (Number.isFinite(options.restitution)) desc.setRestitution(options.restitution);
194
202
  desc.setTranslation((x + offset.x) * parentWorldScale.x, (y + offset.y) * parentWorldScale.y, (z + offset.z) * parentWorldScale.z).setRotation({
195
203
  x: rx,
196
204
  y: ry,
197
205
  z: rz,
198
206
  w: rw
199
207
  });
200
- if (hasCollisionEvents) desc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
201
- if (Number.isFinite(options.friction)) desc.setFriction(options.friction);
202
- if (Number.isFinite(options.restitution)) desc.setRestitution(options.restitution);
203
208
  const actualRigidBody = world.getRigidBody(rigidBody === null || rigidBody === void 0 ? void 0 : rigidBody.handle);
204
209
  const collider = world.createCollider(desc, actualRigidBody);
205
210
  colliders.push(collider);
@@ -207,6 +212,53 @@ const createCollidersFromChildren = (object, rigidBody, options, world, ignoreMe
207
212
  });
208
213
  return colliders;
209
214
  };
215
+ const colliderDescFromGeometry = (geometry, colliders, scale, hasCollisionEvents) => {
216
+ let desc;
217
+
218
+ switch (colliders) {
219
+ case "cuboid":
220
+ {
221
+ geometry.computeBoundingBox();
222
+ const {
223
+ boundingBox
224
+ } = geometry;
225
+ const size = boundingBox.getSize(new three.Vector3());
226
+ desc = rapier3dCompat.ColliderDesc.cuboid(size.x / 2 * scale.x, size.y / 2 * scale.y, size.z / 2 * scale.z);
227
+ }
228
+ break;
229
+
230
+ case "ball":
231
+ {
232
+ geometry.computeBoundingSphere();
233
+ const {
234
+ boundingSphere
235
+ } = geometry;
236
+ const radius = boundingSphere.radius * scale.x;
237
+ desc = rapier3dCompat.ColliderDesc.ball(radius);
238
+ }
239
+ break;
240
+
241
+ case "trimesh":
242
+ {
243
+ var _g$index;
244
+
245
+ const _g = geometry.clone().scale(scale.x, scale.y, scale.z);
246
+
247
+ desc = rapier3dCompat.ColliderDesc.trimesh(_g.attributes.position.array, (_g$index = _g.index) === null || _g$index === void 0 ? void 0 : _g$index.array);
248
+ }
249
+ break;
250
+
251
+ case "hull":
252
+ const g = geometry.clone().scale(scale.x, scale.y, scale.z);
253
+ {
254
+ desc = rapier3dCompat.ColliderDesc.convexHull(g.attributes.position.array);
255
+ }
256
+ break;
257
+ }
258
+
259
+ if (hasCollisionEvents) desc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
260
+ return desc;
261
+ };
210
262
  const scaleVertices = (vertices, scale) => {
211
263
  const scaledVerts = Array.from(vertices);
212
264
 
@@ -218,10 +270,25 @@ const scaleVertices = (vertices, scale) => {
218
270
 
219
271
  return scaledVerts;
220
272
  };
221
- const quaternion = new three.Quaternion();
222
- const euler = new three.Euler();
223
- const vector3ToQuaternion = v => {
224
- return quaternion.setFromEuler(euler.setFromVector3(v));
273
+ const rigidBodyDescFromOptions = options => {
274
+ var _options$linearVeloci, _options$angularVeloc, _options$gravityScale, _options$canSleep, _options$ccd, _options$enabledRotat, _options$enabledTrans;
275
+
276
+ const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
277
+ 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];
278
+ 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];
279
+ const gravityScale = (_options$gravityScale = options === null || options === void 0 ? void 0 : options.gravityScale) !== null && _options$gravityScale !== void 0 ? _options$gravityScale : 1;
280
+ const canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
281
+ const ccdEnabled = (_options$ccd = options === null || options === void 0 ? void 0 : options.ccd) !== null && _options$ccd !== void 0 ? _options$ccd : false;
282
+ 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];
283
+ 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];
284
+ const desc = new rapier3dCompat.RigidBodyDesc(type).setLinvel(lvx, lvy, lvz).setAngvel({
285
+ x: avx,
286
+ y: avy,
287
+ z: avz
288
+ }).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled).enabledRotations(erx, ery, erz).enabledTranslations(etx, ety, etz);
289
+ if (options.lockRotations) desc.lockRotations();
290
+ if (options.lockTranslations) desc.lockTranslations();
291
+ return desc;
225
292
  };
226
293
 
227
294
  const createRigidBodyApi = ref => {
@@ -324,18 +391,19 @@ const createRigidBodyApi = ref => {
324
391
  setEnabledRotations: (x, y, z) => ref.current().setEnabledRotations(x, y, z, true),
325
392
  setEnabledTranslations: (x, y, z) => ref.current().setEnabledTranslations(x, y, z, true)
326
393
  };
327
- }; // TODO: Flesh this out
394
+ };
395
+ const createInstancedRigidBodiesApi = bodiesGetter => ({
396
+ at: index => bodiesGetter.current()[index].api,
328
397
 
329
- const createColliderApi = ref => {
330
- return {
331
- raw: () => ref.current(),
398
+ forEach(callback) {
399
+ return bodiesGetter.current().map(b => b.api).forEach(callback);
400
+ },
332
401
 
333
- get handle() {
334
- return ref.current().handle;
335
- }
402
+ get count() {
403
+ return bodiesGetter.current().length;
404
+ }
336
405
 
337
- };
338
- };
406
+ }); // TODO: Flesh this out
339
407
  const createWorldApi = ref => {
340
408
  return {
341
409
  raw: () => ref.current(),
@@ -382,10 +450,10 @@ const importRapier = async () => {
382
450
  };
383
451
 
384
452
  const Physics = ({
385
- colliders: _colliders = 'cuboid',
453
+ colliders: _colliders = "cuboid",
386
454
  gravity: _gravity = [0, -9.81, 0],
387
455
  children,
388
- timeStep: _timeStep = 'vary'
456
+ timeStep: _timeStep = "vary"
389
457
  }) => {
390
458
  const rapier = useAsset.useAsset(importRapier);
391
459
  const worldRef = React.useRef();
@@ -398,7 +466,7 @@ const Physics = ({
398
466
  return worldRef.current;
399
467
  });
400
468
  const [colliderMeshes] = React.useState(() => new Map());
401
- const [rigidBodyMeshes] = React.useState(() => new Map());
469
+ const [rigidBodyStates] = React.useState(() => new Map());
402
470
  const [rigidBodyEvents] = React.useState(() => new Map());
403
471
  const [eventQueue] = React.useState(() => new rapier3dCompat.EventQueue(false)); // Init world
404
472
 
@@ -428,7 +496,7 @@ const Physics = ({
428
496
  const now = performance.now();
429
497
  const delta = Math.min(100, now - time.current);
430
498
 
431
- if (_timeStep === 'vary') {
499
+ if (_timeStep === "vary") {
432
500
  world.timestep = delta / 1000;
433
501
  } else {
434
502
  world.timestep = _timeStep;
@@ -436,52 +504,35 @@ const Physics = ({
436
504
 
437
505
  world.step(eventQueue); // Update meshes
438
506
 
439
- rigidBodyMeshes.forEach((mesh, handle) => {
507
+ rigidBodyStates.forEach((state, handle) => {
440
508
  const rigidBody = world.getRigidBody(handle);
441
509
  const events = rigidBodyEvents.get(handle);
442
510
 
443
511
  if (events !== null && events !== void 0 && events.onSleep || events !== null && events !== void 0 && events.onWake) {
444
- if (rigidBody.isSleeping() && !mesh.userData.isSleeping) {
512
+ if (rigidBody.isSleeping() && !state.isSleeping) {
445
513
  var _events$onSleep;
446
514
 
447
515
  events === null || events === void 0 ? void 0 : (_events$onSleep = events.onSleep) === null || _events$onSleep === void 0 ? void 0 : _events$onSleep.call(events);
448
516
  }
449
517
 
450
- if (!rigidBody.isSleeping() && mesh.userData.isSleeping) {
518
+ if (!rigidBody.isSleeping() && state.isSleeping) {
451
519
  var _events$onWake;
452
520
 
453
521
  events === null || events === void 0 ? void 0 : (_events$onWake = events.onWake) === null || _events$onWake === void 0 ? void 0 : _events$onWake.call(events);
454
522
  }
455
523
 
456
- mesh.userData.isSleeping = rigidBody.isSleeping();
524
+ state.isSleeping = rigidBody.isSleeping();
457
525
  }
458
526
 
459
- if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !mesh.parent) {
527
+ if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !state.setMatrix) {
460
528
  return;
461
529
  }
462
530
 
463
- const {
464
- x,
465
- y,
466
- z
467
- } = rigidBody.translation();
468
- const {
469
- x: rx,
470
- y: ry,
471
- z: rz,
472
- w: rw
473
- } = rigidBody.rotation();
474
- const scale = mesh.getWorldScale(new three.Vector3()); // haha matrixes I have no idea what I'm doing :)
475
-
476
- const o = new three.Object3D();
477
- o.position.set(x, y, z);
478
- o.rotation.setFromQuaternion(new three.Quaternion(rx, ry, rz, rw));
479
- o.scale.set(scale.x, scale.y, scale.z);
480
- o.updateMatrix();
481
- o.applyMatrix4(mesh.parent.matrixWorld.clone().invert());
482
- o.updateMatrix();
483
- mesh.position.setFromMatrixPosition(o.matrix);
484
- mesh.rotation.setFromRotationMatrix(o.matrix);
531
+ state.setMatrix(_matrix4.compose(rapierVector3ToVector3(rigidBody.translation()), rapierQuaternionToQuaternion(rigidBody.rotation()), state.worldScale).premultiply(state.invertedMatrixWorld));
532
+
533
+ if (state.mesh instanceof three.InstancedMesh) {
534
+ state.mesh.instanceMatrix.needsUpdate = true;
535
+ }
485
536
  }); // Collision events
486
537
 
487
538
  eventQueue.drainCollisionEvents((handle1, handle2, started) => {
@@ -538,7 +589,7 @@ const Physics = ({
538
589
  gravity: _gravity
539
590
  },
540
591
  colliderMeshes,
541
- rigidBodyMeshes,
592
+ rigidBodyStates,
542
593
  rigidBodyEvents
543
594
  }), []);
544
595
  return /*#__PURE__*/React__default["default"].createElement(RapierContext.Provider, {
@@ -546,6 +597,40 @@ const Physics = ({
546
597
  }, children);
547
598
  };
548
599
 
600
+ function _objectWithoutPropertiesLoose(source, excluded) {
601
+ if (source == null) return {};
602
+ var target = {};
603
+ var sourceKeys = Object.keys(source);
604
+ var key, i;
605
+
606
+ for (i = 0; i < sourceKeys.length; i++) {
607
+ key = sourceKeys[i];
608
+ if (excluded.indexOf(key) >= 0) continue;
609
+ target[key] = source[key];
610
+ }
611
+
612
+ return target;
613
+ }
614
+
615
+ function _objectWithoutProperties(source, excluded) {
616
+ if (source == null) return {};
617
+ var target = _objectWithoutPropertiesLoose(source, excluded);
618
+ var key, i;
619
+
620
+ if (Object.getOwnPropertySymbols) {
621
+ var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
622
+
623
+ for (i = 0; i < sourceSymbolKeys.length; i++) {
624
+ key = sourceSymbolKeys[i];
625
+ if (excluded.indexOf(key) >= 0) continue;
626
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
627
+ target[key] = source[key];
628
+ }
629
+ }
630
+
631
+ return target;
632
+ }
633
+
549
634
  function _defineProperty(obj, key, value) {
550
635
  if (key in obj) {
551
636
  Object.defineProperty(obj, key, {
@@ -592,9 +677,8 @@ const useRapier = () => {
592
677
  };
593
678
  const useRigidBody = (options = {}) => {
594
679
  const {
595
- rapier,
596
680
  world,
597
- rigidBodyMeshes,
681
+ rigidBodyStates,
598
682
  physicsOptions,
599
683
  rigidBodyEvents
600
684
  } = useRapier();
@@ -603,23 +687,7 @@ const useRigidBody = (options = {}) => {
603
687
  const rigidBodyRef = React.useRef();
604
688
  const getRigidBodyRef = React.useRef(() => {
605
689
  if (!rigidBodyRef.current) {
606
- var _options$linearVeloci, _options$angularVeloc, _options$gravityScale, _options$canSleep, _options$ccd, _options$enabledRotat, _options$enabledTrans;
607
-
608
- const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
609
- 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];
610
- 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];
611
- const gravityScale = (_options$gravityScale = options === null || options === void 0 ? void 0 : options.gravityScale) !== null && _options$gravityScale !== void 0 ? _options$gravityScale : 1;
612
- const canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
613
- const ccdEnabled = (_options$ccd = options === null || options === void 0 ? void 0 : options.ccd) !== null && _options$ccd !== void 0 ? _options$ccd : false;
614
- 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];
615
- 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];
616
- const desc = new rapier.RigidBodyDesc(type).setLinvel(lvx, lvy, lvz).setAngvel({
617
- x: avx,
618
- y: avy,
619
- z: avz
620
- }).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled).enabledRotations(erx, ery, erz).enabledTranslations(etx, ety, etz);
621
- if (options.lockRotations) desc.lockRotations();
622
- if (options.lockTranslations) desc.lockTranslations();
690
+ const desc = rigidBodyDescFromOptions(options);
623
691
  const rigidBody = world.createRigidBody(desc);
624
692
  rigidBodyRef.current = world.getRigidBody(rigidBody.handle);
625
693
  }
@@ -656,8 +724,7 @@ const useRigidBody = (options = {}) => {
656
724
  y: worldPosition.y + y * scale.y,
657
725
  z: worldPosition.z + z * scale.z
658
726
  }, false);
659
- const eulerAngles = new three.Euler(rx, ry, rz, 'XYZ');
660
- const rotation = new three.Quaternion().setFromEuler(eulerAngles).multiply(worldRotation);
727
+ const rotation = vector3ToQuaternion(new three.Vector3(rx, ry, rz)).multiply(worldRotation);
661
728
  rigidBody.setRotation({
662
729
  x: rotation.x,
663
730
  y: rotation.y,
@@ -670,12 +737,19 @@ const useRigidBody = (options = {}) => {
670
737
  const autoColliders = colliderSetting !== false ? createCollidersFromChildren(ref.current, rigidBody, _objectSpread2(_objectSpread2({}, options), {}, {
671
738
  colliders: colliderSetting
672
739
  }), world) : [];
673
- rigidBodyMeshes.set(rigidBody.handle, ref.current);
740
+ rigidBodyStates.set(rigidBody.handle, {
741
+ mesh: ref.current,
742
+ invertedMatrixWorld: ref.current.parent.matrixWorld.clone().invert(),
743
+ isSleeping: false,
744
+ worldScale: ref.current.getWorldScale(_vector3).clone(),
745
+ setMatrix: mat => ref.current.matrix.copy(mat)
746
+ });
747
+ ref.current.matrixAutoUpdate = false;
674
748
  return () => {
675
749
  world.removeRigidBody(rigidBody);
676
750
  autoColliders.forEach(collider => world.removeCollider(collider));
677
751
  rigidBodyRef.current = undefined;
678
- rigidBodyMeshes.delete(rigidBody.handle);
752
+ rigidBodyStates.delete(rigidBody.handle);
679
753
  };
680
754
  }, []); // Events
681
755
 
@@ -693,29 +767,6 @@ const useRigidBody = (options = {}) => {
693
767
  }, [options.onCollisionEnter, options.onCollisionExit]);
694
768
  const api = React.useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
695
769
  return [ref, api];
696
- };
697
- const useCollider = (body, options = {}) => {
698
- const {
699
- world
700
- } = useRapier();
701
- const colliderRef = React.useRef();
702
- const objectRef = React.useRef();
703
- const getColliderRef = React.useRef(() => {
704
- if (!colliderRef.current) {
705
- colliderRef.current = createColliderFromOptions(options, world, world.getRigidBody(body.handle));
706
- }
707
-
708
- return colliderRef.current;
709
- });
710
- React.useEffect(() => {
711
- const collider = getColliderRef.current();
712
- return () => {
713
- if (collider) world.removeCollider(collider);
714
- colliderRef.current = undefined;
715
- };
716
- }, []);
717
- const api = React.useMemo(() => createColliderApi(getColliderRef), []);
718
- return [objectRef, api];
719
770
  }; // Joints
720
771
 
721
772
  const useImpulseJoint = (body1, body2, params) => {
@@ -728,7 +779,7 @@ const useImpulseJoint = (body1, body2, params) => {
728
779
  let rb1;
729
780
  let rb2;
730
781
 
731
- if ('current' in body1 && body1.current && 'current' in body2 && body2.current) {
782
+ if ("current" in body1 && body1.current && "current" in body2 && body2.current) {
732
783
  rb1 = world.getRigidBody(body1.current.handle);
733
784
  rb2 = world.getRigidBody(body2.current.handle);
734
785
  const newJoint = world.createImpulseJoint(params, rb1, rb2);
@@ -805,79 +856,30 @@ const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
805
856
  return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor), vectorArrayToObject(axis)));
806
857
  };
807
858
 
808
- function _extends() {
809
- _extends = Object.assign || function (target) {
810
- for (var i = 1; i < arguments.length; i++) {
811
- var source = arguments[i];
812
-
813
- for (var key in source) {
814
- if (Object.prototype.hasOwnProperty.call(source, key)) {
815
- target[key] = source[key];
816
- }
817
- }
818
- }
819
-
820
- return target;
821
- };
822
-
823
- return _extends.apply(this, arguments);
824
- }
825
-
826
- function _objectWithoutPropertiesLoose(source, excluded) {
827
- if (source == null) return {};
828
- var target = {};
829
- var sourceKeys = Object.keys(source);
830
- var key, i;
831
-
832
- for (i = 0; i < sourceKeys.length; i++) {
833
- key = sourceKeys[i];
834
- if (excluded.indexOf(key) >= 0) continue;
835
- target[key] = source[key];
836
- }
837
-
838
- return target;
839
- }
840
-
841
- function _objectWithoutProperties(source, excluded) {
842
- if (source == null) return {};
843
- var target = _objectWithoutPropertiesLoose(source, excluded);
844
- var key, i;
845
-
846
- if (Object.getOwnPropertySymbols) {
847
- var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
848
-
849
- for (i = 0; i < sourceSymbolKeys.length; i++) {
850
- key = sourceSymbolKeys[i];
851
- if (excluded.indexOf(key) >= 0) continue;
852
- if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
853
- target[key] = source[key];
854
- }
855
- }
856
-
857
- return target;
858
- }
859
-
860
- const _excluded = ["children"],
861
- _excluded2 = ["children"];
859
+ const _excluded$1 = ["children"];
862
860
  const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
863
-
864
861
  const useRigidBodyContext = () => React.useContext(RigidBodyContext); // RigidBody
865
862
 
866
-
867
863
  const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
868
864
  let {
869
865
  children
870
866
  } = _ref,
871
- props = _objectWithoutProperties(_ref, _excluded);
867
+ props = _objectWithoutProperties(_ref, _excluded$1);
872
868
 
873
- const [object, rigidBody] = useRigidBody(props);
874
- React.useImperativeHandle(ref, () => rigidBody);
869
+ const [object, api] = useRigidBody(props);
870
+ React.useImperativeHandle(ref, () => api);
875
871
  return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
876
- value: [object, rigidBody, !!(props.onCollisionEnter || props.onCollisionExit), props]
872
+ value: {
873
+ ref: object,
874
+ api,
875
+ hasCollisionEvents: !!(props.onCollisionEnter || props.onCollisionExit),
876
+ options: props
877
+ }
877
878
  }, /*#__PURE__*/React__default["default"].createElement("object3D", {
878
879
  ref: object
879
880
  }, children));
880
881
  });
882
+
881
883
  const MeshCollider = ({
882
884
  children,
883
885
  type
@@ -887,15 +889,18 @@ const MeshCollider = ({
887
889
  world
888
890
  } = useRapier();
889
891
  const object = React.useRef(null);
890
- const [, rigidBody, hasCollisionEvents, rigidBodyOptions] = useRigidBodyContext();
892
+ const {
893
+ api,
894
+ options
895
+ } = useRigidBodyContext();
891
896
  React.useEffect(() => {
892
897
  let autoColliders = [];
893
898
 
894
899
  if (object.current) {
895
- var _ref2;
900
+ var _ref;
896
901
 
897
- const colliderSetting = (_ref2 = type !== null && type !== void 0 ? type : physicsOptions.colliders) !== null && _ref2 !== void 0 ? _ref2 : false;
898
- autoColliders = colliderSetting !== false ? createCollidersFromChildren(object.current, rigidBody, _objectSpread2(_objectSpread2({}, rigidBodyOptions), {}, {
902
+ const colliderSetting = (_ref = type !== null && type !== void 0 ? type : physicsOptions.colliders) !== null && _ref !== void 0 ? _ref : false;
903
+ autoColliders = colliderSetting !== false ? createCollidersFromChildren(object.current, api, _objectSpread2(_objectSpread2({}, options), {}, {
899
904
  colliders: colliderSetting
900
905
  }), world, false) : [];
901
906
  }
@@ -909,78 +914,9 @@ const MeshCollider = ({
909
914
  return /*#__PURE__*/React__default["default"].createElement("object3D", {
910
915
  ref: object,
911
916
  userData: {
912
- r3RapierType: 'MeshCollider'
917
+ r3RapierType: "MeshCollider"
913
918
  }
914
919
  }, children);
915
- }; // Colliders
916
-
917
- const AnyCollider = _ref3 => {
918
- let {
919
- children
920
- } = _ref3,
921
- props = _objectWithoutProperties(_ref3, _excluded2);
922
-
923
- const {
924
- world
925
- } = useRapier();
926
- const [, rigidBody, hasCollisionEvents] = useRigidBodyContext();
927
- const ref = React.useRef(null);
928
- React.useEffect(() => {
929
- const scale = ref.current.getWorldScale(new three.Vector3());
930
- const collider = createColliderFromOptions(props, world, rigidBody.raw(), scale, hasCollisionEvents);
931
- return () => {
932
- world.removeCollider(collider);
933
- };
934
- }, []);
935
- return /*#__PURE__*/React__default["default"].createElement("object3D", {
936
- ref: ref
937
- }, children);
938
- };
939
-
940
- const CuboidCollider = props => {
941
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
942
- shape: "cuboid"
943
- }));
944
- };
945
- const RoundCuboidCollider = props => {
946
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
947
- shape: "roundCuboid"
948
- }));
949
- };
950
- const BallCollider = props => {
951
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
952
- shape: "ball"
953
- }));
954
- };
955
- const CapsuleCollider = props => {
956
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
957
- shape: "capsule"
958
- }));
959
- };
960
- const HeightfieldCollider = props => {
961
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
962
- shape: "heightfield"
963
- }));
964
- };
965
- const TrimeshCollider = props => {
966
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
967
- shape: "trimesh"
968
- }));
969
- };
970
- const ConeCollider = props => {
971
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
972
- shape: "cone"
973
- }));
974
- };
975
- const CylinderCollider = props => {
976
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
977
- shape: "cylinder"
978
- }));
979
- };
980
- const ConvexHullCollider = props => {
981
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
982
- shape: "convexHull"
983
- }));
984
920
  };
985
921
 
986
922
  const geometryFromCollider = collider => {
@@ -1098,6 +1034,200 @@ const Debug = () => {
1098
1034
  })));
1099
1035
  };
1100
1036
 
1037
+ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
1038
+ const {
1039
+ world,
1040
+ rigidBodyStates,
1041
+ physicsOptions
1042
+ } = useRapier();
1043
+ const object = React.useRef(null);
1044
+ const instancesRef = React.useRef();
1045
+ const instancesRefGetter = React.useRef(() => {
1046
+ if (!instancesRef.current) {
1047
+ instancesRef.current = [];
1048
+ }
1049
+
1050
+ return instancesRef.current;
1051
+ });
1052
+ React.useEffect(() => {
1053
+ const colliders = [];
1054
+ const rigidBodies = instancesRefGetter.current();
1055
+
1056
+ if (object.current) {
1057
+ const scale = object.current.getWorldScale(new three.Vector3());
1058
+ let hasOneMesh = false;
1059
+ object.current.traverse(mesh => {
1060
+ if (mesh instanceof three.InstancedMesh) {
1061
+ if (hasOneMesh) {
1062
+ console.warn("Can only use a single InstancedMesh inside <InstancedRigidBodies />, more InstancedMeshes will be ignored.");
1063
+ return;
1064
+ }
1065
+
1066
+ hasOneMesh = true;
1067
+ mesh.instanceMatrix.setUsage(three.DynamicDrawUsage);
1068
+ const rigidBodyDesc = rigidBodyDescFromOptions(props);
1069
+ const colliderDesc = colliderDescFromGeometry(mesh.geometry, props.colliders || physicsOptions.colliders, scale, false // Collisions currently not enabled for instances
1070
+ );
1071
+
1072
+ for (let index = 0; index < mesh.count; index++) {
1073
+ const rigidBody = world.createRigidBody(rigidBodyDesc);
1074
+ const matrix = new three.Matrix4();
1075
+ mesh.getMatrixAt(index, matrix);
1076
+ const {
1077
+ position,
1078
+ rotation
1079
+ } = decomposeMatrix4(matrix); // Set positions
1080
+
1081
+ if (props.positions && props.positions[index]) {
1082
+ rigidBody.setTranslation(vectorArrayToObject(props.positions[index]), true);
1083
+ } else {
1084
+ rigidBody.setTranslation(position, true);
1085
+ } // Set rotations
1086
+
1087
+
1088
+ if (props.rotations && props.rotations[index]) {
1089
+ const [x, y, z] = props.rotations[index];
1090
+ rigidBody.setRotation(vector3ToQuaternion(new three.Vector3(x, y, z)), true);
1091
+ } else {
1092
+ rigidBody.setRotation(rotation, true);
1093
+ }
1094
+
1095
+ const collider = world.createCollider(colliderDesc, rigidBody);
1096
+ rigidBodyStates.set(rigidBody.handle, {
1097
+ mesh: mesh,
1098
+ isSleeping: false,
1099
+ invertedMatrixWorld: object.current.matrixWorld.clone().invert(),
1100
+ setMatrix: matrix => mesh.setMatrixAt(index, matrix),
1101
+ worldScale: object.current.getWorldScale(new three.Vector3())
1102
+ });
1103
+ const api = createRigidBodyApi({
1104
+ current() {
1105
+ return rigidBody;
1106
+ }
1107
+
1108
+ });
1109
+ colliders.push(collider);
1110
+ rigidBodies.push({
1111
+ rigidBody,
1112
+ api
1113
+ });
1114
+ }
1115
+ }
1116
+
1117
+ if (mesh.type === "Mesh" && !("isInstancedMesh" in mesh)) {
1118
+ console.warn("Can only use InstancedMesh inside <InstancedRigidBodies />, Mesh will be ignored.");
1119
+ }
1120
+ });
1121
+ return () => {
1122
+ rigidBodies.forEach(rb => world.removeRigidBody(rb.rigidBody));
1123
+ colliders.forEach(coll => world.removeCollider(coll));
1124
+ instancesRef.current = undefined;
1125
+ };
1126
+ }
1127
+ }, []);
1128
+ React.useImperativeHandle(ref, () => createInstancedRigidBodiesApi(instancesRefGetter));
1129
+ return /*#__PURE__*/React__default["default"].createElement("object3D", {
1130
+ ref: object
1131
+ }, props.children);
1132
+ });
1133
+
1134
+ function _extends() {
1135
+ _extends = Object.assign || function (target) {
1136
+ for (var i = 1; i < arguments.length; i++) {
1137
+ var source = arguments[i];
1138
+
1139
+ for (var key in source) {
1140
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
1141
+ target[key] = source[key];
1142
+ }
1143
+ }
1144
+ }
1145
+
1146
+ return target;
1147
+ };
1148
+
1149
+ return _extends.apply(this, arguments);
1150
+ }
1151
+
1152
+ const _excluded = ["children"];
1153
+
1154
+ const AnyCollider = _ref => {
1155
+ let {
1156
+ children
1157
+ } = _ref,
1158
+ props = _objectWithoutProperties(_ref, _excluded);
1159
+
1160
+ const {
1161
+ world
1162
+ } = useRapier();
1163
+ const rigidBodyContext = useRigidBodyContext();
1164
+ const ref = React.useRef(null);
1165
+ React.useEffect(() => {
1166
+ var _rigidBodyContext$api;
1167
+
1168
+ const scale = ref.current.getWorldScale(new three.Vector3());
1169
+ const collider = createColliderFromOptions({
1170
+ options: props,
1171
+ world,
1172
+ rigidBody: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : (_rigidBodyContext$api = rigidBodyContext.api) === null || _rigidBodyContext$api === void 0 ? void 0 : _rigidBodyContext$api.raw(),
1173
+ scale,
1174
+ hasCollisionEvents: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.hasCollisionEvents
1175
+ });
1176
+ return () => {
1177
+ world.removeCollider(collider);
1178
+ };
1179
+ }, []);
1180
+ return /*#__PURE__*/React__default["default"].createElement("object3D", {
1181
+ ref: ref
1182
+ }, children);
1183
+ };
1184
+
1185
+ const CuboidCollider = props => {
1186
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1187
+ shape: "cuboid"
1188
+ }));
1189
+ };
1190
+ const RoundCuboidCollider = props => {
1191
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1192
+ shape: "roundCuboid"
1193
+ }));
1194
+ };
1195
+ const BallCollider = props => {
1196
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1197
+ shape: "ball"
1198
+ }));
1199
+ };
1200
+ const CapsuleCollider = props => {
1201
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1202
+ shape: "capsule"
1203
+ }));
1204
+ };
1205
+ const HeightfieldCollider = props => {
1206
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1207
+ shape: "heightfield"
1208
+ }));
1209
+ };
1210
+ const TrimeshCollider = props => {
1211
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1212
+ shape: "trimesh"
1213
+ }));
1214
+ };
1215
+ const ConeCollider = props => {
1216
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1217
+ shape: "cone"
1218
+ }));
1219
+ };
1220
+ const CylinderCollider = props => {
1221
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1222
+ shape: "cylinder"
1223
+ }));
1224
+ };
1225
+ const ConvexHullCollider = props => {
1226
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1227
+ shape: "convexHull"
1228
+ }));
1229
+ };
1230
+
1101
1231
  Object.defineProperty(exports, 'CoefficientCombineRule', {
1102
1232
  enumerable: true,
1103
1233
  get: function () { return rapier3dCompat.CoefficientCombineRule; }
@@ -1118,12 +1248,12 @@ exports.CuboidCollider = CuboidCollider;
1118
1248
  exports.CylinderCollider = CylinderCollider;
1119
1249
  exports.Debug = Debug;
1120
1250
  exports.HeightfieldCollider = HeightfieldCollider;
1251
+ exports.InstancedRigidBodies = InstancedRigidBodies;
1121
1252
  exports.MeshCollider = MeshCollider;
1122
1253
  exports.Physics = Physics;
1123
1254
  exports.RigidBody = RigidBody;
1124
1255
  exports.RoundCuboidCollider = RoundCuboidCollider;
1125
1256
  exports.TrimeshCollider = TrimeshCollider;
1126
- exports.useCollider = useCollider;
1127
1257
  exports.useFixedJoint = useFixedJoint;
1128
1258
  exports.useImpulseJoint = useImpulseJoint;
1129
1259
  exports.usePrismaticJoint = usePrismaticJoint;