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