@react-three/rapier 0.6.9 → 0.7.0

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,151 +575,450 @@ 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
783
-
784
- React.useEffect(() => {
785
- var _ref$current$parent, _ref, _options$colliders;
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) => {
640
+ if (!rigidBody) {
641
+ return;
642
+ }
786
643
 
787
- const rigidBody = getRigidBodyRef.current();
788
- rigidBodyRef.current = rigidBody;
644
+ const state = states.get(rigidBody.handle);
789
645
 
790
- if (!ref.current) {
791
- ref.current = new three.Object3D();
792
- } // isSleeping used for onSleep and onWake events
646
+ if (state) {
647
+ state.object.updateWorldMatrix(true, false);
793
648
 
649
+ _matrix4.copy(state.object.matrixWorld).decompose(_position, _rotation, _scale);
794
650
 
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
651
+ rigidBody.setTranslation(_position, false);
652
+ rigidBody.setRotation(_rotation, false);
653
+ mutableRigidBodyOptionKeys.forEach(key => {
654
+ if (key in options) {
655
+ mutableRigidBodyOptions[key](rigidBody, options[key]);
656
+ }
839
657
  });
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
-
658
+ }
659
+ };
660
+ const useUpdateRigidBodyOptions = (rigidBodyRef, props, states) => {
849
661
  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) => {
662
+ setRigidBodyOptions(rigidBodyRef.current, props, states);
663
+ }, [props]);
664
+ };
665
+ const useRigidBodyEvents = (rigidBodyRef, props, events) => {
866
666
  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
- }
881
- }
882
-
883
- return jointRef.current;
884
- });
667
+ onWake,
668
+ onSleep,
669
+ onCollisionEnter,
670
+ onCollisionExit,
671
+ onIntersectionEnter,
672
+ onIntersectionExit
673
+ } = props;
885
674
  React.useEffect(() => {
886
- const joint = getJointRef.current();
675
+ events.set(rigidBodyRef.current.handle, {
676
+ onWake,
677
+ onSleep,
678
+ onCollisionEnter,
679
+ onCollisionExit,
680
+ onIntersectionEnter,
681
+ onIntersectionExit
682
+ });
887
683
  return () => {
888
- if (joint) {
889
- world.removeImpulseJoint(joint);
890
- jointRef.current = undefined;
891
- }
684
+ events.delete(rigidBodyRef.current.handle);
892
685
  };
893
- }, []);
894
- const api = React.useMemo(() => createJointApi(getJointRef), []);
895
- return api;
686
+ }, [onWake, onSleep, onCollisionEnter, onCollisionExit]);
896
687
  };
897
- /**
898
- *
899
- * A fixed joint ensures that two rigid-bodies don't move relative to each other.
900
- * Fixed joints are characterized by one local frame (represented by an isometry) on each rigid-body.
901
- * The fixed-joint makes these frames coincide in world-space.
902
- */
903
688
 
