@react-three/rapier 0.6.9 → 0.7.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.
@@ -7,7 +7,6 @@ var React = require('react');
7
7
  var useAsset = require('use-asset');
8
8
  var fiber = require('@react-three/fiber');
9
9
  var three = require('three');
10
- var BufferGeometryUtils = require('three/examples/jsm/utils/BufferGeometryUtils');
11
10
  var MathUtils = require('three/src/math/MathUtils');
12
11
  var threeStdlib = require('three-stdlib');
13
12
 
@@ -34,18 +33,18 @@ function _interopNamespace(e) {
34
33
  var React__default = /*#__PURE__*/_interopDefault(React);
35
34
 
36
35
  const _quaternion = new three.Quaternion();
37
- const _euler = new three.Euler();
36
+ new three.Euler();
38
37
  const _vector3 = new three.Vector3();
39
- new three.Object3D();
38
+ const _object3d = new three.Object3D();
40
39
  const _matrix4 = new three.Matrix4();
40
+ const _position = new three.Vector3();
41
+ const _rotation = new three.Quaternion();
42
+ const _scale = new three.Vector3();
41
43
 
42
44
  const vectorArrayToVector3 = arr => {
43
45
  const [x, y, z] = arr;
44
46
  return new three.Vector3(x, y, z);
45
47
  };
46
- const vector3ToQuaternion = v => {
47
- return _quaternion.setFromEuler(_euler.setFromVector3(v));
48
- };
49
48
  const rapierVector3ToVector3 = ({
50
49
  x,
51
50
  y,
@@ -64,216 +63,6 @@ const rigidBodyTypeMap = {
64
63
  kinematicVelocity: 3
65
64
  };
66
65
  const rigidBodyTypeFromString = type => rigidBodyTypeMap[type];
67
- const decomposeMatrix4 = m => {
68
- const position = new three.Vector3();
69
- const rotation = new three.Quaternion();
70
- const scale = new three.Vector3();
71
- m.decompose(position, rotation, scale);
72
- return {
73
- position,
74
- rotation,
75
- scale
76
- };
77
- };
78
- const scaleColliderArgs = (shape, args, scale) => {
79
- const newArgs = args.slice(); // Heightfield uses a vector
80
-
81
- if (shape === "heightfield") {
82
- const s = newArgs[3];
83
- s.x *= scale.x;
84
- s.x *= scale.y;
85
- s.x *= scale.z;
86
- return newArgs;
87
- } // Trimesh and convex scale the vertices
88
-
89
-
90
- if (shape === "trimesh" || shape === "convexHull") {
91
- newArgs[0] = scaleVertices(newArgs[0], scale);
92
- return newArgs;
93
- } // Prepfill with some extra
94
-
95
-
96
- const scaleArray = [scale.x, scale.y, scale.z, scale.x, scale.x];
97
- return newArgs.map((arg, index) => scaleArray[index] * arg);
98
- };
99
-
100
- const applyColliderOptions = (collider, options) => {
101
- if (options.collisionGroups !== undefined) collider.setCollisionGroups(options.collisionGroups);
102
- if (options.solverGroups !== undefined) collider.setSolverGroups(options.solverGroups);
103
- };
104
-
105
- const createColliderFromOptions = ({
106
- options,
107
- world,
108
- rigidBody,
109
- scale,
110
- hasCollisionEvents
111
- }) => {
112
- var _options$shape, _options$args, _options$restitution, _options$restitutionC, _options$friction, _options$frictionComb;
113
-
114
- const mass = (options === null || options === void 0 ? void 0 : options.mass) || 1;
115
- const colliderShape = (_options$shape = options === null || options === void 0 ? void 0 : options.shape) !== null && _options$shape !== void 0 ? _options$shape : "cuboid";
116
- const colliderArgs = (_options$args = options === null || options === void 0 ? void 0 : options.args) !== null && _options$args !== void 0 ? _options$args : [];
117
- const [cmx, cmy, cmz] = (options === null || options === void 0 ? void 0 : options.centerOfMass) || [0, 0, 0];
118
- const [pix, piy, piz] = (options === null || options === void 0 ? void 0 : options.principalAngularInertia) || [mass * 0.2, mass * 0.2, mass * 0.2];
119
- const [x, y, z] = (options === null || options === void 0 ? void 0 : options.position) || [0, 0, 0];
120
- const [rx, ry, rz] = (options === null || options === void 0 ? void 0 : options.rotation) || [0, 0, 0];
121
- const qRotation = vector3ToQuaternion(new three.Vector3(rx, ry, rz)); // @ts-ignore
122
-
123
- const scaledArgs = scaleColliderArgs(options.shape, colliderArgs, scale);
124
- let colliderDesc = rapier3dCompat.ColliderDesc[colliderShape]( // @ts-ignore
125
- ...scaledArgs).setTranslation(x * scale.x, y * scale.y, z * scale.z).setRotation({
126
- x: qRotation.x,
127
- y: qRotation.y,
128
- z: qRotation.z,
129
- w: qRotation.w
130
- }).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);
131
-
132
- if (hasCollisionEvents) {
133
- colliderDesc = colliderDesc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
134
- } // If any of the mass properties are specified, add mass properties
135
-
136
-
137
- const qMassRot = vector3ToQuaternion(new three.Vector3(0, 0, 0));
138
-
139
- if (options !== null && options !== void 0 && options.mass || options !== null && options !== void 0 && options.centerOfMass || options !== null && options !== void 0 && options.principalAngularInertia) {
140
- colliderDesc.setDensity(0);
141
- colliderDesc.setMassProperties(mass, {
142
- x: cmx,
143
- y: cmy,
144
- z: cmz
145
- }, {
146
- x: pix,
147
- y: piy,
148
- z: piz
149
- }, {
150
- x: qMassRot.x,
151
- y: qMassRot.y,
152
- z: qMassRot.z,
153
- w: qMassRot.w
154
- });
155
- }
156
-
157
- const collider = world.createCollider(colliderDesc, rigidBody);
158
- applyColliderOptions(collider, options);
159
- return collider;
160
- };
161
-
162
- const isChildOfMeshCollider = child => {
163
- let flag = false;
164
- child.traverseAncestors(a => {
165
- if (a.userData.r3RapierType === "MeshCollider") flag = true;
166
- });
167
- return flag;
168
- };
169
-
170
- const createCollidersFromChildren = ({
171
- object,
172
- rigidBody,
173
- options,
174
- world,
175
- ignoreMeshColliders: _ignoreMeshColliders = true
176
- }) => {
177
- const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
178
- const colliders = [];
179
- object.traverseVisible(child => {
180
- if ("isMesh" in child) {
181
- if (_ignoreMeshColliders && isChildOfMeshCollider(child)) return;
182
- const {
183
- geometry
184
- } = child;
185
- const {
186
- x,
187
- y,
188
- z
189
- } = child.position;
190
- const {
191
- x: rx,
192
- y: ry,
193
- z: rz,
194
- w: rw
195
- } = new three.Quaternion().setFromEuler(child.rotation);
196
- const scale = child.getWorldScale(new three.Vector3()); // We translate the colliders based on the parent's world scale
197
-
198
- const parentWorldScale = child.parent.getWorldScale(new three.Vector3());
199
- const desc = colliderDescFromGeometry(geometry, options.colliders, scale, hasCollisionEvents);
200
- const offset = new three.Vector3(0, 0, 0);
201
-
202
- if (options.colliders === "cuboid") {
203
- var _geometry$boundingBox;
204
-
205
- geometry.computeBoundingBox();
206
- (_geometry$boundingBox = geometry.boundingBox) === null || _geometry$boundingBox === void 0 ? void 0 : _geometry$boundingBox.getCenter(offset);
207
- }
208
-
209
- if (options.colliders === "ball") {
210
- geometry.computeBoundingSphere();
211
- offset.copy(geometry.boundingSphere.center);
212
- }
213
-
214
- if (Number.isFinite(options.friction)) desc.setFriction(options.friction);
215
- if (Number.isFinite(options.restitution)) desc.setRestitution(options.restitution);
216
- desc.setTranslation((x + offset.x) * parentWorldScale.x, (y + offset.y) * parentWorldScale.y, (z + offset.z) * parentWorldScale.z).setRotation({
217
- x: rx,
218
- y: ry,
219
- z: rz,
220
- w: rw
221
- });
222
- const actualRigidBody = rigidBody ? world.getRigidBody(rigidBody.handle) : undefined;
223
- const collider = world.createCollider(desc, actualRigidBody);
224
- applyColliderOptions(collider, options);
225
- colliders.push(collider);
226
- }
227
- });
228
- return colliders;
229
- };
230
- const colliderDescFromGeometry = (geometry, colliders, scale, hasCollisionEvents) => {
231
- let desc;
232
-
233
- switch (colliders) {
234
- case "cuboid":
235
- {
236
- geometry.computeBoundingBox();
237
- const {
238
- boundingBox
239
- } = geometry;
240
- const size = boundingBox.getSize(new three.Vector3());
241
- desc = rapier3dCompat.ColliderDesc.cuboid(size.x / 2 * scale.x, size.y / 2 * scale.y, size.z / 2 * scale.z);
242
- }
243
- break;
244
-
245
- case "ball":
246
- {
247
- geometry.computeBoundingSphere();
248
- const {
249
- boundingSphere
250
- } = geometry;
251
- const radius = boundingSphere.radius * scale.x;
252
- desc = rapier3dCompat.ColliderDesc.ball(radius);
253
- }
254
- break;
255
-
256
- case "trimesh":
257
- {
258
- var _g$index;
259
-
260
- const clonedGeometry = geometry.index ? geometry.clone() : BufferGeometryUtils.mergeVertices(geometry);
261
- const g = clonedGeometry.scale(scale.x, scale.y, scale.z);
262
- desc = rapier3dCompat.ColliderDesc.trimesh(g.attributes.position.array, (_g$index = g.index) === null || _g$index === void 0 ? void 0 : _g$index.array);
263
- }
264
- break;
265
-
266
- case "hull":
267
- {
268
- const g = geometry.clone().scale(scale.x, scale.y, scale.z);
269
- desc = rapier3dCompat.ColliderDesc.convexHull(g.attributes.position.array);
270
- }
271
- break;
272
- }
273
-
274
- if (hasCollisionEvents) desc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
275
- return desc;
276
- };
277
66
  const scaleVertices = (vertices, scale) => {
278
67
  const scaledVerts = Array.from(vertices);
279
68
 
@@ -285,28 +74,6 @@ const scaleVertices = (vertices, scale) => {
285
74
 
286
75
  return scaledVerts;
287
76
  };
288
- const rigidBodyDescFromOptions = options => {
289
- var _options$linearVeloci, _options$angularVeloc, _options$angularDampi, _options$linearDampin, _options$gravityScale, _options$canSleep, _options$ccd, _options$enabledRotat, _options$enabledTrans;
290
-
291
- const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
292
- 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];
293
- 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];
294
- const angularDamping = (_options$angularDampi = options === null || options === void 0 ? void 0 : options.angularDamping) !== null && _options$angularDampi !== void 0 ? _options$angularDampi : 0;
295
- const linearDamping = (_options$linearDampin = options === null || options === void 0 ? void 0 : options.linearDamping) !== null && _options$linearDampin !== void 0 ? _options$linearDampin : 0;
296
- const gravityScale = (_options$gravityScale = options === null || options === void 0 ? void 0 : options.gravityScale) !== null && _options$gravityScale !== void 0 ? _options$gravityScale : 1;
297
- const canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
298
- const ccdEnabled = (_options$ccd = options === null || options === void 0 ? void 0 : options.ccd) !== null && _options$ccd !== void 0 ? _options$ccd : false;
299
- 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];
300
- 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];
301
- const desc = new rapier3dCompat.RigidBodyDesc(type).setLinvel(lvx, lvy, lvz).setAngvel({
302
- x: avx,
303
- y: avy,
304
- z: avz
305
- }).setLinearDamping(linearDamping).setAngularDamping(angularDamping).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled).enabledRotations(erx, ery, erz).enabledTranslations(etx, ety, etz);
306
- if (options.lockRotations) desc.lockRotations();
307
- if (options.lockTranslations) desc.lockTranslations();
308
- return desc;
309
- };
310
77
 