904
- const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor, body2LocalFrame]) => {
905
- const {
689
+ const scaleColliderArgs = (shape, args, scale) => {
690
+ const newArgs = args.slice(); // Heightfield uses a vector
691
+
692
+ if (shape === "heightfield") {
693
+ const s = newArgs[3];
694
+ s.x *= scale.x;
695
+ s.x *= scale.y;
696
+ s.x *= scale.z;
697
+ return newArgs;
698
+ } // Trimesh and convex scale the vertices
699
+
700
+
701
+ if (shape === "trimesh" || shape === "convexHull") {
702
+ newArgs[0] = scaleVertices(newArgs[0], scale);
703
+ return newArgs;
704
+ } // Prepfill with some extra
705
+
706
+
707
+ const scaleArray = [scale.x, scale.y, scale.z, scale.x, scale.x];
708
+ return newArgs.map((arg, index) => scaleArray[index] * arg);
709
+ };
710
+ const createColliderFromOptions = (options, world, scale, rigidBody) => {
711
+ const scaledArgs = scaleColliderArgs(options.shape, options.args, scale); // @ts-ignore
712
+
713
+ const desc = rapier3dCompat.ColliderDesc[options.shape](...scaledArgs);
714
+ return world.createCollider(desc, rigidBody);
715
+ };
716
+ const mutableColliderOptions = {
717
+ sensor: (collider, value) => {
718
+ collider.setSensor(value);
719
+ },
720
+ collisionGroups: (collider, value) => {
721
+ collider.setCollisionGroups(value);
722
+ },
723
+ solverGroups: (collider, value) => {
724
+ collider.setSolverGroups(value);
725
+ },
726
+ friction: (collider, value) => {
727
+ collider.setFriction(value);
728
+ },
729
+ restitution: (collider, value) => {
730
+ collider.setRestitution(value);
731
+ },
732
+ density: (collider, value) => {
733
+ collider.setDensity(value);
734
+ },
735
+ mass: (collider, value) => {
736
+ collider.setMass(value);
737
+ }
738
+ };
739
+ const mutableColliderOptionKeys = Object.keys(mutableColliderOptions);
740
+ const setColliderOptions = (collider, options, states) => {
741
+ const state = states.get(collider.handle);
742
+
743
+ if (state) {
744
+ // Update collider position based on the object's position
745
+ const parentWorldScale = state.object.parent.getWorldScale(_vector3);
746
+ state.object.updateWorldMatrix(true, false);
747
+
748
+ _matrix4.copy(state.object.matrixWorld).premultiply(state.worldParent.matrixWorld.clone().invert()).decompose(_position, _rotation, _scale);
749
+
750
+ collider.setTranslationWrtParent({
751
+ x: _position.x * parentWorldScale.x,
752
+ y: _position.y * parentWorldScale.y,
753
+ z: _position.z * parentWorldScale.z
754
+ });
755
+ collider.setRotationWrtParent(_rotation);
756
+ mutableColliderOptionKeys.forEach(key => {
757
+ if (key in options) {
758
+ mutableColliderOptions[key](collider, options[key]);
759
+ }
760
+ });
761
+ }
762
+ };
763
+ const useUpdateColliderOptions = (collidersRef, props, states) => {
764
+ React.useEffect(() => {
765
+ collidersRef.current.forEach(collider => {
766
+ setColliderOptions(collider, props, states);
767
+ });
768
+ }, [props]);
769
+ };
770
+
771
+ const isChildOfMeshCollider = child => {
772
+ let flag = false;
773
+ child.traverseAncestors(a => {
774
+ if (a.userData.r3RapierType === "MeshCollider") flag = true;
775
+ });
776
+ return flag;
777
+ };
778
+
779
+ const createColliderState = (collider, object, rigidBodyObject) => {
780
+ return {
781
+ collider,
782
+ worldParent: rigidBodyObject || object.parent,
783
+ object
784
+ };
785
+ };
786
+ const autoColliderMap = {
787
+ cuboid: "cuboid",
788
+ ball: "ball",
789
+ hull: "convexHull",
790
+ trimesh: "trimesh"
791
+ };
792
+ const createColliderPropsFromChildren = ({
793
+ object,
794
+ ignoreMeshColliders: _ignoreMeshColliders = true,
795
+ options
796
+ }) => {
797
+ const colliderProps = [];
798
+ object.updateWorldMatrix(true, false);
799
+ const invertedParentMatrixWorld = object.matrixWorld.clone().invert();
800
+ object.traverseVisible(child => {
801
+ if ("isMesh" in child) {
802
+ if (_ignoreMeshColliders && isChildOfMeshCollider(child)) return;
803
+ const worldScale = child.getWorldScale(_scale);
804
+ const shape = autoColliderMap[options.colliders || "cuboid"];
805
+ child.updateWorldMatrix(true, false);
806
+
807
+ _matrix4.copy(child.matrixWorld).premultiply(invertedParentMatrixWorld).decompose(_position, _rotation, _scale);
808
+
809
+ const rotationEuler = new three.Euler().setFromQuaternion(_rotation, "XYZ");
810
+ const {
811
+ geometry
812
+ } = child;
813
+ const {
814
+ args,
815
+ offset
816
+ } = getColliderArgsFromGeometry(geometry, options.colliders || "cuboid");
817
+ colliderProps.push(_objectSpread2(_objectSpread2({}, options), {}, {
818
+ args: args,
819
+ shape: shape,
820
+ rotation: [rotationEuler.x, rotationEuler.y, rotationEuler.z],
821
+ position: [_position.x + offset.x * worldScale.x, _position.y + offset.y * worldScale.y, _position.z + offset.z * worldScale.z],
822
+ scale: [worldScale.x, worldScale.y, worldScale.z]
823
+ }));
824
+ }
825
+ });
826
+ return colliderProps;
827
+ };
828
+ const getColliderArgsFromGeometry = (geometry, colliders) => {
829
+ switch (colliders) {
830
+ case "cuboid":
831
+ {
832
+ geometry.computeBoundingBox();
833
+ const {
834
+ boundingBox
835
+ } = geometry;
836
+ const size = boundingBox.getSize(new three.Vector3());
837
+ return {
838
+ args: [size.x / 2, size.y / 2, size.z / 2],
839
+ offset: boundingBox.getCenter(new three.Vector3())
840
+ };
841
+ }
842
+
843
+ case "ball":
844
+ {
845
+ geometry.computeBoundingSphere();
846
+ const {
847
+ boundingSphere
848
+ } = geometry;
849
+ const radius = boundingSphere.radius;
850
+ return {
851
+ args: [radius],
852
+ offset: boundingSphere.center
853
+ };
854
+ }
855
+
856
+ case "trimesh":
857
+ {
858
+ var _clonedGeometry$index;
859
+
860
+ const clonedGeometry = geometry.index ? geometry.clone() : threeStdlib.mergeVertices(geometry);
861
+ return {
862
+ args: [clonedGeometry.attributes.position.array, (_clonedGeometry$index = clonedGeometry.index) === null || _clonedGeometry$index === void 0 ? void 0 : _clonedGeometry$index.array],
863
+ offset: new three.Vector3()
864
+ };
865
+ }
866
+
867
+ case "hull":
868
+ {
869
+ const g = geometry.clone();
870
+ return {
871
+ args: [g.attributes.position.array],
872
+ offset: new three.Vector3()
873
+ };
874
+ }
875
+ }
876
+
877
+ return {
878
+ args: [],
879
+ offset: new three.Vector3()
880
+ };
881
+ };
882
+ const useColliderEvents = (collidersRef, props, events) => {
883
+ const {
884
+ onCollisionEnter,
885
+ onCollisionExit,
886
+ onIntersectionEnter,
887
+ onIntersectionExit
888
+ } = props;
889
+ React.useEffect(() => {
890
+ var _collidersRef$current;
891
+
892
+ (_collidersRef$current = collidersRef.current) === null || _collidersRef$current === void 0 ? void 0 : _collidersRef$current.forEach(collider => {
893
+ if (onCollisionEnter || onCollisionExit || onIntersectionEnter || onIntersectionExit) {
894
+ collider.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
895
+ }
896
+
897
+ events.set(collider.handle, {
898
+ onCollisionEnter,
899
+ onCollisionExit,
900
+ onIntersectionEnter,
901
+ onIntersectionExit
902
+ });
903
+ });
904
+ return () => {
905
+ var _collidersRef$current2;
906
+
907
+ (_collidersRef$current2 = collidersRef.current) === null || _collidersRef$current2 === void 0 ? void 0 : _collidersRef$current2.forEach(collider => events.delete(collider.handle));
908
+ };
909
+ }, [onCollisionEnter, onCollisionExit]);
910
+ };
911
+
912
+ const useRapier = () => {
913
+ return React.useContext(RapierContext);
914
+ };
915
+ const useChildColliderProps = (ref, options, ignoreMeshColliders = true) => {
916
+ const [colliderProps, setColliderProps] = React.useState([]);
917
+ React.useEffect(() => {
918
+ const object = ref.current;
919
+
920
+ if (object && options.colliders !== false) {
921
+ setColliderProps(createColliderPropsFromChildren({
922
+ object: ref.current,
923
+ options,
924
+ ignoreMeshColliders
925
+ }));
926
+ }
927
+ }, [options]);
928
+ return colliderProps;
929
+ };
930
+ const useRigidBody = (options = {}) => {
931
+ const {
932
+ world,
933
+ rigidBodyStates,
934
+ physicsOptions,
935
+ rigidBodyEvents
936
+ } = useRapier();
937
+ const ref = React.useRef();
938
+ const mergedOptions = React.useMemo(() => {
939
+ return _objectSpread2(_objectSpread2(_objectSpread2({}, physicsOptions), options), {}, {
940
+ children: undefined
941
+ });
942
+ }, [physicsOptions, options]);
943
+ const childColliderProps = useChildColliderProps(ref, mergedOptions); // Create rigidbody
944
+
945
+ const rigidBodyRef = React.useRef();
946
+ const getRigidBodyRef = React.useRef(() => {
947
+ if (!rigidBodyRef.current) {
948
+ const desc = rigidBodyDescFromOptions(options);
949
+ const rigidBody = world.createRigidBody(desc);
950
+ rigidBodyRef.current = world.getRigidBody(rigidBody.handle);
951
+ }
952
+
953
+ return rigidBodyRef.current;
954
+ }); // Setup
955
+
956
+ React.useEffect(() => {
957
+ const rigidBody = getRigidBodyRef.current();
958
+ rigidBodyRef.current = rigidBody;
959
+
960
+ if (!ref.current) {
961
+ ref.current = new three.Object3D();
962
+ } // isSleeping used for onSleep and onWake events
963
+
964
+
965
+ ref.current.userData.isSleeping = false;
966
+ rigidBodyStates.set(rigidBody.handle, createRigidBodyState({
967
+ rigidBody,
968
+ object: ref.current
969
+ }));
970
+ return () => {
971
+ world.removeRigidBody(rigidBody);
972
+ rigidBodyStates.delete(rigidBody.handle);
973
+ };
974
+ }, []);
975
+ useUpdateRigidBodyOptions(rigidBodyRef, mergedOptions, rigidBodyStates);
976
+ useRigidBodyEvents(rigidBodyRef, mergedOptions, rigidBodyEvents);
977
+ const api = React.useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
978
+ return [ref, api, childColliderProps];
979
+ }; // Joints
980
+
981
+ const useImpulseJoint = (body1, body2, params) => {
982
+ const {
983
+ world
984
+ } = useRapier();
985
+ const jointRef = React.useRef();
986
+ const getJointRef = React.useRef(() => {
987
+ if (!jointRef.current) {
988
+ let rb1;
989
+ let rb2;
990
+
991
+ if ("current" in body1 && body1.current && "current" in body2 && body2.current) {
992
+ rb1 = world.getRigidBody(body1.current.handle);
993
+ rb2 = world.getRigidBody(body2.current.handle);
994
+ const newJoint = world.createImpulseJoint(params, rb1, rb2);
995
+ jointRef.current = newJoint;
996
+ }
997
+ }
998
+
999
+ return jointRef.current;
1000
+ });
1001
+ React.useEffect(() => {
1002
+ const joint = getJointRef.current();
1003
+ return () => {
1004
+ if (joint) {
1005
+ world.removeImpulseJoint(joint);
1006
+ jointRef.current = undefined;
1007
+ }
1008
+ };
1009
+ }, []);
1010
+ const api = React.useMemo(() => createJointApi(getJointRef), []);
1011
+ return api;
1012
+ };
1013
+ /**
1014
+ *
1015
+ * A fixed joint ensures that two rigid-bodies don't move relative to each other.
1016
+ * Fixed joints are characterized by one local frame (represented by an isometry) on each rigid-body.
1017
+ * The fixed-joint makes these frames coincide in world-space.
1018
+ */
1019
+
1020
+ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor, body2LocalFrame]) => {
1021
+ const {
906
1022
  rapier
907
1023
  } = useRapier();
908
1024
  return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToVector3(body1Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body1LocalFrame)), {}, {
@@ -949,80 +1065,173 @@ const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
949
1065
  return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
950
1066
  };
951
1067
 
952
- const _excluded$1 = ["children"],
953
- _excluded2 = ["type", "position", "rotation"];
954
- const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
955
- const useRigidBodyContext = () => React.useContext(RigidBodyContext); // RigidBody
1068
+ // Colliders
1069
+ const AnyCollider = /*#__PURE__*/React.memo(props => {
1070
+ const {
1071
+ children,
1072
+ position,
1073
+ rotation,
1074
+ quaternion,
1075
+ scale
1076
+ } = props;
1077
+ const {
1078
+ world,
1079
+ colliderEvents,
1080
+ colliderStates
1081
+ } = useRapier();
1082
+ const rigidBodyContext = useRigidBodyContext();
1083
+ const ref = React.useRef(null);
1084
+ const collidersRef = React.useRef([]);
1085
+ React.useEffect(() => {
1086
+ const object = ref.current;
1087
+ const worldScale = object.getWorldScale(new three.Vector3());
1088
+ const colliders = []; // If this is an InstancedRigidBody api
956
1089
 
957
- const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
958
- let {
959
- children
960
- } = _ref,
961
- props = _objectWithoutProperties(_ref, _excluded$1);
1090
+ if (rigidBodyContext && "at" in rigidBodyContext.api) {
1091
+ rigidBodyContext.api.forEach((body, index) => {
1092
+ var _rigidBodyContext$opt, _rigidBodyContext$opt2;
1093
+
1094
+ let instanceScale = worldScale;
1095
+
1096
+ 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]) {
1097
+ instanceScale = instanceScale.clone().multiply(vectorArrayToVector3(rigidBodyContext.options.scales[index]));
1098
+ }
962
1099
 
963
- const [object, api] = useRigidBody(props);
1100
+ const collider = createColliderFromOptions(props, world, instanceScale, body.raw());
1101
+ colliderStates.set(collider.handle, createColliderState(collider, object, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
1102
+ colliders.push(collider);
1103
+ });
1104
+ } else {
1105
+ const collider = createColliderFromOptions(props, world, worldScale, rigidBodyContext && (rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.api).raw());
1106
+ colliderStates.set(collider.handle, createColliderState(collider, object, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
1107
+ colliders.push(collider);
1108
+ }
1109
+
1110
+ collidersRef.current = colliders;
1111
+ return () => {
1112
+ colliders.forEach(collider => {
1113
+ world.removeCollider(collider);
1114
+ });
1115
+ };
1116
+ }, []);
1117
+ useUpdateColliderOptions(collidersRef, props, colliderStates);
1118
+ useColliderEvents(collidersRef, props, colliderEvents);
1119
+ return /*#__PURE__*/React__default["default"].createElement("object3D", {
1120
+ position: position,
1121
+ rotation: rotation,
1122
+ quaternion: quaternion,
1123
+ scale: scale,
1124
+ ref: ref
1125
+ }, children);
1126
+ });
1127
+ const CuboidCollider = props => {
1128
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1129
+ shape: "cuboid"
1130
+ }));
1131
+ };
1132
+ const RoundCuboidCollider = props => {
1133
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1134
+ shape: "roundCuboid"
1135
+ }));
1136
+ };
1137
+ const BallCollider = props => {
1138
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1139
+ shape: "ball"
1140
+ }));
1141
+ };
1142
+ const CapsuleCollider = props => {
1143
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1144
+ shape: "capsule"
1145
+ }));
1146
+ };
1147
+ const HeightfieldCollider = props => {
1148
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1149
+ shape: "heightfield"
1150
+ }));
1151
+ };
1152
+ const TrimeshCollider = props => {
1153
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1154
+ shape: "trimesh"
1155
+ }));
1156
+ };
1157
+ const ConeCollider = props => {
1158
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1159
+ shape: "cone"
1160
+ }));
1161
+ };
1162
+ const CylinderCollider = props => {
1163
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1164
+ shape: "cylinder"
1165
+ }));
1166
+ };
1167
+ const ConvexHullCollider = props => {
1168
+ return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
1169
+ shape: "convexHull"
1170
+ }));
1171
+ };
964
1172
 