311
78
  const createRigidBodyApi = ref => {
312
79
  return {
@@ -458,7 +225,6 @@ const Physics = ({
458
225
  gravity: _gravity = [0, -9.81, 0],
459
226
  children,
460
227
  timeStep: _timeStep = 1 / 60,
461
- maxSubSteps: _maxSubSteps = 10,
462
228
  paused: _paused = false,
463
229
  updatePriority
464
230
  }) => {
@@ -477,6 +243,7 @@ const Physics = ({
477
243
  return worldRef.current;
478
244
  });
479
245
  const [rigidBodyStates] = React.useState(() => new Map());
246
+ const [colliderStates] = React.useState(() => new Map());
480
247
  const [rigidBodyEvents] = React.useState(() => new Map());
481
248
  const [colliderEvents] = React.useState(() => new Map());
482
249
  const [eventQueue] = React.useState(() => new rapier3dCompat.EventQueue(false)); // Init world
@@ -498,11 +265,9 @@ const Physics = ({
498
265
  }
499
266
  }, [_gravity]);
500
267
  const [steppingState] = React.useState({
501
- time: 0,
502
- lastTime: 0,
503
268
  accumulator: 0
504
269
  });
505
- fiber.useFrame((_, delta) => {
270
+ fiber.useFrame((_, dt) => {
506
271
  const world = worldRef.current;
507
272
  if (!world) return;
508
273
  world.timestep = _timeStep;
@@ -510,33 +275,19 @@ const Physics = ({
510
275
  * Fixed timeStep simulation progression
511
276
  * @see https://gafferongames.com/post/fix_your_timestep/
512
277
  */
278
+ // don't step time forwards if paused
279
+ // Increase accumulator
513
280
 
514
- let previousTranslations = {}; // don't step time forwards if paused
515
-
516
- const nowTime = steppingState.time += _paused ? 0 : MathUtils.clamp(delta, 0, 1) * 1000;
517
- const timeStepMs = _timeStep * 1000;
518
- const timeSinceLast = nowTime - steppingState.lastTime;
519
- steppingState.lastTime = nowTime;
520
- steppingState.accumulator += timeSinceLast;
281
+ steppingState.accumulator += _paused ? 0 : MathUtils.clamp(dt, 0, 0.2);
521
282
 
522
283
  if (!_paused) {
523
- let subSteps = 0;
524
-
525
- while (steppingState.accumulator >= timeStepMs && subSteps < _maxSubSteps) {
526
- // Collect previous state
527
- world.bodies.forEach(b => {
528
- previousTranslations[b.handle] = {
529
- rotation: rapierQuaternionToQuaternion(b.rotation()).normalize(),
530
- translation: rapierVector3ToVector3(b.translation())
531
- };
532
- });
284
+ while (steppingState.accumulator >= _timeStep) {
533
285
  world.step(eventQueue);
534
- subSteps++;
535
- steppingState.accumulator -= timeStepMs;
286
+ steppingState.accumulator -= _timeStep;
536
287
  }
537
288
  }
538
289
 
539
- const interpolationAlpha = steppingState.accumulator % timeStepMs / timeStepMs; // Update meshes
290
+ const interpolationAlpha = steppingState.accumulator % _timeStep / _timeStep; // Update meshes
540
291
 
541
292
  rigidBodyStates.forEach((state, handle) => {
542
293
  const rigidBody = world.getRigidBody(handle);
@@ -562,86 +313,151 @@ const Physics = ({
562
313
  return;
563
314
  }
564
315
 
565
- let oldState = previousTranslations[rigidBody.handle];
566
- let newTranslation = rigidBody.translation();
567
- let newRotation = rapierQuaternionToQuaternion(rigidBody.rotation());
568
- let interpolatedTranslation = oldState ? oldState.translation.lerp(newTranslation, 1) : newTranslation;
569
- let interpolatedRotation = oldState ? oldState.rotation.slerp(newRotation, interpolationAlpha) : newRotation;
570
- state.setMatrix(_matrix4.compose(interpolatedTranslation, interpolatedRotation, state.worldScale).premultiply(state.invertedMatrixWorld));
316
+ let t = rigidBody.translation();
317
+ let r = rigidBody.rotation(); // Get new position
571
318
 
572
- if (state.mesh instanceof three.InstancedMesh) {
573
- state.mesh.instanceMatrix.needsUpdate = true;
574
- }
575
- }); // Collision events
319
+ _matrix4.compose(t, rapierQuaternionToQuaternion(r), state.scale).premultiply(state.invertedWorldMatrix).decompose(_position, _rotation, _scale);
576
320
 
321
+ if (state.object instanceof three.InstancedMesh) {
322
+ state.setMatrix(_matrix4);
323
+ state.object.instanceMatrix.needsUpdate = true;
324
+ } else {
325
+ // Interpolate from last position
326
+ state.object.position.lerp(_position, interpolationAlpha);
327
+ state.object.quaternion.slerp(_rotation, interpolationAlpha);
328
+ }
329
+ });
577
330
  eventQueue.drainCollisionEvents((handle1, handle2, started) => {
578
331
  var _collider1$parent, _collider2$parent;
579
332
 
580
333
  const collider1 = world.getCollider(handle1);
581
334
  const collider2 = world.getCollider(handle2);
582
335
  const rigidBodyHandle1 = (_collider1$parent = collider1.parent()) === null || _collider1$parent === void 0 ? void 0 : _collider1$parent.handle;
583
- const rigidBodyHandle2 = (_collider2$parent = collider2.parent()) === null || _collider2$parent === void 0 ? void 0 : _collider2$parent.handle;
336
+ const rigidBodyHandle2 = (_collider2$parent = collider2.parent()) === null || _collider2$parent === void 0 ? void 0 : _collider2$parent.handle; // Collision Events
584
337
 
585
- if (!collider1 || !collider2 || rigidBodyHandle1 === undefined || rigidBodyHandle2 === undefined) {
338
+ if (!collider1 || !collider2) {
586
339
  return;
587
340
  }
588
341
 
589
- const rigidBody1 = world.getRigidBody(rigidBodyHandle1);
590
- const rigidBody2 = world.getRigidBody(rigidBodyHandle2);
591
- const rigidBody1Events = rigidBodyEvents.get(rigidBodyHandle1);
592
- const rigidBoyd2Events = rigidBodyEvents.get(rigidBodyHandle2);
593
342
  const collider1Events = colliderEvents.get(collider1.handle);
594
343
  const collider2Events = colliderEvents.get(collider2.handle);
344
+ const rigidBody1 = rigidBodyHandle1 ? world.getRigidBody(rigidBodyHandle1) : undefined;
345
+ const rigidBody2 = rigidBodyHandle2 ? world.getRigidBody(rigidBodyHandle2) : undefined;
346
+ const rigidBody1Events = rigidBodyHandle1 ? rigidBodyEvents.get(rigidBodyHandle1) : undefined;
347
+ const rigidBody2Events = rigidBodyHandle2 ? rigidBodyEvents.get(rigidBodyHandle2) : undefined;
348
+ const collider1State = colliderStates.get(collider1.handle);
349
+ const collider2State = colliderStates.get(collider2.handle);
350
+ const rigidBody1State = rigidBodyHandle1 ? rigidBodyStates.get(rigidBodyHandle1) : undefined;
351
+ const rigidBody2State = rigidBodyHandle2 ? rigidBodyStates.get(rigidBodyHandle2) : undefined;
595
352
 
596
353
  if (started) {
597
354
  world.contactPair(collider1, collider2, (manifold, flipped) => {
598
- var _rigidBody1Events$onC, _rigidBoyd2Events$onC, _collider1Events$onCo, _collider2Events$onCo;
355
+ var _rigidBody1Events$onC, _rigidBody2Events$onC, _collider1Events$onCo, _collider2Events$onCo;
599
356
 
600
357
  /* RigidBody events */
601
358
  rigidBody1Events === null || rigidBody1Events === void 0 ? void 0 : (_rigidBody1Events$onC = rigidBody1Events.onCollisionEnter) === null || _rigidBody1Events$onC === void 0 ? void 0 : _rigidBody1Events$onC.call(rigidBody1Events, {
602
- target: rigidBody2,
359
+ rigidBody: rigidBody2,
603
360
  collider: collider2,
361
+ colliderObject: collider2State === null || collider2State === void 0 ? void 0 : collider2State.object,
362
+ rigidBodyObject: rigidBody2State === null || rigidBody2State === void 0 ? void 0 : rigidBody2State.object,
604
363
  manifold,
605
364
  flipped
606
365
  });
607
- rigidBoyd2Events === null || rigidBoyd2Events === void 0 ? void 0 : (_rigidBoyd2Events$onC = rigidBoyd2Events.onCollisionEnter) === null || _rigidBoyd2Events$onC === void 0 ? void 0 : _rigidBoyd2Events$onC.call(rigidBoyd2Events, {
608
- target: rigidBody1,
366
+ rigidBody2Events === null || rigidBody2Events === void 0 ? void 0 : (_rigidBody2Events$onC = rigidBody2Events.onCollisionEnter) === null || _rigidBody2Events$onC === void 0 ? void 0 : _rigidBody2Events$onC.call(rigidBody2Events, {
367
+ rigidBody: rigidBody1,
609
368
  collider: collider1,
369
+ colliderObject: collider1State === null || collider1State === void 0 ? void 0 : collider1State.object,
370
+ rigidBodyObject: rigidBody1State === null || rigidBody1State === void 0 ? void 0 : rigidBody1State.object,
610
371
  manifold,
611
372
  flipped
612
373
  });
613
374
  /* Collider events */
614
375
 
615
376
  collider1Events === null || collider1Events === void 0 ? void 0 : (_collider1Events$onCo = collider1Events.onCollisionEnter) === null || _collider1Events$onCo === void 0 ? void 0 : _collider1Events$onCo.call(collider1Events, {
616
- target: rigidBody2,
377
+ rigidBody: rigidBody2,
617
378
  collider: collider2,
379
+ colliderObject: collider2State === null || collider2State === void 0 ? void 0 : collider2State.object,
380
+ rigidBodyObject: rigidBody2State === null || rigidBody2State === void 0 ? void 0 : rigidBody2State.object,
618
381
  manifold,
619
382
  flipped
620
383
  });
621
384
  collider2Events === null || collider2Events === void 0 ? void 0 : (_collider2Events$onCo = collider2Events.onCollisionEnter) === null || _collider2Events$onCo === void 0 ? void 0 : _collider2Events$onCo.call(collider2Events, {
622
- target: rigidBody1,
385
+ rigidBody: rigidBody1,
623
386
  collider: collider1,
387
+ colliderObject: collider1State === null || collider1State === void 0 ? void 0 : collider1State.object,
388
+ rigidBodyObject: rigidBody1State === null || rigidBody1State === void 0 ? void 0 : rigidBody1State.object,
624
389
  manifold,
625
390
  flipped
626
391
  });
627
392
  });
628
393
  } else {
629
- var _rigidBody1Events$onC2, _rigidBoyd2Events$onC2, _collider1Events$onCo2, _collider2Events$onCo2;
394
+ var _rigidBody1Events$onC2, _rigidBody2Events$onC2, _collider1Events$onCo2, _collider2Events$onCo2;
630
395
 
631
396
  rigidBody1Events === null || rigidBody1Events === void 0 ? void 0 : (_rigidBody1Events$onC2 = rigidBody1Events.onCollisionExit) === null || _rigidBody1Events$onC2 === void 0 ? void 0 : _rigidBody1Events$onC2.call(rigidBody1Events, {
632
- target: rigidBody2,
397
+ rigidBody: rigidBody2,
633
398
  collider: collider2
634
399
  });
635
- rigidBoyd2Events === null || rigidBoyd2Events === void 0 ? void 0 : (_rigidBoyd2Events$onC2 = rigidBoyd2Events.onCollisionExit) === null || _rigidBoyd2Events$onC2 === void 0 ? void 0 : _rigidBoyd2Events$onC2.call(rigidBoyd2Events, {
636
- target: rigidBody1,
400
+ rigidBody2Events === null || rigidBody2Events === void 0 ? void 0 : (_rigidBody2Events$onC2 = rigidBody2Events.onCollisionExit) === null || _rigidBody2Events$onC2 === void 0 ? void 0 : _rigidBody2Events$onC2.call(rigidBody2Events, {
401
+ rigidBody: rigidBody1,
637
402
  collider: collider1
638
403
  });
639
404
  collider1Events === null || collider1Events === void 0 ? void 0 : (_collider1Events$onCo2 = collider1Events.onCollisionExit) === null || _collider1Events$onCo2 === void 0 ? void 0 : _collider1Events$onCo2.call(collider1Events, {
640
- target: rigidBody2,
405
+ rigidBody: rigidBody2,
641
406
  collider: collider2
642
407
  });
643
408
  collider2Events === null || collider2Events === void 0 ? void 0 : (_collider2Events$onCo2 = collider2Events.onCollisionExit) === null || _collider2Events$onCo2 === void 0 ? void 0 : _collider2Events$onCo2.call(collider2Events, {
644
- target: rigidBody1,
409
+ rigidBody: rigidBody1,
410
+ collider: collider1
411
+ });
412
+ } // Sensor Intersections
413
+
414
+
415
+ if (started) {
416
+ if (world.intersectionPair(collider1, collider2)) {
417
+ var _rigidBody1Events$onI, _rigidBody2Events$onI, _collider1Events$onIn, _collider2Events$onIn;
418
+
419
+ rigidBody1Events === null || rigidBody1Events === void 0 ? void 0 : (_rigidBody1Events$onI = rigidBody1Events.onIntersectionEnter) === null || _rigidBody1Events$onI === void 0 ? void 0 : _rigidBody1Events$onI.call(rigidBody1Events, {
420
+ rigidBody: rigidBody2,
421
+ collider: collider2,
422
+ colliderObject: collider2State === null || collider2State === void 0 ? void 0 : collider2State.object,
423
+ rigidBodyObject: rigidBody2State === null || rigidBody2State === void 0 ? void 0 : rigidBody2State.object
424
+ });
425
+ rigidBody2Events === null || rigidBody2Events === void 0 ? void 0 : (_rigidBody2Events$onI = rigidBody2Events.onIntersectionEnter) === null || _rigidBody2Events$onI === void 0 ? void 0 : _rigidBody2Events$onI.call(rigidBody2Events, {
426
+ rigidBody: rigidBody1,
427
+ collider: collider1,
428
+ colliderObject: collider1State === null || collider1State === void 0 ? void 0 : collider1State.object,
429
+ rigidBodyObject: rigidBody1State === null || rigidBody1State === void 0 ? void 0 : rigidBody1State.object
430
+ });
431
+ collider1Events === null || collider1Events === void 0 ? void 0 : (_collider1Events$onIn = collider1Events.onIntersectionEnter) === null || _collider1Events$onIn === void 0 ? void 0 : _collider1Events$onIn.call(collider1Events, {
432
+ rigidBody: rigidBody2,
433
+ collider: collider2,
434
+ colliderObject: collider2State === null || collider2State === void 0 ? void 0 : collider2State.object,
435
+ rigidBodyObject: rigidBody2State === null || rigidBody2State === void 0 ? void 0 : rigidBody2State.object
436
+ });
437
+ collider2Events === null || collider2Events === void 0 ? void 0 : (_collider2Events$onIn = collider2Events.onIntersectionEnter) === null || _collider2Events$onIn === void 0 ? void 0 : _collider2Events$onIn.call(collider2Events, {
438
+ rigidBody: rigidBody1,
439
+ collider: collider1,
440
+ colliderObject: collider1State === null || collider1State === void 0 ? void 0 : collider1State.object,
441
+ rigidBodyObject: rigidBody1State === null || rigidBody1State === void 0 ? void 0 : rigidBody1State.object
442
+ });
443
+ }
444
+ } else {
445
+ var _rigidBody1Events$onI2, _rigidBody2Events$onI2, _collider1Events$onIn2, _collider2Events$onIn2;
446
+
447
+ rigidBody1Events === null || rigidBody1Events === void 0 ? void 0 : (_rigidBody1Events$onI2 = rigidBody1Events.onIntersectionExit) === null || _rigidBody1Events$onI2 === void 0 ? void 0 : _rigidBody1Events$onI2.call(rigidBody1Events, {
448
+ rigidBody: rigidBody2,
449
+ collider: collider2
450
+ });
451
+ rigidBody2Events === null || rigidBody2Events === void 0 ? void 0 : (_rigidBody2Events$onI2 = rigidBody2Events.onIntersectionExit) === null || _rigidBody2Events$onI2 === void 0 ? void 0 : _rigidBody2Events$onI2.call(rigidBody2Events, {
452
+ rigidBody: rigidBody1,
453
+ collider: collider1
454
+ });
455
+ collider1Events === null || collider1Events === void 0 ? void 0 : (_collider1Events$onIn2 = collider1Events.onIntersectionExit) === null || _collider1Events$onIn2 === void 0 ? void 0 : _collider1Events$onIn2.call(collider1Events, {
456
+ rigidBody: rigidBody2,
457
+ collider: collider2
458
+ });
459
+ collider2Events === null || collider2Events === void 0 ? void 0 : (_collider2Events$onIn2 = collider2Events.onIntersectionExit) === null || _collider2Events$onIn2 === void 0 ? void 0 : _collider2Events$onIn2.call(collider2Events, {
460
+ rigidBody: rigidBody1,
645
461
  collider: collider1
646
462
  });
647
463
  }
@@ -656,6 +472,7 @@ const Physics = ({
656
472
  gravity: _gravity
657
473
  },
658
474
  rigidBodyStates,
475
+ colliderStates,
659
476
  rigidBodyEvents,
660
477
  colliderEvents,
661
478
  isPaused
@@ -758,144 +575,466 @@ function _objectSpread2(target) {
758
575
  return target;
759
576
  }
760
577
 
761
- const useRapier = () => {
762
- return React.useContext(RapierContext);
578
+ const rigidBodyDescFromOptions = options => {
579
+ const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
580
+ const desc = new rapier3dCompat.RigidBodyDesc(type);
581
+ return desc;
763
582
  };
764
- const useRigidBody = (options = {}) => {
765
- const {
766
- world,
767
- rigidBodyStates,
768
- physicsOptions,
769
- rigidBodyEvents
770
- } = useRapier();
771
- const ref = React.useRef(); // Create rigidbody
772
-
773
- const rigidBodyRef = React.useRef();
774
- const getRigidBodyRef = React.useRef(() => {
775
- if (!rigidBodyRef.current) {
776
- const desc = rigidBodyDescFromOptions(options);
777
- const rigidBody = world.createRigidBody(desc);
778
- rigidBodyRef.current = world.getRigidBody(rigidBody.handle);
779
- }
780
-
781
- return rigidBodyRef.current;
782
- }); // Setup
583
+ const createRigidBodyState = ({
584
+ rigidBody,
585
+ object,
586
+ setMatrix,
587
+ getMatrix,
588
+ worldScale
589
+ }) => {
590
+ object.updateWorldMatrix(true, false);
591
+ const invertedWorldMatrix = object.parent.matrixWorld.clone().invert();
592
+ return {
593
+ object,
594
+ rigidBody,
595
+ invertedWorldMatrix,
596
+ setMatrix: setMatrix ? setMatrix : matrix => {
597
+ object.matrix.copy(matrix);
598
+ },
599
+ getMatrix: getMatrix ? getMatrix : matrix => matrix.copy(object.matrix),
600
+ scale: worldScale || object.getWorldScale(_scale).clone(),
601
+ isSleeping: false
602
+ };
603
+ };
604
+ const mutableRigidBodyOptions = {
605
+ gravityScale: (rb, value) => {
606
+ rb.setGravityScale(value, true);
607
+ },
608
+ linearDamping: (rb, value) => {
609
+ rb.setLinearDamping(value);
610
+ },
611
+ angularDamping: (rb, value) => {
612
+ rb.setAngularDamping(value);
613
+ },
614
+ enabledRotations: (rb, [x, y, z]) => {
615
+ rb.setEnabledRotations(x, y, z, true);
616
+ },
617
+ enabledTranslations: (rb, [x, y, z]) => {
618
+ rb.setEnabledTranslations(x, y, z, true);
619
+ },
620
+ angularVelocity: (rb, [x, y, z]) => {
621
+ rb.setAngvel({
622
+ x,
623
+ y,
624
+ z
625
+ }, true);
626
+ },
627
+ linearVelocity: (rb, [x, y, z]) => {
628
+ rb.setLinvel({
629
+ x,
630
+ y,
631
+ z
632
+ }, true);
633
+ },
634
+ ccd: (rb, value) => {
635
+ rb.enableCcd(value);
636
+ }
637
+ };
638
+ const mutableRigidBodyOptionKeys = Object.keys(mutableRigidBodyOptions);
639
+ const setRigidBodyOptions = (rigidBody, options, states, updateTranslations = true) => {
640
+ if (!rigidBody) {
641
+ return;
642
+ }
783
643
 
784
- React.useEffect(() => {
785
- var _ref$current$parent, _ref, _options$colliders;
644
+ const state = states.get(rigidBody.handle);
786
645
 
787
- const rigidBody = getRigidBodyRef.current();
788
- rigidBodyRef.current = rigidBody;
646
+ if (state) {
647
+ if (updateTranslations) {
648
+ state.object.updateWorldMatrix(true, false);
789
649
 
790
- if (!ref.current) {
791
- ref.current = new three.Object3D();
792
- } // isSleeping used for onSleep and onWake events
650
+ _matrix4.copy(state.object.matrixWorld).decompose(_position, _rotation, _scale);
793
651
 
652
+ rigidBody.setTranslation(_position, false);
653
+ rigidBody.setRotation(_rotation, false);
654
+ }
794
655
 
795
- ref.current.userData.isSleeping = false; // Get intitial world transforms
796
-
797
- const worldPosition = ref.current.getWorldPosition(new three.Vector3());
798
- const worldRotation = ref.current.getWorldQuaternion(new three.Quaternion());
799
- const scale = ((_ref$current$parent = ref.current.parent) === null || _ref$current$parent === void 0 ? void 0 : _ref$current$parent.getWorldScale(new three.Vector3())) || {
800
- x: 1,
801
- y: 1,
802
- z: 1
803
- }; // Transforms from options
804
-
805
- const [x, y, z] = (options === null || options === void 0 ? void 0 : options.position) || [0, 0, 0];
806
- const [rx, ry, rz] = (options === null || options === void 0 ? void 0 : options.rotation) || [0, 0, 0]; // Set initial transforms based on world transforms
807
-
808
- rigidBody.setTranslation({
809
- x: worldPosition.x + x * scale.x,
810
- y: worldPosition.y + y * scale.y,
811
- z: worldPosition.z + z * scale.z
812
- }, false);
813
- const rotation = vector3ToQuaternion(new three.Vector3(rx, ry, rz)).multiply(worldRotation);
814
- rigidBody.setRotation({
815
- x: rotation.x,
816
- y: rotation.y,
817
- z: rotation.z,
818
- w: rotation.w
819
- }, false);
820
- rigidBody.resetForces(false);
821
- rigidBody.resetTorques(false);
822
- const colliderSetting = (_ref = (_options$colliders = options === null || options === void 0 ? void 0 : options.colliders) !== null && _options$colliders !== void 0 ? _options$colliders : physicsOptions.colliders) !== null && _ref !== void 0 ? _ref : false;
823
- const autoColliders = colliderSetting !== false ? createCollidersFromChildren({
824
- object: ref.current,
825
- rigidBody,
826
- options: _objectSpread2(_objectSpread2({}, options), {}, {
827
- colliders: colliderSetting
828
- }),
829
- world,
830
- ignoreMeshColliders: true
831
- }) : [];
832
- rigidBodyStates.set(rigidBody.handle, {
833
- mesh: ref.current,
834
- invertedMatrixWorld: ref.current.parent.matrixWorld.clone().invert(),
835
- isSleeping: false,
836
- worldScale: ref.current.getWorldScale(_vector3).clone(),
837
- setMatrix: mat => ref.current.matrix.copy(mat),
838
- getMatrix: () => ref.current.matrix
656
+ mutableRigidBodyOptionKeys.forEach(key => {
657
+ if (key in options) {
658
+ mutableRigidBodyOptions[key](rigidBody, options[key]);
659
+ }
839
660
  });
840
- ref.current.matrixAutoUpdate = false;
841
- return () => {
842
- world.removeRigidBody(rigidBody);
843
- autoColliders.forEach(collider => world.removeCollider(collider));
844
- rigidBodyRef.current = undefined;
845
- rigidBodyStates.delete(rigidBody.handle);
846
- };
847
- }, []); // Events
848
-
661
+ }
662
+ };
663
+ const useUpdateRigidBodyOptions = (rigidBodyRef, props, states, updateTranslations = true) => {
849
664
  React.useEffect(() => {
850
- const rigidBody = getRigidBodyRef.current();
851
- rigidBodyEvents.set(rigidBody.handle, {
852
- onCollisionEnter: options === null || options === void 0 ? void 0 : options.onCollisionEnter,
853
- onCollisionExit: options === null || options === void 0 ? void 0 : options.onCollisionExit,
854
- onSleep: options === null || options === void 0 ? void 0 : options.onSleep,
855
- onWake: options === null || options === void 0 ? void 0 : options.onWake
856
- });
857
- return () => {
858
- rigidBodyEvents.delete(rigidBody.handle);
859
- };
860
- }, [options.onCollisionEnter, options.onCollisionExit]);
861
- const api = React.useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
862
- return [ref, api];
863
- }; // Joints
864
-
865
- const useImpulseJoint = (body1, body2, params) => {
665
+ if ("length" in rigidBodyRef.current) {
666
+ rigidBodyRef.current.forEach(rigidBody => {
667
+ setRigidBodyOptions(rigidBody, props, states, updateTranslations);
668
+ });
669
+ } else {
670
+ setRigidBodyOptions(rigidBodyRef.current, props, states, updateTranslations);
671
+ }
672
+ }, [props]);
673
+ };
674
+ const useRigidBodyEvents = (rigidBodyRef, props, events) => {
866
675
  const {
867
- world
868
- } = useRapier();
869
- const jointRef = React.useRef();
870
- const getJointRef = React.useRef(() => {
871
- if (!jointRef.current) {
872
- let rb1;
873
- let rb2;
874
-
875
- if ("current" in body1 && body1.current && "current" in body2 && body2.current) {
876
- rb1 = world.getRigidBody(body1.current.handle);
877
- rb2 = world.getRigidBody(body2.current.handle);
878
- const newJoint = world.createImpulseJoint(params, rb1, rb2);
879
- jointRef.current = newJoint;
880
- }
676
+ onWake,
677
+ onSleep,
678
+ onCollisionEnter,
679
+ onCollisionExit,
680
+ onIntersectionEnter,
681
+ onIntersectionExit
682
+ } = props;
683
+ const eventHandlers = {
684
+ onWake,
685
+ onSleep,
686
+ onCollisionEnter,
687
+ onCollisionExit,
688
+ onIntersectionEnter,
689
+ onIntersectionExit
690
+ };
691
+ React.useEffect(() => {
692
+ if ("length" in rigidBodyRef.current) {
693
+ rigidBodyRef.current.forEach(rigidBody => {
694
+ events.set(rigidBody.handle, eventHandlers);
695
+ });
696
+ } else {
697
+ events.set(rigidBodyRef.current.handle, eventHandlers);
881
698
  }
882
699
 
883
- return jointRef.current;
884
- });
885
- React.useEffect(() => {
886
- const joint = getJointRef.current();
887
700
  return () => {
888
- if (joint) {
889
- world.removeImpulseJoint(joint);
890
- jointRef.current = undefined;
701
+ if ("length" in rigidBodyRef.current) {
702
+ rigidBodyRef.current.forEach(rigidBody => {
703
+ events.delete(rigidBody.handle);
704
+ });
705
+ } else {
706
+ events.delete(rigidBodyRef.current.handle);
891
707
  }
892
708
  };
893
- }, []);
894
- const api = React.useMemo(() => createJointApi(getJointRef), []);
895
- return api;
709
+ }, [onWake, onSleep, onCollisionEnter, onCollisionExit]);
896
710
  };
897
- /**
898
- *
711
+
712
+ const scaleColliderArgs = (shape, args, scale) => {
713
+ const newArgs = args.slice(); // Heightfield uses a vector
714
+
715
+ if (shape === "heightfield") {
716
+ const s = newArgs[3];
717
+ s.x *= scale.x;
718
+ s.x *= scale.y;
719
+ s.x *= scale.z;
720
+ return newArgs;
721
+ } // Trimesh and convex scale the vertices
722
+
723
+
724
+ if (shape === "trimesh" || shape === "convexHull") {
725
+ newArgs[0] = scaleVertices(newArgs[0], scale);
726
+ return newArgs;
727
+ } // Prepfill with some extra
728
+
729
+
730
+ const scaleArray = [scale.x, scale.y, scale.z, scale.x, scale.x];
731
+ return newArgs.map((arg, index) => scaleArray[index] * arg);
732
+ };
733
+ const createColliderFromOptions = (options, world, scale, rigidBody) => {
734
+ const scaledArgs = scaleColliderArgs(options.shape, options.args, scale); // @ts-ignore
735
+
736
+ const desc = rapier3dCompat.ColliderDesc[options.shape](...scaledArgs);
737
+ return world.createCollider(desc, rigidBody);
738
+ };
739
+ const mutableColliderOptions = {
740
+ sensor: (collider, value) => {
741
+ collider.setSensor(value);
742
+ },
743
+ collisionGroups: (collider, value) => {
744
+ collider.setCollisionGroups(value);
745
+ },
746
+ solverGroups: (collider, value) => {
747
+ collider.setSolverGroups(value);
748
+ },
749
+ friction: (collider, value) => {
750
+ collider.setFriction(value);
751
+ },
752
+ restitution: (collider, value) => {
753
+ collider.setRestitution(value);
754
+ },
755
+ density: (collider, value) => {
756
+ collider.setDensity(value);
757
+ },
758
+ mass: (collider, value) => {
759
+ collider.setMass(value);
760
+ }
761
+ };
762
+ const mutableColliderOptionKeys = Object.keys(mutableColliderOptions);
763
+ const setColliderOptions = (collider, options, states) => {
764
+ const state = states.get(collider.handle);
765
+
766
+ if (state) {
767
+ // Update collider position based on the object's position
768
+ const parentWorldScale = state.object.parent.getWorldScale(_vector3);
769
+ state.object.updateWorldMatrix(true, false);
770
+
771
+ _matrix4.copy(state.object.matrixWorld).premultiply(state.worldParent.matrixWorld.clone().invert()).decompose(_position, _rotation, _scale);
772
+
773
+ collider.setTranslationWrtParent({
774
+ x: _position.x * parentWorldScale.x,
775
+ y: _position.y * parentWorldScale.y,
776
+ z: _position.z * parentWorldScale.z
777
+ });
778
+ collider.setRotationWrtParent(_rotation);
779
+ mutableColliderOptionKeys.forEach(key => {
780
+ if (key in options) {
781
+ mutableColliderOptions[key](collider, options[key]);
782
+ }
783
+ });
784
+ }
785
+ };
786
+ const useUpdateColliderOptions = (collidersRef, props, states) => {
787
+ React.useEffect(() => {
788
+ collidersRef.current.forEach(collider => {
789
+ setColliderOptions(collider, props, states);
790
+ });
791
+ }, [props]);
792
+ };
793
+
794
+ const isChildOfMeshCollider = child => {
795
+ let flag = false;
796
+ child.traverseAncestors(a => {
797
+ if (a.userData.r3RapierType === "MeshCollider") flag = true;
798
+ });
799
+ return flag;
800
+ };
801
+
802
+ const createColliderState = (collider, object, rigidBodyObject) => {
803
+ return {
804
+ collider,
805
+ worldParent: rigidBodyObject || object.parent,
806
+ object
807
+ };
808
+ };
809
+ const autoColliderMap = {
810
+ cuboid: "cuboid",
811
+ ball: "ball",
812
+ hull: "convexHull",
813
+ trimesh: "trimesh"
814
+ };
815
+ const createColliderPropsFromChildren = ({
816
+ object,
817
+ ignoreMeshColliders: _ignoreMeshColliders = true,
818
+ options
819
+ }) => {
820
+ const colliderProps = [];
821
+ object.updateWorldMatrix(true, false);
822
+ const invertedParentMatrixWorld = object.matrixWorld.clone().invert();
823
+ object.traverseVisible(child => {
824
+ if ("isMesh" in child) {
825
+ if (_ignoreMeshColliders && isChildOfMeshCollider(child)) return;
826
+ const worldScale = child.getWorldScale(_scale);
827
+ const shape = autoColliderMap[options.colliders || "cuboid"];
828
+ child.updateWorldMatrix(true, false);
829
+
830
+ _matrix4.copy(child.matrixWorld).premultiply(invertedParentMatrixWorld).decompose(_position, _rotation, _scale);
831
+
832
+ const rotationEuler = new three.Euler().setFromQuaternion(_rotation, "XYZ");
833
+ const {
834
+ geometry
835
+ } = child;
836
+ const {
837
+ args,
838
+ offset
839
+ } = getColliderArgsFromGeometry(geometry, options.colliders || "cuboid");
840
+ colliderProps.push(_objectSpread2(_objectSpread2({}, options), {}, {
841
+ args: args,
842
+ shape: shape,
843
+ rotation: [rotationEuler.x, rotationEuler.y, rotationEuler.z],
844
+ position: [_position.x + offset.x * worldScale.x, _position.y + offset.y * worldScale.y, _position.z + offset.z * worldScale.z],
845
+ scale: [worldScale.x, worldScale.y, worldScale.z]
846
+ }));
847
+ }
848
+ });
849
+ return colliderProps;
850
+ };
851
+ const getColliderArgsFromGeometry = (geometry, colliders) => {
852
+ switch (colliders) {
853
+ case "cuboid":
854
+ {
855
+ geometry.computeBoundingBox();
856
+ const {
857
+ boundingBox
858
+ } = geometry;
859
+ const size = boundingBox.getSize(new three.Vector3());
860
+ return {
861
+ args: [size.x / 2, size.y / 2, size.z / 2],
862
+ offset: boundingBox.getCenter(new three.Vector3())
863
+ };
864
+ }
865
+
866
+ case "ball":
867
+ {
868
+ geometry.computeBoundingSphere();
869
+ const {
870
+ boundingSphere
871
+ } = geometry;
872
+ const radius = boundingSphere.radius;
873
+ return {
874
+ args: [radius],
875
+ offset: boundingSphere.center
876
+ };
877
+ }
878
+
879
+ case "trimesh":
880
+ {
881
+ var _clonedGeometry$index;
882
+
883
+ const clonedGeometry = geometry.index ? geometry.clone() : threeStdlib.mergeVertices(geometry);
884
+ return {
885
+ args: [clonedGeometry.attributes.position.array, (_clonedGeometry$index = clonedGeometry.index) === null || _clonedGeometry$index === void 0 ? void 0 : _clonedGeometry$index.array],
886
+ offset: new three.Vector3()
887
+ };
888
+ }
889
+
890
+ case "hull":
891
+ {
892
+ const g = geometry.clone();
893
+ return {
894
+ args: [g.attributes.position.array],
895
+ offset: new three.Vector3()
896
+ };
897
+ }
898
+ }
899
+
900
+ return {
901
+ args: [],
902
+ offset: new three.Vector3()
903
+ };
904
+ };
905
+ const useColliderEvents = (collidersRef, props, events) => {
906
+ const {
907
+ onCollisionEnter,
908
+ onCollisionExit,
909
+ onIntersectionEnter,
910
+ onIntersectionExit
911
+ } = props;
912
+ React.useEffect(() => {
913
+ var _collidersRef$current;
914
+
915
+ (_collidersRef$current = collidersRef.current) === null || _collidersRef$current === void 0 ? void 0 : _collidersRef$current.forEach(collider => {
916
+ if (onCollisionEnter || onCollisionExit || onIntersectionEnter || onIntersectionExit) {
917
+ collider.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
918
+ }
919
+
920
+ events.set(collider.handle, {
921
+ onCollisionEnter,
922
+ onCollisionExit,
923
+ onIntersectionEnter,
924
+ onIntersectionExit
925
+ });
926
+ });
927
+ return () => {
928
+ var _collidersRef$current2;
929
+
930
+ (_collidersRef$current2 = collidersRef.current) === null || _collidersRef$current2 === void 0 ? void 0 : _collidersRef$current2.forEach(collider => events.delete(collider.handle));
931
+ };
932
+ }, [onCollisionEnter, onCollisionExit]);
933
+ };
934
+
935
+ const useRapier = () => {
936
+ return React.useContext(RapierContext);
937
+ };
938
+ const useChildColliderProps = (ref, options, ignoreMeshColliders = true) => {
939
+ const [colliderProps, setColliderProps] = React.useState([]);
940
+ React.useEffect(() => {
941
+ const object = ref.current;
942
+
943
+ if (object && options.colliders !== false) {
944
+ setColliderProps(createColliderPropsFromChildren({
945
+ object: ref.current,
946
+ options,
947
+ ignoreMeshColliders
948
+ }));
949
+ }
950
+ }, [options]);
951
+ return colliderProps;
952
+ };
953
+ const useRigidBody = (options = {}) => {
954
+ const {
955
+ world,
956
+ rigidBodyStates,
957
+ physicsOptions,
958
+ rigidBodyEvents
959
+ } = useRapier();
960
+ const ref = React.useRef();
961
+ const mergedOptions = React.useMemo(() => {
962
+ return _objectSpread2(_objectSpread2(_objectSpread2({}, physicsOptions), options), {}, {
963
+ children: undefined
964
+ });
965
+ }, [physicsOptions, options]);
966
+ const childColliderProps = useChildColliderProps(ref, mergedOptions); // Create rigidbody
967
+
968
+ const rigidBodyRef = React.useRef();
969
+ const getRigidBodyRef = React.useRef(() => {
970
+ if (!rigidBodyRef.current) {
971
+ const desc = rigidBodyDescFromOptions(options);
972
+ const rigidBody = world.createRigidBody(desc);
973
+ rigidBodyRef.current = world.getRigidBody(rigidBody.handle);
974
+ }
975
+
976
+ return rigidBodyRef.current;
977
+ }); // Setup
978
+
979
+ React.useEffect(() => {
980
+ const rigidBody = getRigidBodyRef.current();
981
+ rigidBodyRef.current = rigidBody;
982
+
983
+ if (!ref.current) {
984
+ ref.current = new three.Object3D();
985
+ } // isSleeping used for onSleep and onWake events
986
+
987
+
988
+ ref.current.userData.isSleeping = false;
989
+ rigidBodyStates.set(rigidBody.handle, createRigidBodyState({
990
+ rigidBody,
991
+ object: ref.current
992
+ }));
993
+ return () => {
994
+ world.removeRigidBody(rigidBody);
995
+ rigidBodyStates.delete(rigidBody.handle);
996
+ };
997
+ }, []);
998
+ useUpdateRigidBodyOptions(rigidBodyRef, mergedOptions, rigidBodyStates);
999
+ useRigidBodyEvents(rigidBodyRef, mergedOptions, rigidBodyEvents);
1000
+ const api = React.useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
1001
+ return [ref, api, childColliderProps];
1002
+ }; // Joints
1003
+
1004
+ const useImpulseJoint = (body1, body2, params) => {
1005
+ const {
1006
+ world
1007
+ } = useRapier();
1008
+ const jointRef = React.useRef();
1009
+ const getJointRef = React.useRef(() => {
1010
+ if (!jointRef.current) {
1011
+ let rb1;
1012
+ let rb2;
1013
+
1014
+ if ("current" in body1 && body1.current && "current" in body2 && body2.current) {
1015
+ rb1 = world.getRigidBody(body1.current.handle);
1016
+ rb2 = world.getRigidBody(body2.current.handle);
1017
+ const newJoint = world.createImpulseJoint(params, rb1, rb2);
1018
+ jointRef.current = newJoint;
1019
+ }
1020
+ }
1021
+
1022
+ return jointRef.current;
1023
+ });
1024
+ React.useEffect(() => {
1025
+ const joint = getJointRef.current();
1026
+ return () => {
1027
+ if (joint) {
1028
+ world.removeImpulseJoint(joint);
1029
+ jointRef.current = undefined;
1030
+ }
1031
+ };
1032
+ }, []);
1033
+ const api = React.useMemo(() => createJointApi(getJointRef), []);
1034
+ return api;
1035
+ };
1036
+ /**
1037
+ *
899
1038
  * A fixed joint ensures that two rigid-bodies don't move relative to each other.
900
1039
  * Fixed joints are characterized by one local frame (represented by an isometry) on each rigid-body.
901
1040
  * The fixed-joint makes these frames coincide in world-space.
@@ -949,80 +1088,173 @@ const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
949
1088
  return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
950
1089
  };
951
1090
 
952
- const _excluded$1 = ["children"],
953
- _excluded2 = ["type", "position", "rotation"];
954
- const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
955
- const useRigidBodyContext = () => React.useContext(RigidBodyContext); // RigidBody
1091
+ // Colliders
1092
+ const AnyCollider = /*#__PURE__*/React.memo(props => {
1093
+ const {
1094
+ children,
1095
+ position,
1096
+ rotation,
1097
+ quaternion,
1098
+ scale
1099
+ } = props;
1100
+ const {
1101
+ world,
1102
+ colliderEvents,
1103
+ colliderStates
1104
+ } = useRapier();
1105
+ const rigidBodyContext = useRigidBodyContext();
1106
+ const ref = React.useRef(null);
1107
+ const collidersRef = React.useRef([]);
1108
+ React.useEffect(() => {
1109
+ const object = ref.current;
1110
+ const worldScale = object.getWorldScale(new three.Vector3());
1111
+ const colliders = []; // If this is an InstancedRigidBody api
956
1112
 
957
- const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
958
- let {
959
- children
960
- } = _ref,
961
- props = _objectWithoutProperties(_ref, _excluded$1);
1113
+ if (rigidBodyContext && "at" in rigidBodyContext.api) {
1114
+ rigidBodyContext.api.forEach((body, index) => {
1115
+ var _rigidBodyContext$opt, _rigidBodyContext$opt2;
1116
+
1117
+ let instanceScale = worldScale;
962
1118
 
963
- const [object, api] = useRigidBody(props);
1119
+ if ("scales" in rigidBodyContext.options && rigidBodyContext !== null && rigidBodyContext !== void 0 && (_rigidBodyContext$opt = rigidBodyContext.options) !== null && _rigidBodyContext$opt !== void 0 && (_rigidBodyContext$opt2 = _rigidBodyContext$opt.scales) !== null && _rigidBodyContext$opt2 !== void 0 && _rigidBodyContext$opt2[index]) {
1120
+ instanceScale = instanceScale.clone().multiply(vectorArrayToVector3(rigidBodyContext.options.scales[index]));
1121
+ }
964
1122
 
965
- const objectProps = _objectWithoutProperties(props, _excluded2);
1123
+ const collider = createColliderFromOptions(props, world, instanceScale, body.raw());
1124
+ colliderStates.set(collider.handle, createColliderState(collider, object, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
1125
+ colliders.push(collider);
1126
+ });
1127
+ } else {
1128
+ const collider = createColliderFromOptions(props, world, worldScale, rigidBodyContext && (rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.api).raw());
1129
+ colliderStates.set(collider.handle, createColliderState(collider, object, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
1130
+ colliders.push(collider);
1131
+ }
966
1132
 
1133
+ collidersRef.current = colliders;
1134
+ return () => {
1135
+ colliders.forEach(collider => {
1136
+ world.removeCollider(collider);
1137
+ });
1138
+ };
1139
+ }, []);
1140
+ useUpdateColliderOptions(collidersRef, props, colliderStates);
1141
+ useColliderEvents(collidersRef, props, colliderEvents);
1142
+ return /*#__PURE__*/React__default["default"].createElement("object3D", {
1143
+ position: position,
1144
+ rotation: rotation,
1145
+ quaternion: quaternion,
1146
+ scale: scale,
1147
+ ref: ref
1148
+ }, children);
1149
+ });
1150
+ const CuboidCollider = props => {
1151
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1152
+ shape: "cuboid"
1153
+ }));
1154
+ };
1155
+ const RoundCuboidCollider = props => {
1156
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1157
+ shape: "roundCuboid"
1158
+ }));
1159
+ };
1160
+ const BallCollider = props => {
1161
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1162
+ shape: "ball"
1163
+ }));
1164
+ };
1165
+ const CapsuleCollider = props => {
1166
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1167
+ shape: "capsule"
1168
+ }));
1169
+ };
1170
+ const HeightfieldCollider = props => {
1171
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1172
+ shape: "heightfield"
1173
+ }));
1174
+ };
1175
+ const TrimeshCollider = props => {
1176
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1177
+ shape: "trimesh"
1178
+ }));
1179
+ };
1180
+ const ConeCollider = props => {
1181
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1182
+ shape: "cone"
1183
+ }));
1184
+ };
1185
+ const CylinderCollider = props => {
1186
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1187
+ shape: "cylinder"
1188
+ }));
1189
+ };
1190
+ const ConvexHullCollider = props => {
1191
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1192
+ shape: "convexHull"
1193
+ }));
1194
+ };
1195
+
1196
+ const _excluded$1 = ["children", "type", "position", "rotation", "scale", "quaternion"];
1197
+ const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
1198
+ const useRigidBodyContext = () => React.useContext(RigidBodyContext);
1199
+ const RigidBody = /*#__PURE__*/React.forwardRef((props, ref) => {
1200
+ const {
1201
+ children,
1202
+ type,
1203
+ position,
1204
+ rotation,
1205
+ scale,
1206
+ quaternion
1207
+ } = props,
1208
+ objectProps = _objectWithoutProperties(props, _excluded$1);
1209
+
1210
+ const [object, api, childColliderProps] = useRigidBody(props);
967
1211
  React.useImperativeHandle(ref, () => api);
968
1212
  return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
969
1213
  value: {
970
1214
  ref: object,
971
1215
  api,
972
- hasCollisionEvents: !!(props.onCollisionEnter || props.onCollisionExit),
973
1216
  options: props
974
1217
  }
975
1218
  }, /*#__PURE__*/React__default["default"].createElement("object3D", _extends({
976
1219
  ref: object
977
- }, objectProps), children));
1220
+ }, objectProps, {
1221
+ position: position,
1222
+ rotation: rotation,
1223
+ quaternion: quaternion,
1224
+ scale: scale
1225
+ }), children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({
1226
+ key: index
1227
+ }, colliderProps)))));
978
1228
  });
979
1229
 
980
- const MeshCollider = ({
981
- children,
982
- type
983
- }) => {
1230
+ const MeshCollider = props => {
1231
+ const {
1232
+ children,
1233
+ type
1234
+ } = props;
984
1235
  const {
985
1236
  physicsOptions,
986
1237
  world
987
1238
  } = useRapier();
988
1239
  const object = React.useRef(null);
989
1240
  const {
990
- api,
991
1241
  options
992
1242
  } = useRigidBodyContext();
993
- React.useEffect(() => {
994
- let autoColliders = [];
995
-
996
- if (object.current) {
997
- var _ref;
998
-
999
- const colliderSetting = (_ref = type !== null && type !== void 0 ? type : physicsOptions.colliders) !== null && _ref !== void 0 ? _ref : false;
1000
-
1001
- if ("raw" in api) {
1002
- autoColliders = createCollidersFromChildren({
1003
- object: object.current,
1004
- rigidBody: api,
1005
- options: _objectSpread2(_objectSpread2({}, options), {}, {
1006
- colliders: colliderSetting
1007
- }),
1008
- world,
1009
- ignoreMeshColliders: false
1010
- });
1011
- }
1012
- }
1013
-
1014
- return () => {
1015
- autoColliders.forEach(collider => {
1016
- world.removeCollider(collider);
1017
- });
1018
- };
1019
- }, []);
1243
+ const mergedOptions = React.useMemo(() => {
1244
+ return _objectSpread2(_objectSpread2(_objectSpread2({}, physicsOptions), options), {}, {
1245
+ children: undefined,
1246
+ colliders: type
1247
+ });
1248
+ }, [physicsOptions, options]);
1249
+ const childColliderProps = useChildColliderProps(object, mergedOptions, false);
1020
1250
  return /*#__PURE__*/React__default["default"].createElement("object3D", {
1021
1251
  ref: object,
1022
1252
  userData: {
1023
1253
  r3RapierType: "MeshCollider"
1024
1254
  }
1025
- }, children);
1255
+ }, children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({
1256
+ key: index
1257
+ }, colliderProps))));
1026
1258
  };