965
- const objectProps = _objectWithoutProperties(props, _excluded2);
1173
+ const _excluded$1 = ["children", "type", "position", "rotation", "scale", "quaternion"];
1174
+ const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
1175
+ const useRigidBodyContext = () => React.useContext(RigidBodyContext);
1176
+ const RigidBody = /*#__PURE__*/React.forwardRef((props, ref) => {
1177
+ const {
1178
+ children,
1179
+ type,
1180
+ position,
1181
+ rotation,
1182
+ scale,
1183
+ quaternion
1184
+ } = props,
1185
+ objectProps = _objectWithoutProperties(props, _excluded$1);
966
1186
 
1187
+ const [object, api, childColliderProps] = useRigidBody(props);
967
1188
  React.useImperativeHandle(ref, () => api);
968
1189
  return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
969
1190
  value: {
970
1191
  ref: object,
971
1192
  api,
972
- hasCollisionEvents: !!(props.onCollisionEnter || props.onCollisionExit),
973
1193
  options: props
974
1194
  }
975
1195
  }, /*#__PURE__*/React__default["default"].createElement("object3D", _extends({
976
1196
  ref: object
977
- }, objectProps), children));
1197
+ }, objectProps, {
1198
+ position: position,
1199
+ rotation: rotation,
1200
+ quaternion: quaternion,
1201
+ scale: scale
1202
+ }), children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({
1203
+ key: index
1204
+ }, colliderProps)))));
978
1205
  });