1027
1259
 
1028
1260
  const geometryFromCollider = collider => {
@@ -1199,14 +1431,24 @@ const Debug = ({
1199
1431
  })));
1200
1432
  };
1201
1433
 
1434
+ const _excluded = ["positions", "rotations", "children"];
1202
1435
  const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
1203
1436
  const {
1204
1437
  world,
1205
1438
  rigidBodyStates,
1206
- physicsOptions
1439
+ physicsOptions,
1440
+ rigidBodyEvents
1207
1441
  } = useRapier();
1208
1442
  const object = React.useRef(null);
1209
- const instancesRef = React.useRef();
1443
+
1444
+ const {
1445
+ positions,
1446
+ rotations,
1447
+ children
1448
+ } = props,
1449
+ options = _objectWithoutProperties(props, _excluded);
1450
+
1451
+ const instancesRef = React.useRef([]);
1210
1452
  const instancesRefGetter = React.useRef(() => {
1211
1453
  if (!instancesRef.current) {
1212
1454
  instancesRef.current = [];
@@ -1214,235 +1456,94 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
1214
1456
 
1215
1457
  return instancesRef.current;
1216
1458
  });
1459
+ const mergedOptions = React.useMemo(() => {
1460
+ return _objectSpread2(_objectSpread2({}, physicsOptions), options);
1461
+ }, [physicsOptions, options]);
1462
+ const childColliderProps = useChildColliderProps(object, mergedOptions);
1217
1463
  React.useLayoutEffect(() => {
1218
- const colliders = [];
1464
+ object.current.updateWorldMatrix(true, false);
1219
1465
  const rigidBodies = instancesRefGetter.current();
1220
-
1221
- if (object.current) {
1222
- const worldScale = object.current.getWorldScale(new three.Vector3());
1223
- let hasOneMesh = false;
1224
- object.current.traverse(mesh => {
1225
- if (mesh instanceof three.InstancedMesh) {
1226
- if (hasOneMesh) {
1227
- console.warn("Can only use a single InstancedMesh inside <InstancedRigidBodies />, more InstancedMeshes will be ignored.");
1228
- return;
1229
- }
1230
-
1231
- hasOneMesh = true;
1232
- mesh.instanceMatrix.setUsage(three.DynamicDrawUsage);
1233
-
1234
- for (let index = 0; index < mesh.count; index++) {
1235
- const scale = worldScale.clone();
1236
- const rigidBodyDesc = rigidBodyDescFromOptions(props);
1237
-
1238
- if (props.scales && props.scales[index]) {
1239
- const s = vectorArrayToVector3(props.scales[index]);
1240
- scale.multiply(s);
1466
+ const invertedWorld = object.current.matrixWorld.clone().invert();
1467
+ object.current.traverseVisible(mesh => {
1468
+ if (mesh instanceof three.InstancedMesh) {
1469
+ mesh.instanceMatrix.setUsage(three.DynamicDrawUsage);
1470
+ const worldScale = mesh.getWorldScale(_scale);
1471
+
1472
+ for (let index = 0; index < mesh.count; index++) {
1473
+ var _options$scales;
1474
+
1475
+ const desc = rigidBodyDescFromOptions(props);
1476
+ const rigidBody = world.createRigidBody(desc);
1477
+ const scale = ((_options$scales = options.scales) === null || _options$scales === void 0 ? void 0 : _options$scales[index]) || [1, 1, 1];
1478
+ const instanceScale = worldScale.clone().multiply(vectorArrayToVector3(scale));
1479
+ rigidBodyStates.set(rigidBody.handle, createRigidBodyState({
1480
+ rigidBody,
1481
+ object: mesh,
1482
+ setMatrix: matrix => mesh.setMatrixAt(index, matrix),
1483
+ getMatrix: matrix => {
1484
+ mesh.getMatrixAt(index, matrix);
1485
+ return matrix;
1486
+ },
1487
+ worldScale: instanceScale
1488
+ }));
1489
+ const [x, y, z] = (positions === null || positions === void 0 ? void 0 : positions[index]) || [0, 0, 0];
1490
+ const [rx, ry, rz] = (rotations === null || rotations === void 0 ? void 0 : rotations[index]) || [0, 0, 0];
1491
+
1492
+ _object3d.position.set(x, y, z);
1493
+
1494
+ _object3d.rotation.set(rx, ry, rz);
1495
+
1496
+ _object3d.applyMatrix4(invertedWorld);
1497
+
1498
+ mesh.setMatrixAt(index, _object3d.matrix);
1499
+ rigidBody.setTranslation(_object3d.position, false);
1500
+ rigidBody.setRotation(_object3d.quaternion, false);
1501
+ const api = createRigidBodyApi({
1502
+ current() {
1503
+ return rigidBody;
1241
1504
  }
1242
1505
 
1243
- const rigidBody = world.createRigidBody(rigidBodyDesc);
1244
- const matrix = new three.Matrix4();
1245
- mesh.getMatrixAt(index, matrix);
1246
- const {
1247
- position,
1248
- rotation
1249
- } = decomposeMatrix4(matrix);
1250
-
1251
- if (props.colliders !== false) {
1252
- const colliderDesc = colliderDescFromGeometry(mesh.geometry, props.colliders !== undefined ? props.colliders : physicsOptions.colliders, scale, false // Collisions currently not enabled for instances
1253
- );
1254
- const collider = world.createCollider(colliderDesc, rigidBody);
1255
- colliders.push(collider);
1256
- } // Set positions
1257
-
1258
-
1259
- if (props.positions && props.positions[index]) {
1260
- rigidBody.setTranslation(vectorArrayToVector3(props.positions[index]), true);
1261
- } else {
1262
- rigidBody.setTranslation(position, true);
1263
- } // Set rotations
1264
-
1265
-
1266
- if (props.rotations && props.rotations[index]) {
1267
- const [x, y, z] = props.rotations[index];
1268
- rigidBody.setRotation(vector3ToQuaternion(new three.Vector3(x, y, z)), true);
1269
- } else {
1270
- rigidBody.setRotation(rotation, true);
1271
- }
1272
-
1273
- rigidBodyStates.set(rigidBody.handle, {
1274
- mesh: mesh,
1275
- isSleeping: false,
1276
- invertedMatrixWorld: object.current.matrixWorld.clone().invert(),
1277
- setMatrix: matrix => mesh.setMatrixAt(index, matrix),
1278
- getMatrix: () => {
1279
- const m = new three.Matrix4();
1280
- mesh.getMatrixAt(index, m);
1281
- return m;
1282
- },
1283
- // Setting the world scale to the scale here, because
1284
- // we want the scales to be reflected by instance
1285
- worldScale: scale
1286
- });
1287
- const api = createRigidBodyApi({
1288
- current() {
1289
- return rigidBody;
1290
- }
1291
-
1292
- });
1293
- rigidBodies.push({
1294
- rigidBody,
1295
- api
1296
- });
1297
- }
1298
- }
1299
-
1300
- if (mesh.type === "Mesh" && !("isInstancedMesh" in mesh)) {
1301
- console.warn("Can only use InstancedMesh inside <InstancedRigidBodies />, Mesh will be ignored.");
1506
+ });
1507
+ rigidBodies.push({
1508
+ rigidBody,
1509
+ api
1510
+ });
1302
1511
  }
1512
+ }
1513
+ });
1514
+ return () => {
1515
+ rigidBodies.forEach(rb => {
1516
+ world.removeRigidBody(rb.rigidBody);
1517
+ rigidBodyStates.delete(rb.rigidBody.handle);
1303
1518
  });
1304
- return () => {
1305
- rigidBodies.forEach(rb => world.removeRigidBody(rb.rigidBody));
1306
- colliders.forEach(coll => world.removeCollider(coll));
1307
- instancesRef.current = undefined;
1308
- };
1309
- }
1519
+ instancesRef.current = [];
1520
+ };
1310
1521
  }, []);
1311
1522
  const api = React.useMemo(() => createInstancedRigidBodiesApi(instancesRefGetter), []);
1312
- React.useImperativeHandle(ref, () => api); // console.log(api);
1313
-
1523
+ React.useImperativeHandle(ref, () => api);
1524
+ useUpdateRigidBodyOptions({
1525
+ current: instancesRef.current.map(({
1526
+ rigidBody
1527
+ }) => rigidBody)
1528
+ }, mergedOptions, rigidBodyStates, false);
1529
+ useRigidBodyEvents({
1530
+ current: instancesRef.current.map(({
1531
+ rigidBody
1532
+ }) => rigidBody)
1533
+ }, mergedOptions, rigidBodyEvents);
1314
1534
  return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
1315
1535
  value: {
1316
1536
  ref: object,
1317
1537
  api,
1318
- hasCollisionEvents: false,
1319
1538
  options: props
1320
1539
  }
1321
1540
  }, /*#__PURE__*/React__default["default"].createElement("object3D", {
1322
1541
  ref: object
1323
- }, props.children));
1542
+ }, props.children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({
1543
+ key: index
1544
+ }, colliderProps)))));
1324
1545
  });