979
1206
 
980
- const MeshCollider = ({
981
- children,
982
- type
983
- }) => {
1207
+ const MeshCollider = props => {
1208
+ const {
1209
+ children,
1210
+ type
1211
+ } = props;
984
1212
  const {
985
1213
  physicsOptions,
986
1214
  world
987
1215
  } = useRapier();
988
1216
  const object = React.useRef(null);
989
1217
  const {
990
- api,
991
1218
  options
992
1219
  } = 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
- }, []);
1220
+ const mergedOptions = React.useMemo(() => {
1221
+ return _objectSpread2(_objectSpread2(_objectSpread2({}, physicsOptions), options), {}, {
1222
+ children: undefined,
1223
+ colliders: type
1224
+ });
1225
+ }, [physicsOptions, options]);
1226
+ const childColliderProps = useChildColliderProps(object, mergedOptions, false);
1020
1227
  return /*#__PURE__*/React__default["default"].createElement("object3D", {
1021
1228
  ref: object,
1022
1229
  userData: {
1023
1230
  r3RapierType: "MeshCollider"
1024
1231
  }
1025
- }, children);
1232
+ }, children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({
1233
+ key: index
1234
+ }, colliderProps))));
1026
1235
  };
1027
1236
 
1028
1237
  const geometryFromCollider = collider => {
@@ -1199,6 +1408,7 @@ const Debug = ({
1199
1408
  })));
1200
1409
  };
1201
1410
 
1411
+ const _excluded = ["positions", "rotations", "children"];
1202
1412
  const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
1203
1413
  const {
1204
1414
  world,
@@ -1206,6 +1416,14 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
1206
1416
  physicsOptions
1207
1417
  } = useRapier();
1208
1418
  const object = React.useRef(null);
1419
+
1420
+ const {
1421
+ positions,
1422
+ rotations,
1423
+ children
1424
+ } = props,
1425
+ options = _objectWithoutProperties(props, _excluded);
1426
+
1209
1427
  const instancesRef = React.useRef();
1210
1428
  const instancesRefGetter = React.useRef(() => {
1211
1429
  if (!instancesRef.current) {
@@ -1214,235 +1432,85 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
1214
1432
 
1215
1433
  return instancesRef.current;
1216
1434
  });
1435
+ const mergedOptions = React.useMemo(() => {
1436
+ return _objectSpread2(_objectSpread2({}, physicsOptions), options);
1437
+ }, [physicsOptions, options]);
1438
+ const childColliderProps = useChildColliderProps(object, mergedOptions);
1217
1439
  React.useLayoutEffect(() => {
1218
- const colliders = [];
1440
+ object.current.updateWorldMatrix(true, false);
1219
1441
  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);
1442
+ const invertedWorld = object.current.matrixWorld.clone().invert();
1443
+ object.current.traverseVisible(mesh => {
1444
+ if (mesh instanceof three.InstancedMesh) {
1445
+ mesh.instanceMatrix.setUsage(three.DynamicDrawUsage);
1446
+ const worldScale = mesh.getWorldScale(_scale);
1447
+
1448
+ for (let index = 0; index < mesh.count; index++) {
1449
+ var _options$scales;
1450
+
1451
+ const desc = rigidBodyDescFromOptions(props);
1452
+ const rigidBody = world.createRigidBody(desc);
1453
+ const scale = ((_options$scales = options.scales) === null || _options$scales === void 0 ? void 0 : _options$scales[index]) || [1, 1, 1];
1454
+ const instanceScale = worldScale.clone().multiply(vectorArrayToVector3(scale));
1455
+ rigidBodyStates.set(rigidBody.handle, createRigidBodyState({
1456
+ rigidBody,
1457
+ object: mesh,
1458
+ setMatrix: matrix => mesh.setMatrixAt(index, matrix),
1459
+ getMatrix: matrix => {
1460
+ mesh.getMatrixAt(index, matrix);
1461
+ return matrix;
1462
+ },
1463
+ worldScale: instanceScale
1464
+ }));
1465
+ const [x, y, z] = (positions === null || positions === void 0 ? void 0 : positions[index]) || [0, 0, 0];
1466
+ const [rx, ry, rz] = (rotations === null || rotations === void 0 ? void 0 : rotations[index]) || [0, 0, 0];
1467
+
1468
+ _object3d.position.set(x, y, z);
1469
+
1470
+ _object3d.rotation.set(rx, ry, rz);
1471
+
1472
+ _object3d.applyMatrix4(invertedWorld); // Set initial transforms based on world transforms
1473
+ // will be replaced by the setRigidBodyOption below
1474
+
1475
+
1476
+ rigidBody.setTranslation(_object3d.position, false);
1477
+ rigidBody.setRotation(_object3d.quaternion, false);
1478
+ const api = createRigidBodyApi({
1479
+ current() {
1480
+ return rigidBody;
1241
1481
  }
1242
1482
 
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.");
1483
+ });
1484
+ rigidBodies.push({
1485
+ rigidBody,
1486
+ api
1487
+ });
1302
1488
  }
1489
+ }
1490
+ });
1491
+ return () => {
1492
+ rigidBodies.forEach(rb => {
1493
+ world.removeRigidBody(rb.rigidBody);
1494
+ rigidBodyStates.delete(rb.rigidBody.handle);
1303
1495
  });
1304
- return () => {
1305
- rigidBodies.forEach(rb => world.removeRigidBody(rb.rigidBody));
1306
- colliders.forEach(coll => world.removeCollider(coll));
1307
- instancesRef.current = undefined;
1308
- };
1309
- }
1496
+ instancesRef.current = undefined;
1497
+ };
1310
1498
  }, []);