1325
1546
 
1326
- const _excluded = ["children", "onCollisionEnter", "onCollisionExit"];
1327
-
1328
- const AnyCollider = _ref => {
1329
- let {
1330
- children,
1331
- onCollisionEnter,
1332
- onCollisionExit
1333
- } = _ref,
1334
- props = _objectWithoutProperties(_ref, _excluded);
1335
-
1336
- const {
1337
- world,
1338
- colliderEvents
1339
- } = useRapier();
1340
- const rigidBodyContext = useRigidBodyContext();
1341
- const ref = React.useRef(null);
1342
- React.useEffect(() => {
1343
- const scale = ref.current.getWorldScale(new three.Vector3());
1344
- const colliders = [];
1345
- const hasCollisionEvents = (rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.hasCollisionEvents) || !!onCollisionEnter || !!onCollisionExit; // If this is an InstancedRigidBody api
1346
-
1347
- if (rigidBodyContext && "at" in rigidBodyContext.api) {
1348
- rigidBodyContext.api.forEach((body, index) => {
1349
- var _rigidBodyContext$opt, _rigidBodyContext$opt2;
1350
-
1351
- let instanceScale = scale.clone();
1352
-
1353
- if ("scales" in rigidBodyContext.options && rigidBodyContext !== null && rigidBodyContext !== void 0 && (_rigidBodyContext$opt = rigidBodyContext.options) !== null && _rigidBodyContext$opt !== void 0 && (_rigidBodyContext$opt2 = _rigidBodyContext$opt.scales) !== null && _rigidBodyContext$opt2 !== void 0 && _rigidBodyContext$opt2[index]) {
1354
- instanceScale.multiply(vectorArrayToVector3(rigidBodyContext.options.scales[index]));
1355
- }
1356
-
1357
- colliders.push(createColliderFromOptions({
1358
- options: _objectSpread2({
1359
- solverGroups: rigidBodyContext.options.solverGroups,
1360
- collisionGroups: rigidBodyContext.options.collisionGroups
1361
- }, props),
1362
- world,
1363
- rigidBody: body.raw(),
1364
- scale: instanceScale,
1365
- hasCollisionEvents
1366
- }));
1367
- });
1368
- } else {
1369
- colliders.push(createColliderFromOptions({
1370
- options: _objectSpread2({
1371
- solverGroups: (rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options.solverGroups) || props.solverGroups,
1372
- collisionGroups: (rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options.collisionGroups) || props.collisionGroups
1373
- }, props),
1374
- world,
1375
- // Initiate with a rigidbody, or undefined, because colliders can exist without a rigid body
1376
- rigidBody: rigidBodyContext && "raw" in rigidBodyContext.api ? rigidBodyContext.api.raw() : undefined,
1377
- scale,
1378
- hasCollisionEvents
1379
- }));
1380
- }
1381
- /* Register collision events. */
1382
-
1383
-
1384
- colliders.forEach(collider => colliderEvents.set(collider.handle, {
1385
- onCollisionEnter,
1386
- onCollisionExit
1387
- }));
1388
- return () => {
1389
- colliders.forEach(collider => {
1390
- colliderEvents.delete(collider.handle);
1391
- world.removeCollider(collider);
1392
- });
1393
- };
1394
- }, []);
1395
- return /*#__PURE__*/React__default["default"].createElement("object3D", {
1396
- ref: ref
1397
- }, children);
1398
- };
1399
-
1400
- const CuboidCollider = props => {
1401
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1402
- shape: "cuboid"
1403
- }));
1404
- };
1405
- const RoundCuboidCollider = props => {
1406
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1407
- shape: "roundCuboid"
1408
- }));
1409
- };
1410
- const BallCollider = props => {
1411
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1412
- shape: "ball"
1413
- }));
1414
- };
1415
- const CapsuleCollider = props => {
1416
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1417
- shape: "capsule"
1418
- }));
1419
- };
1420
- const HeightfieldCollider = props => {
1421
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1422
- shape: "heightfield"
1423
- }));
1424
- };
1425
- const TrimeshCollider = props => {
1426
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1427
- shape: "trimesh"
1428
- }));
1429
- };
1430
- const ConeCollider = props => {
1431
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1432
- shape: "cone"
1433
- }));
1434
- };
1435
- const CylinderCollider = props => {
1436
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1437
- shape: "cylinder"
1438
- }));
1439
- };
1440
- const ConvexHullCollider = props => {
1441
- return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1442
- shape: "convexHull"
1443
- }));
1444
- };
1445
-
1446
1547
  /**
1447
1548
  * Calculates an InteractionGroup bitmask for use in the `collisionGroups` or `solverGroups`
1448
1549
  * properties of RigidBody or Collider components. The first argument represents a list of
@@ -1491,6 +1592,7 @@ Object.defineProperty(exports, 'RapierRigidBody', {
1491
1592
  enumerable: true,
1492
1593
  get: function () { return rapier3dCompat.RigidBody; }
1493
1594
  });
1595
+ exports.AnyCollider = AnyCollider;
1494
1596
  exports.BallCollider = BallCollider;
1495
1597
  exports.CapsuleCollider = CapsuleCollider;
1496
1598
  exports.ConeCollider = ConeCollider;
@@ -1506,6 +1608,7 @@ exports.RigidBody = RigidBody;
1506
1608
  exports.RoundCuboidCollider = RoundCuboidCollider;
1507
1609
  exports.TrimeshCollider = TrimeshCollider;
1508
1610
  exports.interactionGroups = interactionGroups;
1611
+ exports.useChildColliderProps = useChildColliderProps;
1509
1612
  exports.useFixedJoint = useFixedJoint;
1510
1613
  exports.useImpulseJoint = useImpulseJoint;
1511
1614
  exports.usePrismaticJoint = usePrismaticJoint;