1311
1499
  const api = React.useMemo(() => createInstancedRigidBodiesApi(instancesRefGetter), []);
1312
- React.useImperativeHandle(ref, () => api); // console.log(api);
1313
-
1500
+ React.useImperativeHandle(ref, () => api);
1314
1501
  return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
1315
1502
  value: {
1316
1503
  ref: object,
1317
1504
  api,
1318
- hasCollisionEvents: false,
1319
1505
  options: props
1320
1506
  }
1321
1507
  }, /*#__PURE__*/React__default["default"].createElement("object3D", {
1322
1508
  ref: object
1323
- }, props.children));
1509
+ }, props.children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({
1510
+ key: index
1511
+ }, colliderProps)))));
1324
1512
  });
1325
1513
 
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
1514
  /**
1447
1515
  * Calculates an InteractionGroup bitmask for use in the `collisionGroups` or `solverGroups`
1448
1516
  * properties of RigidBody or Collider components. The first argument represents a list of
@@ -1491,6 +1559,7 @@ Object.defineProperty(exports, 'RapierRigidBody', {
1491
1559
  enumerable: true,
1492
1560
  get: function () { return rapier3dCompat.RigidBody; }
1493
1561
  });
1562
+ exports.AnyCollider = AnyCollider;
1494
1563
  exports.BallCollider = BallCollider;
1495
1564
  exports.CapsuleCollider = CapsuleCollider;
1496
1565
  exports.ConeCollider = ConeCollider;
@@ -1506,6 +1575,7 @@ exports.RigidBody = RigidBody;
1506
1575
  exports.RoundCuboidCollider = RoundCuboidCollider;
1507
1576
  exports.TrimeshCollider = TrimeshCollider;
1508
1577
  exports.interactionGroups = interactionGroups;
1578
+ exports.useChildColliderProps = useChildColliderProps;
1509
1579
  exports.useFixedJoint = useFixedJoint;
1510
1580
  exports.useImpulseJoint = useImpulseJoint;
1511
1581
  exports.usePrismaticJoint = usePrismaticJoint;