@react-three/rapier 0.12.2 → 0.13.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.
- package/dist/declarations/src/{AnyCollider.d.ts → components/AnyCollider.d.ts} +51 -11
- package/dist/declarations/src/{Attractor.d.ts → components/Attractor.d.ts} +0 -0
- package/dist/declarations/src/{Debug.d.ts → components/Debug.d.ts} +0 -0
- package/dist/declarations/src/components/InstancedRigidBodies.d.ts +12 -0
- package/dist/declarations/src/{MeshCollider.d.ts → components/MeshCollider.d.ts} +5 -1
- package/dist/declarations/src/{Physics.d.ts → components/Physics.d.ts} +10 -3
- package/dist/declarations/src/{RigidBody.d.ts → components/RigidBody.d.ts} +10 -8
- package/dist/declarations/src/{hooks.d.ts → hooks/hooks.d.ts} +17 -5
- package/dist/declarations/src/{joints.d.ts → hooks/joints.d.ts} +19 -8
- package/dist/declarations/src/hooks/use-imperative-instance.d.ts +4 -0
- package/dist/declarations/src/index.d.ts +18 -17
- package/dist/declarations/src/types.d.ts +10 -10
- package/dist/declarations/src/utils/api.d.ts +18 -0
- package/dist/declarations/src/{interaction-groups.d.ts → utils/interaction-groups.d.ts} +0 -0
- package/dist/declarations/src/{shared-objects.d.ts → utils/shared-objects.d.ts} +0 -0
- package/dist/declarations/src/utils/three-object-helpers.d.ts +29 -0
- package/dist/declarations/src/{utils-collider.d.ts → utils/utils-collider.d.ts} +6 -7
- package/dist/declarations/src/{utils-rigidbody.d.ts → utils/utils-rigidbody.d.ts} +6 -6
- package/dist/declarations/src/{utils.d.ts → utils/utils.d.ts} +2 -2
- package/dist/react-three-rapier.cjs.dev.js +546 -589
- package/dist/react-three-rapier.cjs.prod.js +546 -589
- package/dist/react-three-rapier.esm.js +547 -593
- package/package.json +12 -12
- package/readme.md +165 -52
- package/dist/declarations/src/InstancedRigidBodies.d.ts +0 -10
- package/dist/declarations/src/api.d.ts +0 -179
@@ -1,8 +1,8 @@
|
|
1
|
-
import { ColliderDesc,
|
1
|
+
import { ActiveEvents, ColliderDesc, EventQueue, RigidBodyDesc } from '@dimforge/rapier3d-compat';
|
2
2
|
export { CoefficientCombineRule, Collider as RapierCollider, RigidBody as RapierRigidBody } from '@dimforge/rapier3d-compat';
|
3
3
|
import { useFrame, useThree } from '@react-three/fiber';
|
4
|
-
import React, { useRef, useMemo, useEffect, useContext, useState, memo, createContext, useCallback, forwardRef, useImperativeHandle,
|
5
|
-
import { Quaternion, Euler, Vector3, Object3D, Matrix4, MathUtils,
|
4
|
+
import React, { useRef, useMemo, useEffect, useContext, useState, memo, createContext, useCallback, forwardRef, useImperativeHandle, Fragment } from 'react';
|
5
|
+
import { Quaternion, Euler, Vector3, Object3D, Matrix4, MathUtils, BufferAttribute, DynamicDrawUsage } from 'three';
|
6
6
|
import { useAsset } from 'use-asset';
|
7
7
|
import { mergeVertices, VertexNormalsHelper } from 'three-stdlib';
|
8
8
|
|
@@ -47,10 +47,44 @@ function _objectSpread2(target) {
|
|
47
47
|
return target;
|
48
48
|
}
|
49
49
|
|
50
|
+
const createWorldApi = ref => {
|
51
|
+
return {
|
52
|
+
raw: () => ref.current(),
|
53
|
+
getCollider: handle => ref.current().getCollider(handle),
|
54
|
+
getRigidBody: handle => ref.current().getRigidBody(handle),
|
55
|
+
createRigidBody: desc => ref.current().createRigidBody(desc),
|
56
|
+
createCollider: (desc, rigidBody) => ref.current().createCollider(desc, rigidBody),
|
57
|
+
removeRigidBody: rigidBody => {
|
58
|
+
if (!ref.current().bodies.contains(rigidBody.handle)) return;
|
59
|
+
ref.current().removeRigidBody(rigidBody);
|
60
|
+
},
|
61
|
+
removeCollider: (collider, wakeUp = true) => {
|
62
|
+
if (!ref.current().colliders.contains(collider.handle)) return;
|
63
|
+
ref.current().removeCollider(collider, wakeUp);
|
64
|
+
},
|
65
|
+
createImpulseJoint: (params, rigidBodyA, rigidBodyB, wakeUp = true) => ref.current().createImpulseJoint(params, rigidBodyA, rigidBodyB, wakeUp),
|
66
|
+
removeImpulseJoint: (joint, wakeUp = true) => {
|
67
|
+
if (!ref.current().impulseJoints.contains(joint.handle)) return;
|
68
|
+
ref.current().removeImpulseJoint(joint, wakeUp);
|
69
|
+
},
|
70
|
+
forEachCollider: callback => ref.current().forEachCollider(callback),
|
71
|
+
setGravity: ({
|
72
|
+
x,
|
73
|
+
y,
|
74
|
+
z
|
75
|
+
}) => ref.current().gravity = {
|
76
|
+
x,
|
77
|
+
y,
|
78
|
+
z
|
79
|
+
},
|
80
|
+
debugRender: () => ref.current().debugRender()
|
81
|
+
};
|
82
|
+
};
|
83
|
+
|
50
84
|
const _quaternion = new Quaternion();
|
51
85
|
new Euler();
|
52
86
|
const _vector3 = new Vector3();
|
53
|
-
|
87
|
+
new Object3D();
|
54
88
|
const _matrix4 = new Matrix4();
|
55
89
|
const _position = new Vector3();
|
56
90
|
const _rotation = new Quaternion();
|
@@ -66,11 +100,6 @@ const tupleToObject = (tuple, keys) => {
|
|
66
100
|
return obj;
|
67
101
|
}, {});
|
68
102
|
};
|
69
|
-
const rapierVector3ToVector3 = ({
|
70
|
-
x,
|
71
|
-
y,
|
72
|
-
z
|
73
|
-
}) => _vector3.set(x, y, z);
|
74
103
|
const rapierQuaternionToQuaternion = ({
|
75
104
|
x,
|
76
105
|
y,
|
@@ -124,152 +153,6 @@ function useConst(initialValue) {
|
|
124
153
|
return ref.current.value;
|
125
154
|
}
|
126
155
|
|
127
|
-
const createRigidBodyApi = ref => {
|
128
|
-
return {
|
129
|
-
raw: () => ref.current(),
|
130
|
-
|
131
|
-
get handle() {
|
132
|
-
return ref.current().handle;
|
133
|
-
},
|
134
|
-
|
135
|
-
mass: () => ref.current().mass(),
|
136
|
-
|
137
|
-
applyImpulse(impulseVector, wakeUp = true) {
|
138
|
-
ref.current().applyImpulse(impulseVector, wakeUp);
|
139
|
-
},
|
140
|
-
|
141
|
-
applyTorqueImpulse(torqueVector, wakeUp = true) {
|
142
|
-
ref.current().applyTorqueImpulse(torqueVector, wakeUp);
|
143
|
-
},
|
144
|
-
|
145
|
-
applyImpulseAtPoint: (impulseVector, impulsePoint, wakeUp = true) => ref.current().applyImpulseAtPoint(impulseVector, impulsePoint, wakeUp),
|
146
|
-
addForce: (force, wakeUp = true) => ref.current().addForce(force, wakeUp),
|
147
|
-
addForceAtPoint: (force, point, wakeUp = true) => ref.current().addForceAtPoint(force, point, wakeUp),
|
148
|
-
addTorque: (torque, wakeUp = true) => ref.current().addTorque(torque, wakeUp),
|
149
|
-
|
150
|
-
translation() {
|
151
|
-
return rapierVector3ToVector3(ref.current().translation());
|
152
|
-
},
|
153
|
-
|
154
|
-
setTranslation: (translation, wakeUp = true) => ref.current().setTranslation(translation, wakeUp),
|
155
|
-
|
156
|
-
rotation() {
|
157
|
-
const {
|
158
|
-
x,
|
159
|
-
y,
|
160
|
-
z,
|
161
|
-
w
|
162
|
-
} = ref.current().rotation();
|
163
|
-
return new Quaternion(x, y, z, w);
|
164
|
-
},
|
165
|
-
|
166
|
-
setRotation: (rotation, wakeUp = true) => {
|
167
|
-
ref.current().setRotation(rotation, wakeUp);
|
168
|
-
},
|
169
|
-
|
170
|
-
linvel() {
|
171
|
-
const {
|
172
|
-
x,
|
173
|
-
y,
|
174
|
-
z
|
175
|
-
} = ref.current().linvel();
|
176
|
-
return new Vector3(x, y, z);
|
177
|
-
},
|
178
|
-
|
179
|
-
setLinvel: (velocity, wakeUp = true) => ref.current().setLinvel(velocity, wakeUp),
|
180
|
-
|
181
|
-
angvel() {
|
182
|
-
const {
|
183
|
-
x,
|
184
|
-
y,
|
185
|
-
z
|
186
|
-
} = ref.current().angvel();
|
187
|
-
return new Vector3(x, y, z);
|
188
|
-
},
|
189
|
-
|
190
|
-
setAngvel: (velocity, wakeUp = true) => ref.current().setAngvel(velocity, wakeUp),
|
191
|
-
|
192
|
-
linearDamping() {
|
193
|
-
return ref.current().linearDamping();
|
194
|
-
},
|
195
|
-
|
196
|
-
setLinearDamping: factor => ref.current().setLinearDamping(factor),
|
197
|
-
|
198
|
-
angularDamping() {
|
199
|
-
return ref.current().angularDamping();
|
200
|
-
},
|
201
|
-
|
202
|
-
setAngularDamping: factor => ref.current().setAngularDamping(factor),
|
203
|
-
setNextKinematicRotation: rotation => {
|
204
|
-
ref.current().setNextKinematicRotation(rotation);
|
205
|
-
},
|
206
|
-
setNextKinematicTranslation: translation => ref.current().setNextKinematicTranslation(translation),
|
207
|
-
resetForces: (wakeUp = true) => ref.current().resetForces(wakeUp),
|
208
|
-
resetTorques: (wakeUp = true) => ref.current().resetTorques(wakeUp),
|
209
|
-
lockRotations: (locked, wakeUp = true) => ref.current().lockRotations(locked, wakeUp),
|
210
|
-
lockTranslations: (locked, wakeUp = true) => ref.current().lockTranslations(locked, wakeUp),
|
211
|
-
setEnabledRotations: (x, y, z, wakeUp = true) => ref.current().setEnabledRotations(x, y, z, wakeUp),
|
212
|
-
setEnabledTranslations: (x, y, z, wakeUp = true) => ref.current().setEnabledTranslations(x, y, z, wakeUp)
|
213
|
-
};
|
214
|
-
};
|
215
|
-
const createInstancedRigidBodiesApi = bodiesGetter => ({
|
216
|
-
at: index => bodiesGetter.current()[index].api,
|
217
|
-
|
218
|
-
forEach(callback) {
|
219
|
-
return bodiesGetter.current().map(b => b.api).forEach(callback);
|
220
|
-
},
|
221
|
-
|
222
|
-
get count() {
|
223
|
-
return bodiesGetter.current().length;
|
224
|
-
}
|
225
|
-
|
226
|
-
});
|
227
|
-
const createWorldApi = ref => {
|
228
|
-
return {
|
229
|
-
raw: () => ref.current(),
|
230
|
-
getCollider: handle => ref.current().getCollider(handle),
|
231
|
-
getRigidBody: handle => ref.current().getRigidBody(handle),
|
232
|
-
createRigidBody: desc => ref.current().createRigidBody(desc),
|
233
|
-
createCollider: (desc, rigidBody) => ref.current().createCollider(desc, rigidBody),
|
234
|
-
removeRigidBody: rigidBody => {
|
235
|
-
if (!ref.current().bodies.contains(rigidBody.handle)) return;
|
236
|
-
ref.current().removeRigidBody(rigidBody);
|
237
|
-
},
|
238
|
-
removeCollider: (collider, wakeUp = true) => {
|
239
|
-
if (!ref.current().colliders.contains(collider.handle)) return;
|
240
|
-
ref.current().removeCollider(collider, wakeUp);
|
241
|
-
},
|
242
|
-
createImpulseJoint: (params, rigidBodyA, rigidBodyB, wakeUp = true) => ref.current().createImpulseJoint(params, rigidBodyA, rigidBodyB, wakeUp),
|
243
|
-
removeImpulseJoint: (joint, wakeUp = true) => {
|
244
|
-
if (!ref.current().impulseJoints.contains(joint.handle)) return;
|
245
|
-
ref.current().removeImpulseJoint(joint, wakeUp);
|
246
|
-
},
|
247
|
-
forEachCollider: callback => ref.current().forEachCollider(callback),
|
248
|
-
setGravity: ({
|
249
|
-
x,
|
250
|
-
y,
|
251
|
-
z
|
252
|
-
}) => ref.current().gravity = {
|
253
|
-
x,
|
254
|
-
y,
|
255
|
-
z
|
256
|
-
},
|
257
|
-
debugRender: () => ref.current().debugRender()
|
258
|
-
};
|
259
|
-
};
|
260
|
-
const createJointApi = ref => {
|
261
|
-
return {
|
262
|
-
raw: () => ref.current(),
|
263
|
-
|
264
|
-
get handle() {
|
265
|
-
return ref.current().handle;
|
266
|
-
},
|
267
|
-
|
268
|
-
configureMotorPosition: (targetPos, stiffness, damping) => ref.current().configureMotorPosition(targetPos, stiffness, damping),
|
269
|
-
configureMotorVelocity: (targetVel, damping) => ref.current().configureMotorVelocity(targetVel, damping)
|
270
|
-
};
|
271
|
-
};
|
272
|
-
|
273
156
|
const scaleColliderArgs = (shape, args, scale) => {
|
274
157
|
const newArgs = args.slice(); // Heightfield uses a vector
|
275
158
|
|
@@ -291,11 +174,11 @@ const scaleColliderArgs = (shape, args, scale) => {
|
|
291
174
|
const scaleArray = [scale.x, scale.y, scale.z, scale.x, scale.x];
|
292
175
|
return newArgs.map((arg, index) => scaleArray[index] * arg);
|
293
176
|
};
|
294
|
-
const createColliderFromOptions = (options, world, scale,
|
177
|
+
const createColliderFromOptions = (options, world, scale, getRigidBody) => {
|
295
178
|
const scaledArgs = scaleColliderArgs(options.shape, options.args, scale); // @ts-ignore
|
296
179
|
|
297
180
|
const desc = ColliderDesc[options.shape](...scaledArgs);
|
298
|
-
return world.createCollider(desc,
|
181
|
+
return world.createCollider(desc, getRigidBody === null || getRigidBody === void 0 ? void 0 : getRigidBody());
|
299
182
|
};
|
300
183
|
const massPropertiesConflictError = "Please pick ONLY ONE of the `density`, `mass` and `massProperties` options.";
|
301
184
|
|
@@ -399,15 +282,14 @@ const setColliderOptions = (collider, options, states) => {
|
|
399
282
|
setColliderMassOptions(collider, options);
|
400
283
|
}
|
401
284
|
};
|
402
|
-
const useUpdateColliderOptions = (
|
285
|
+
const useUpdateColliderOptions = (getCollider, props, states) => {
|
403
286
|
// TODO: Improve this, split each prop into its own effect
|
404
287
|
const mutablePropsAsFlatArray = useMemo(() => mutableColliderOptionKeys.flatMap(key => {
|
405
288
|
return vectorToTuple(props[key]);
|
406
289
|
}), [props]);
|
407
290
|
useEffect(() => {
|
408
|
-
|
409
|
-
|
410
|
-
});
|
291
|
+
const collider = getCollider();
|
292
|
+
setColliderOptions(collider, props, states);
|
411
293
|
}, mutablePropsAsFlatArray);
|
412
294
|
};
|
413
295
|
|
@@ -530,7 +412,7 @@ const getColliderArgsFromGeometry = (geometry, colliders) => {
|
|
530
412
|
offset: new Vector3()
|
531
413
|
};
|
532
414
|
};
|
533
|
-
const useColliderEvents = (
|
415
|
+
const useColliderEvents = (getCollider, props, events) => {
|
534
416
|
const {
|
535
417
|
onCollisionEnter,
|
536
418
|
onCollisionExit,
|
@@ -539,9 +421,9 @@ const useColliderEvents = (collidersRef, props, events) => {
|
|
539
421
|
onContactForce
|
540
422
|
} = props;
|
541
423
|
useEffect(() => {
|
542
|
-
|
424
|
+
const collider = getCollider();
|
543
425
|
|
544
|
-
|
426
|
+
if (collider) {
|
545
427
|
const hasCollisionEvent = !!(onCollisionEnter || onCollisionExit || onIntersectionEnter || onIntersectionExit);
|
546
428
|
const hasContactForceEvent = !!onContactForce;
|
547
429
|
|
@@ -560,265 +442,87 @@ const useColliderEvents = (collidersRef, props, events) => {
|
|
560
442
|
onIntersectionExit,
|
561
443
|
onContactForce
|
562
444
|
});
|
563
|
-
}
|
564
|
-
return () => {
|
565
|
-
var _collidersRef$current2;
|
445
|
+
}
|
566
446
|
|
567
|
-
|
447
|
+
return () => {
|
448
|
+
if (collider) {
|
449
|
+
events.delete(collider.handle);
|
450
|
+
}
|
568
451
|
};
|
569
452
|
}, [onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit, onContactForce]);
|
570
453
|
};
|
571
454
|
|
572
|
-
const
|
573
|
-
|
455
|
+
const useMutableCallback = fn => {
|
456
|
+
const ref = useRef(fn);
|
457
|
+
useEffect(() => {
|
458
|
+
ref.current = fn;
|
459
|
+
}, [fn]);
|
460
|
+
return ref;
|
461
|
+
}; // External hooks
|
574
462
|
|
575
|
-
|
576
|
-
|
463
|
+
/**
|
464
|
+
* Exposes the Rapier context, and world
|
465
|
+
* @category Hooks
|
466
|
+
*/
|
577
467
|
|
578
|
-
desc.canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
|
579
|
-
return desc;
|
580
|
-
};
|
581
|
-
const createRigidBodyState = ({
|
582
|
-
rigidBody,
|
583
|
-
object,
|
584
|
-
setMatrix,
|
585
|
-
getMatrix,
|
586
|
-
worldScale
|
587
|
-
}) => {
|
588
|
-
object.updateWorldMatrix(true, false);
|
589
|
-
const invertedWorldMatrix = object.parent.matrixWorld.clone().invert();
|
590
|
-
return {
|
591
|
-
object,
|
592
|
-
rigidBody,
|
593
|
-
invertedWorldMatrix,
|
594
|
-
setMatrix: setMatrix ? setMatrix : matrix => {
|
595
|
-
object.matrix.copy(matrix);
|
596
|
-
},
|
597
|
-
getMatrix: getMatrix ? getMatrix : matrix => matrix.copy(object.matrix),
|
598
|
-
scale: worldScale || object.getWorldScale(_scale).clone(),
|
599
|
-
isSleeping: false
|
600
|
-
};
|
601
|
-
};
|
602
|
-
const mutableRigidBodyOptions = {
|
603
|
-
gravityScale: (rb, value) => {
|
604
|
-
rb.setGravityScale(value, true);
|
605
|
-
},
|
606
|
-
linearDamping: (rb, value) => {
|
607
|
-
rb.setLinearDamping(value);
|
608
|
-
},
|
609
|
-
angularDamping: (rb, value) => {
|
610
|
-
rb.setAngularDamping(value);
|
611
|
-
},
|
612
|
-
enabledRotations: (rb, [x, y, z]) => {
|
613
|
-
rb.setEnabledRotations(x, y, z, true);
|
614
|
-
},
|
615
|
-
enabledTranslations: (rb, [x, y, z]) => {
|
616
|
-
rb.setEnabledTranslations(x, y, z, true);
|
617
|
-
},
|
618
|
-
lockRotations: (rb, value) => {
|
619
|
-
rb.lockRotations(value, true);
|
620
|
-
},
|
621
|
-
lockTranslations: (rb, value) => {
|
622
|
-
rb.lockTranslations(value, true);
|
623
|
-
},
|
624
|
-
angularVelocity: (rb, [x, y, z]) => {
|
625
|
-
rb.setAngvel({
|
626
|
-
x,
|
627
|
-
y,
|
628
|
-
z
|
629
|
-
}, true);
|
630
|
-
},
|
631
|
-
linearVelocity: (rb, [x, y, z]) => {
|
632
|
-
rb.setLinvel({
|
633
|
-
x,
|
634
|
-
y,
|
635
|
-
z
|
636
|
-
}, true);
|
637
|
-
},
|
638
|
-
ccd: (rb, value) => {
|
639
|
-
rb.enableCcd(value);
|
640
|
-
},
|
641
|
-
userData: (rb, value) => {
|
642
|
-
rb.userData = value;
|
643
|
-
},
|
644
468
|
|
645
|
-
|
646
|
-
|
647
|
-
|
469
|
+
const useRapier = () => {
|
470
|
+
return useContext(rapierContext);
|
471
|
+
};
|
472
|
+
/**
|
473
|
+
* Registers a callback to be called before the physics step
|
474
|
+
* @category Hooks
|
475
|
+
*/
|
648
476
|
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
477
|
+
const useBeforePhysicsStep = callback => {
|
478
|
+
const {
|
479
|
+
beforeStepCallbacks
|
480
|
+
} = useRapier();
|
481
|
+
const ref = useMutableCallback(callback);
|
482
|
+
useEffect(() => {
|
483
|
+
beforeStepCallbacks.add(ref);
|
484
|
+
return () => {
|
485
|
+
beforeStepCallbacks.delete(ref);
|
486
|
+
};
|
487
|
+
}, []);
|
653
488
|
};
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
}
|
489
|
+
/**
|
490
|
+
* Registers a callback to be called after the physics step
|
491
|
+
* @category Hooks
|
492
|
+
*/
|
659
493
|
|
660
|
-
|
494
|
+
const useAfterPhysicsStep = callback => {
|
495
|
+
const {
|
496
|
+
afterStepCallbacks
|
497
|
+
} = useRapier();
|
498
|
+
const ref = useMutableCallback(callback);
|
499
|
+
useEffect(() => {
|
500
|
+
afterStepCallbacks.add(ref);
|
501
|
+
return () => {
|
502
|
+
afterStepCallbacks.delete(ref);
|
503
|
+
};
|
504
|
+
}, []);
|
505
|
+
}; // Internal hooks
|
661
506
|
|
662
|
-
|
663
|
-
|
664
|
-
|
507
|
+
/**
|
508
|
+
* @internal
|
509
|
+
*/
|
665
510
|
|
666
|
-
|
511
|
+
const useChildColliderProps = (ref, options, ignoreMeshColliders = true) => {
|
512
|
+
const [colliderProps, setColliderProps] = useState([]);
|
513
|
+
useEffect(() => {
|
514
|
+
const object = ref.current;
|
667
515
|
|
668
|
-
|
669
|
-
|
516
|
+
if (object && options.colliders !== false) {
|
517
|
+
setColliderProps(createColliderPropsFromChildren({
|
518
|
+
object: ref.current,
|
519
|
+
options,
|
520
|
+
ignoreMeshColliders
|
521
|
+
}));
|
670
522
|
}
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
mutableRigidBodyOptions[key](rigidBody, options[key]);
|
675
|
-
}
|
676
|
-
});
|
677
|
-
}
|
678
|
-
};
|
679
|
-
const useUpdateRigidBodyOptions = (rigidBodyRef, props, states, updateTranslations = true) => {
|
680
|
-
// TODO: Improve this, split each prop into its own effect
|
681
|
-
const mutablePropsAsFlatArray = useMemo(() => mutableRigidBodyOptionKeys.flatMap(key => {
|
682
|
-
return vectorToTuple(props[key]);
|
683
|
-
}), [props]);
|
684
|
-
useEffect(() => {
|
685
|
-
if (Array.isArray(rigidBodyRef.current)) {
|
686
|
-
for (const rigidBody of rigidBodyRef.current) {
|
687
|
-
setRigidBodyOptions(rigidBody, props, states, updateTranslations);
|
688
|
-
}
|
689
|
-
} else if (rigidBodyRef.current) {
|
690
|
-
setRigidBodyOptions(rigidBodyRef.current, props, states, updateTranslations);
|
691
|
-
}
|
692
|
-
}, mutablePropsAsFlatArray);
|
693
|
-
};
|
694
|
-
const useRigidBodyEvents = (rigidBodyRef, props, events) => {
|
695
|
-
const {
|
696
|
-
onWake,
|
697
|
-
onSleep,
|
698
|
-
onCollisionEnter,
|
699
|
-
onCollisionExit,
|
700
|
-
onIntersectionEnter,
|
701
|
-
onIntersectionExit
|
702
|
-
} = props;
|
703
|
-
const eventHandlers = {
|
704
|
-
onWake,
|
705
|
-
onSleep,
|
706
|
-
onCollisionEnter,
|
707
|
-
onCollisionExit,
|
708
|
-
onIntersectionEnter,
|
709
|
-
onIntersectionExit
|
710
|
-
};
|
711
|
-
useEffect(() => {
|
712
|
-
if (Array.isArray(rigidBodyRef.current)) {
|
713
|
-
for (const rigidBody of rigidBodyRef.current) {
|
714
|
-
events.set(rigidBody.handle, eventHandlers);
|
715
|
-
}
|
716
|
-
} else if (rigidBodyRef.current) {
|
717
|
-
events.set(rigidBodyRef.current.handle, eventHandlers);
|
718
|
-
}
|
719
|
-
|
720
|
-
return () => {
|
721
|
-
if (Array.isArray(rigidBodyRef.current)) {
|
722
|
-
for (const rigidBody of rigidBodyRef.current) {
|
723
|
-
events.delete(rigidBody.handle);
|
724
|
-
}
|
725
|
-
} else if (rigidBodyRef.current) {
|
726
|
-
events.delete(rigidBodyRef.current.handle);
|
727
|
-
}
|
728
|
-
};
|
729
|
-
}, [onWake, onSleep, onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit]);
|
730
|
-
};
|
731
|
-
|
732
|
-
const useRapier = () => {
|
733
|
-
return useContext(rapierContext);
|
734
|
-
};
|
735
|
-
const useBeforePhysicsStep = callback => {
|
736
|
-
const {
|
737
|
-
beforeStepCallbacks
|
738
|
-
} = useRapier();
|
739
|
-
useEffect(() => {
|
740
|
-
beforeStepCallbacks.add(callback);
|
741
|
-
return () => {
|
742
|
-
beforeStepCallbacks.delete(callback);
|
743
|
-
};
|
744
|
-
}, []);
|
745
|
-
};
|
746
|
-
const useAfterPhysicsStep = callback => {
|
747
|
-
const {
|
748
|
-
afterStepCallbacks
|
749
|
-
} = useRapier();
|
750
|
-
useEffect(() => {
|
751
|
-
afterStepCallbacks.add(callback);
|
752
|
-
return () => {
|
753
|
-
afterStepCallbacks.delete(callback);
|
754
|
-
};
|
755
|
-
}, []);
|
756
|
-
}; // Internal hooks
|
757
|
-
|
758
|
-
const useChildColliderProps = (ref, options, ignoreMeshColliders = true) => {
|
759
|
-
const [colliderProps, setColliderProps] = useState([]);
|
760
|
-
useEffect(() => {
|
761
|
-
const object = ref.current;
|
762
|
-
|
763
|
-
if (object && options.colliders !== false) {
|
764
|
-
setColliderProps(createColliderPropsFromChildren({
|
765
|
-
object: ref.current,
|
766
|
-
options,
|
767
|
-
ignoreMeshColliders
|
768
|
-
}));
|
769
|
-
}
|
770
|
-
}, [options.colliders]);
|
771
|
-
return colliderProps;
|
772
|
-
};
|
773
|
-
const useRigidBody = (options = {}) => {
|
774
|
-
const {
|
775
|
-
world,
|
776
|
-
rigidBodyStates,
|
777
|
-
physicsOptions,
|
778
|
-
rigidBodyEvents
|
779
|
-
} = useRapier();
|
780
|
-
const ref = useRef();
|
781
|
-
const mergedOptions = useMemo(() => {
|
782
|
-
return _objectSpread2(_objectSpread2(_objectSpread2({}, physicsOptions), options), {}, {
|
783
|
-
children: undefined
|
784
|
-
});
|
785
|
-
}, [physicsOptions, options]);
|
786
|
-
const childColliderProps = useChildColliderProps(ref, mergedOptions); // Create rigidbody
|
787
|
-
|
788
|
-
const rigidBodyRef = useRef();
|
789
|
-
const getRigidBodyRef = useRef(() => {
|
790
|
-
if (!rigidBodyRef.current) {
|
791
|
-
const desc = rigidBodyDescFromOptions(options);
|
792
|
-
const rigidBody = world.createRigidBody(desc);
|
793
|
-
rigidBodyRef.current = world.getRigidBody(rigidBody.handle);
|
794
|
-
}
|
795
|
-
|
796
|
-
return rigidBodyRef.current;
|
797
|
-
}); // Setup
|
798
|
-
|
799
|
-
useEffect(() => {
|
800
|
-
const rigidBody = getRigidBodyRef.current();
|
801
|
-
rigidBodyRef.current = rigidBody;
|
802
|
-
|
803
|
-
if (!ref.current) {
|
804
|
-
ref.current = new Object3D();
|
805
|
-
}
|
806
|
-
|
807
|
-
rigidBodyStates.set(rigidBody.handle, createRigidBodyState({
|
808
|
-
rigidBody,
|
809
|
-
object: ref.current
|
810
|
-
}));
|
811
|
-
return () => {
|
812
|
-
world.removeRigidBody(rigidBody);
|
813
|
-
rigidBodyStates.delete(rigidBody.handle);
|
814
|
-
rigidBodyRef.current = undefined;
|
815
|
-
};
|
816
|
-
}, []);
|
817
|
-
useUpdateRigidBodyOptions(rigidBodyRef, mergedOptions, rigidBodyStates);
|
818
|
-
useRigidBodyEvents(rigidBodyRef, mergedOptions, rigidBodyEvents);
|
819
|
-
const api = useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
|
820
|
-
return [ref, api, childColliderProps];
|
821
|
-
};
|
523
|
+
}, [options.colliders]);
|
524
|
+
return colliderProps;
|
525
|
+
};
|
822
526
|
|
823
527
|
const calcForceByType = {
|
824
528
|
static: (s, m2, r, d, G) => s,
|
@@ -936,6 +640,10 @@ const importRapier = async () => {
|
|
936
640
|
return r;
|
937
641
|
};
|
938
642
|
|
643
|
+
/**
|
644
|
+
* The main physics component used to create a physics world.
|
645
|
+
* @category Components
|
646
|
+
*/
|
939
647
|
const Physics = ({
|
940
648
|
colliders: _colliders = "cuboid",
|
941
649
|
gravity: _gravity = [0, -9.81, 0],
|
@@ -1037,12 +745,12 @@ const Physics = ({
|
|
1037
745
|
}); // Trigger beforeStep callbacks
|
1038
746
|
|
1039
747
|
beforeStepCallbacks.forEach(callback => {
|
1040
|
-
callback(api);
|
748
|
+
callback.current(api);
|
1041
749
|
});
|
1042
750
|
world.step(eventQueue); // Trigger afterStep callbacks
|
1043
751
|
|
1044
752
|
afterStepCallbacks.forEach(callback => {
|
1045
|
-
callback(api);
|
753
|
+
callback.current(api);
|
1046
754
|
});
|
1047
755
|
};
|
1048
756
|
|
@@ -1095,7 +803,7 @@ const Physics = ({
|
|
1095
803
|
state.isSleeping = rigidBody.isSleeping();
|
1096
804
|
}
|
1097
805
|
|
1098
|
-
if (!rigidBody || rigidBody.isSleeping() || !state.setMatrix) {
|
806
|
+
if (!rigidBody || rigidBody.isSleeping() && !("isInstancedMesh" in state.object) || !state.setMatrix) {
|
1099
807
|
return;
|
1100
808
|
} // New states
|
1101
809
|
|
@@ -1109,7 +817,7 @@ const Physics = ({
|
|
1109
817
|
_matrix4.compose(previousState.position, rapierQuaternionToQuaternion(previousState.rotation), state.scale).premultiply(state.invertedWorldMatrix).decompose(_position, _rotation, _scale); // Apply previous tick position
|
1110
818
|
|
1111
819
|
|
1112
|
-
if (
|
820
|
+
if (state.meshType == "mesh") {
|
1113
821
|
state.object.position.copy(_position);
|
1114
822
|
state.object.quaternion.copy(_rotation);
|
1115
823
|
}
|
@@ -1118,9 +826,8 @@ const Physics = ({
|
|
1118
826
|
|
1119
827
|
_matrix4.compose(t, rapierQuaternionToQuaternion(r), state.scale).premultiply(state.invertedWorldMatrix).decompose(_position, _rotation, _scale);
|
1120
828
|
|
1121
|
-
if (state.
|
829
|
+
if (state.meshType == "instancedMesh") {
|
1122
830
|
state.setMatrix(_matrix4);
|
1123
|
-
state.object.instanceMatrix.needsUpdate = true;
|
1124
831
|
} else {
|
1125
832
|
// Interpolate to new position
|
1126
833
|
state.object.position.lerp(_position, interpolationAlpha);
|
@@ -1304,8 +1011,87 @@ function _objectWithoutProperties(source, excluded) {
|
|
1304
1011
|
return target;
|
1305
1012
|
}
|
1306
1013
|
|
1014
|
+
/**
|
1015
|
+
* Initiate an instance and return a safe getter
|
1016
|
+
*/
|
1017
|
+
|
1018
|
+
const useImperativeInstance = (createFn, destroyFn) => {
|
1019
|
+
const ref = useRef();
|
1020
|
+
const refGetter = useMemo(() => () => {
|
1021
|
+
if (!ref.current) {
|
1022
|
+
ref.current = createFn();
|
1023
|
+
}
|
1024
|
+
|
1025
|
+
return ref.current;
|
1026
|
+
}, []);
|
1027
|
+
useEffect(() => {
|
1028
|
+
const instance = refGetter();
|
1029
|
+
return () => {
|
1030
|
+
destroyFn(instance);
|
1031
|
+
ref.current = undefined;
|
1032
|
+
};
|
1033
|
+
}, []);
|
1034
|
+
return refGetter;
|
1035
|
+
};
|
1036
|
+
|
1037
|
+
/**
|
1038
|
+
* Takes an object resembling a Vector3 and returs a Three.Vector3
|
1039
|
+
* @category Math helpers
|
1040
|
+
*/
|
1041
|
+
|
1042
|
+
const vec3 = ({
|
1043
|
+
x,
|
1044
|
+
y,
|
1045
|
+
z
|
1046
|
+
} = {
|
1047
|
+
x: 0,
|
1048
|
+
y: 0,
|
1049
|
+
z: 0
|
1050
|
+
}) => {
|
1051
|
+
return new Vector3(x, y, z);
|
1052
|
+
};
|
1053
|
+
/**
|
1054
|
+
* Takes an object resembling a Quaternion and returs a Three.Quaternion
|
1055
|
+
* @category Math helpers
|
1056
|
+
*/
|
1057
|
+
|
1058
|
+
const quat = ({
|
1059
|
+
x,
|
1060
|
+
y,
|
1061
|
+
z,
|
1062
|
+
w
|
1063
|
+
} = {
|
1064
|
+
x: 0,
|
1065
|
+
y: 0,
|
1066
|
+
z: 0,
|
1067
|
+
w: 1
|
1068
|
+
}) => {
|
1069
|
+
return new Quaternion(x, y, z, w);
|
1070
|
+
};
|
1071
|
+
/**
|
1072
|
+
* Takes an object resembling an Euler and returs a Three.Euler
|
1073
|
+
* @category Math helpers
|
1074
|
+
*/
|
1075
|
+
|
1076
|
+
const euler = ({
|
1077
|
+
x,
|
1078
|
+
y,
|
1079
|
+
z
|
1080
|
+
} = {
|
1081
|
+
x: 0,
|
1082
|
+
y: 0,
|
1083
|
+
z: 0
|
1084
|
+
}) => {
|
1085
|
+
return new Euler(x, y, z);
|
1086
|
+
};
|
1087
|
+
|
1307
1088
|
// Colliders
|
1308
|
-
|
1089
|
+
|
1090
|
+
/**
|
1091
|
+
* A collider is a shape that can be attached to a rigid body to define its physical properties.
|
1092
|
+
* @internal
|
1093
|
+
*/
|
1094
|
+
const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwardedRef) => {
|
1309
1095
|
const {
|
1310
1096
|
children,
|
1311
1097
|
position,
|
@@ -1321,52 +1107,21 @@ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/React.forwardRef((props, for
|
|
1321
1107
|
} = useRapier();
|
1322
1108
|
const rigidBodyContext = useRigidBodyContext();
|
1323
1109
|
const ref = useRef(null);
|
1324
|
-
const
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1332
|
-
}
|
1333
|
-
|
1334
|
-
const object = ref.current;
|
1335
|
-
const worldScale = object.getWorldScale(new Vector3());
|
1336
|
-
const colliders = []; // If this is an InstancedRigidBody api
|
1337
|
-
|
1338
|
-
if (rigidBodyContext && "at" in rigidBodyContext.api) {
|
1339
|
-
rigidBodyContext.api.forEach((body, index) => {
|
1340
|
-
var _rigidBodyContext$opt, _rigidBodyContext$opt2;
|
1341
|
-
|
1342
|
-
let instanceScale = worldScale;
|
1343
|
-
|
1344
|
-
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]) {
|
1345
|
-
instanceScale = instanceScale.clone().multiply(vectorArrayToVector3(rigidBodyContext.options.scales[index]));
|
1346
|
-
}
|
1347
|
-
|
1348
|
-
const collider = createColliderFromOptions(props, world, instanceScale, body.raw());
|
1349
|
-
colliderStates.set(collider.handle, createColliderState(collider, object, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
|
1350
|
-
colliders.push(collider);
|
1351
|
-
});
|
1352
|
-
} else {
|
1353
|
-
const collider = createColliderFromOptions(props, world, worldScale, rigidBodyContext && (rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.api).raw());
|
1354
|
-
colliderStates.set(collider.handle, createColliderState(collider, object, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
|
1355
|
-
colliders.push(collider);
|
1356
|
-
}
|
1357
|
-
|
1358
|
-
collidersRef.current = colliders;
|
1359
|
-
return () => {
|
1360
|
-
colliders.forEach(collider => {
|
1361
|
-
world.removeCollider(collider);
|
1362
|
-
});
|
1363
|
-
};
|
1364
|
-
}, []);
|
1110
|
+
const getInstance = useImperativeInstance(() => {
|
1111
|
+
const worldScale = ref.current.getWorldScale(vec3());
|
1112
|
+
const collider = createColliderFromOptions(props, world, worldScale, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.getRigidBody);
|
1113
|
+
colliderStates.set(collider.handle, createColliderState(collider, ref.current, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
|
1114
|
+
return collider;
|
1115
|
+
}, collider => {
|
1116
|
+
colliderStates.delete(collider.handle);
|
1117
|
+
world.removeCollider(collider);
|
1118
|
+
});
|
1119
|
+
useImperativeHandle(forwardedRef, () => getInstance());
|
1365
1120
|
const mergedProps = useMemo(() => {
|
1366
1121
|
return _objectSpread2(_objectSpread2({}, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options), props);
|
1367
1122
|
}, [props, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options]);
|
1368
|
-
useUpdateColliderOptions(
|
1369
|
-
useColliderEvents(
|
1123
|
+
useUpdateColliderOptions(getInstance, mergedProps, colliderStates);
|
1124
|
+
useColliderEvents(getInstance, mergedProps, colliderEvents);
|
1370
1125
|
return /*#__PURE__*/React.createElement("object3D", {
|
1371
1126
|
position: position,
|
1372
1127
|
rotation: rotation,
|
@@ -1376,54 +1131,99 @@ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/React.forwardRef((props, for
|
|
1376
1131
|
name: name
|
1377
1132
|
}, children);
|
1378
1133
|
}));
|
1134
|
+
|
1135
|
+
/**
|
1136
|
+
* A cuboid collider shape
|
1137
|
+
* @category Colliders
|
1138
|
+
*/
|
1379
1139
|
const CuboidCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
|
1380
1140
|
return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
|
1381
1141
|
shape: "cuboid",
|
1382
1142
|
ref: ref
|
1383
1143
|
}));
|
1384
1144
|
});
|
1145
|
+
/**
|
1146
|
+
* A round cuboid collider shape
|
1147
|
+
* @category Colliders
|
1148
|
+
*/
|
1149
|
+
|
1385
1150
|
const RoundCuboidCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
|
1386
1151
|
return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
|
1387
1152
|
shape: "roundCuboid",
|
1388
1153
|
ref: ref
|
1389
1154
|
}));
|
1390
1155
|
});
|
1156
|
+
/**
|
1157
|
+
* A ball collider shape
|
1158
|
+
* @category Colliders
|
1159
|
+
*/
|
1160
|
+
|
1391
1161
|
const BallCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
|
1392
1162
|
return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
|
1393
1163
|
shape: "ball",
|
1394
1164
|
ref: ref
|
1395
1165
|
}));
|
1396
1166
|
});
|
1167
|
+
/**
|
1168
|
+
* A capsule collider shape
|
1169
|
+
* @category Colliders
|
1170
|
+
*/
|
1171
|
+
|
1397
1172
|
const CapsuleCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
|
1398
1173
|
return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
|
1399
1174
|
shape: "capsule",
|
1400
1175
|
ref: ref
|
1401
1176
|
}));
|
1402
1177
|
});
|
1178
|
+
/**
|
1179
|
+
* A heightfield collider shape
|
1180
|
+
* @category Colliders
|
1181
|
+
*/
|
1182
|
+
|
1403
1183
|
const HeightfieldCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
|
1404
1184
|
return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
|
1405
1185
|
shape: "heightfield",
|
1406
1186
|
ref: ref
|
1407
1187
|
}));
|
1408
1188
|
});
|
1189
|
+
/**
|
1190
|
+
* A trimesh collider shape
|
1191
|
+
* @category Colliders
|
1192
|
+
*/
|
1193
|
+
|
1409
1194
|
const TrimeshCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
|
1410
1195
|
return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
|
1411
1196
|
shape: "trimesh",
|
1412
1197
|
ref: ref
|
1413
1198
|
}));
|
1414
1199
|
});
|
1200
|
+
/**
|
1201
|
+
* A cone collider shape
|
1202
|
+
* @category Colliders
|
1203
|
+
*/
|
1204
|
+
|
1415
1205
|
const ConeCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
|
1416
1206
|
return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
|
1417
1207
|
shape: "cone",
|
1418
1208
|
ref: ref
|
1419
1209
|
}));
|
1420
1210
|
});
|
1211
|
+
/**
|
1212
|
+
* A cylinder collider shape
|
1213
|
+
* @category Colliders
|
1214
|
+
*/
|
1215
|
+
|
1421
1216
|
const CylinderCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
|
1422
1217
|
return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
|
1423
1218
|
shape: "cylinder",
|
1424
1219
|
ref: ref
|
1425
1220
|
}));
|
1426
1221
|
});
|
1222
|
+
/**
|
1223
|
+
* A convex hull collider shape
|
1224
|
+
* @category Colliders
|
1225
|
+
*/
|
1226
|
+
|
1427
1227
|
const ConvexHullCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
|
1428
1228
|
return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
|
1429
1229
|
shape: "convexHull",
|
@@ -1440,31 +1240,212 @@ ConeCollider.displayName = "ConeCollider";
|
|
1440
1240
|
CylinderCollider.displayName = "CylinderCollider";
|
1441
1241
|
ConvexHullCollider.displayName = "ConvexHullCollider";
|
1442
1242
|
|
1443
|
-
const
|
1243
|
+
const rigidBodyDescFromOptions = options => {
|
1244
|
+
var _options$canSleep;
|
1245
|
+
|
1246
|
+
const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
|
1247
|
+
const desc = new RigidBodyDesc(type); // Apply immutable options
|
1248
|
+
|
1249
|
+
desc.canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
|
1250
|
+
return desc;
|
1251
|
+
};
|
1252
|
+
const createRigidBodyState = ({
|
1253
|
+
rigidBody,
|
1254
|
+
object,
|
1255
|
+
setMatrix,
|
1256
|
+
getMatrix,
|
1257
|
+
worldScale,
|
1258
|
+
meshType: _meshType = "mesh"
|
1259
|
+
}) => {
|
1260
|
+
object.updateWorldMatrix(true, false);
|
1261
|
+
const invertedWorldMatrix = object.parent.matrixWorld.clone().invert();
|
1262
|
+
return {
|
1263
|
+
object,
|
1264
|
+
rigidBody,
|
1265
|
+
invertedWorldMatrix,
|
1266
|
+
setMatrix: setMatrix ? setMatrix : matrix => {
|
1267
|
+
object.matrix.copy(matrix);
|
1268
|
+
},
|
1269
|
+
getMatrix: getMatrix ? getMatrix : matrix => matrix.copy(object.matrix),
|
1270
|
+
scale: worldScale || object.getWorldScale(_scale).clone(),
|
1271
|
+
isSleeping: false,
|
1272
|
+
meshType: _meshType
|
1273
|
+
};
|
1274
|
+
};
|
1275
|
+
const mutableRigidBodyOptions = {
|
1276
|
+
gravityScale: (rb, value) => {
|
1277
|
+
rb.setGravityScale(value, true);
|
1278
|
+
},
|
1279
|
+
linearDamping: (rb, value) => {
|
1280
|
+
rb.setLinearDamping(value);
|
1281
|
+
},
|
1282
|
+
angularDamping: (rb, value) => {
|
1283
|
+
rb.setAngularDamping(value);
|
1284
|
+
},
|
1285
|
+
enabledRotations: (rb, [x, y, z]) => {
|
1286
|
+
rb.setEnabledRotations(x, y, z, true);
|
1287
|
+
},
|
1288
|
+
enabledTranslations: (rb, [x, y, z]) => {
|
1289
|
+
rb.setEnabledTranslations(x, y, z, true);
|
1290
|
+
},
|
1291
|
+
lockRotations: (rb, value) => {
|
1292
|
+
rb.lockRotations(value, true);
|
1293
|
+
},
|
1294
|
+
lockTranslations: (rb, value) => {
|
1295
|
+
rb.lockTranslations(value, true);
|
1296
|
+
},
|
1297
|
+
angularVelocity: (rb, [x, y, z]) => {
|
1298
|
+
rb.setAngvel({
|
1299
|
+
x,
|
1300
|
+
y,
|
1301
|
+
z
|
1302
|
+
}, true);
|
1303
|
+
},
|
1304
|
+
linearVelocity: (rb, [x, y, z]) => {
|
1305
|
+
rb.setLinvel({
|
1306
|
+
x,
|
1307
|
+
y,
|
1308
|
+
z
|
1309
|
+
}, true);
|
1310
|
+
},
|
1311
|
+
ccd: (rb, value) => {
|
1312
|
+
rb.enableCcd(value);
|
1313
|
+
},
|
1314
|
+
userData: (rb, value) => {
|
1315
|
+
rb.userData = value;
|
1316
|
+
},
|
1317
|
+
|
1318
|
+
type(rb, value) {
|
1319
|
+
rb.setBodyType(rigidBodyTypeFromString(value), true);
|
1320
|
+
},
|
1321
|
+
|
1322
|
+
position: () => {},
|
1323
|
+
rotation: () => {},
|
1324
|
+
quaternion: () => {},
|
1325
|
+
scale: () => {}
|
1326
|
+
};
|
1327
|
+
const mutableRigidBodyOptionKeys = Object.keys(mutableRigidBodyOptions);
|
1328
|
+
const setRigidBodyOptions = (rigidBody, options, states, updateTranslations = true) => {
|
1329
|
+
if (!rigidBody) {
|
1330
|
+
return;
|
1331
|
+
}
|
1332
|
+
|
1333
|
+
const state = states.get(rigidBody.handle);
|
1334
|
+
|
1335
|
+
if (state) {
|
1336
|
+
if (updateTranslations) {
|
1337
|
+
state.object.updateWorldMatrix(true, false);
|
1338
|
+
|
1339
|
+
_matrix4.copy(state.object.matrixWorld).decompose(_position, _rotation, _scale);
|
1340
|
+
|
1341
|
+
rigidBody.setTranslation(_position, false);
|
1342
|
+
rigidBody.setRotation(_rotation, false);
|
1343
|
+
}
|
1344
|
+
|
1345
|
+
mutableRigidBodyOptionKeys.forEach(key => {
|
1346
|
+
if (key in options) {
|
1347
|
+
mutableRigidBodyOptions[key](rigidBody, options[key]);
|
1348
|
+
}
|
1349
|
+
});
|
1350
|
+
}
|
1351
|
+
};
|
1352
|
+
const useUpdateRigidBodyOptions = (getRigidBody, props, states, updateTranslations = true) => {
|
1353
|
+
// TODO: Improve this, split each prop into its own effect
|
1354
|
+
const mutablePropsAsFlatArray = useMemo(() => mutableRigidBodyOptionKeys.flatMap(key => {
|
1355
|
+
return vectorToTuple(props[key]);
|
1356
|
+
}), [props]);
|
1357
|
+
useEffect(() => {
|
1358
|
+
const rigidBody = getRigidBody();
|
1359
|
+
setRigidBodyOptions(rigidBody, props, states, updateTranslations);
|
1360
|
+
}, mutablePropsAsFlatArray);
|
1361
|
+
};
|
1362
|
+
const useRigidBodyEvents = (getRigidBody, props, events) => {
|
1363
|
+
const {
|
1364
|
+
onWake,
|
1365
|
+
onSleep,
|
1366
|
+
onCollisionEnter,
|
1367
|
+
onCollisionExit,
|
1368
|
+
onIntersectionEnter,
|
1369
|
+
onIntersectionExit
|
1370
|
+
} = props;
|
1371
|
+
const eventHandlers = {
|
1372
|
+
onWake,
|
1373
|
+
onSleep,
|
1374
|
+
onCollisionEnter,
|
1375
|
+
onCollisionExit,
|
1376
|
+
onIntersectionEnter,
|
1377
|
+
onIntersectionExit
|
1378
|
+
};
|
1379
|
+
useEffect(() => {
|
1380
|
+
const rigidBody = getRigidBody();
|
1381
|
+
events.set(rigidBody.handle, eventHandlers);
|
1382
|
+
return () => {
|
1383
|
+
events.delete(rigidBody.handle);
|
1384
|
+
};
|
1385
|
+
}, [onWake, onSleep, onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit]);
|
1386
|
+
};
|
1387
|
+
|
1388
|
+
const _excluded$1 = ["children", "type", "position", "rotation", "scale", "quaternion", "transformState"];
|
1444
1389
|
const RigidBodyContext = /*#__PURE__*/createContext(undefined);
|
1445
1390
|
const useRigidBodyContext = () => useContext(RigidBodyContext);
|
1446
|
-
|
1391
|
+
|
1392
|
+
/**
|
1393
|
+
* A rigid body is a physical object that can be simulated by the physics engine.
|
1394
|
+
* @category Components
|
1395
|
+
*/
|
1396
|
+
const RigidBody = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwardedRef) => {
|
1447
1397
|
const {
|
1448
1398
|
children,
|
1449
1399
|
type,
|
1450
1400
|
position,
|
1451
1401
|
rotation,
|
1452
1402
|
scale,
|
1453
|
-
quaternion
|
1403
|
+
quaternion,
|
1404
|
+
transformState
|
1454
1405
|
} = props,
|
1455
1406
|
objectProps = _objectWithoutProperties(props, _excluded$1);
|
1456
1407
|
|
1457
|
-
const
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
}
|
1408
|
+
const ref = useRef(null);
|
1409
|
+
const {
|
1410
|
+
world,
|
1411
|
+
rigidBodyStates,
|
1412
|
+
physicsOptions,
|
1413
|
+
rigidBodyEvents
|
1414
|
+
} = useRapier();
|
1415
|
+
const mergedOptions = useMemo(() => {
|
1416
|
+
return _objectSpread2(_objectSpread2(_objectSpread2({}, physicsOptions), props), {}, {
|
1417
|
+
children: undefined
|
1418
|
+
});
|
1419
|
+
}, [physicsOptions, props]);
|
1420
|
+
const childColliderProps = useChildColliderProps(ref, mergedOptions); // Create rigidbody
|
1421
|
+
|
1422
|
+
const getInstance = useImperativeInstance(() => {
|
1423
|
+
const desc = rigidBodyDescFromOptions(mergedOptions);
|
1424
|
+
const rigidBody = world.createRigidBody(desc);
|
1425
|
+
const state = createRigidBodyState({
|
1426
|
+
rigidBody,
|
1427
|
+
object: ref.current
|
1428
|
+
});
|
1429
|
+
rigidBodyStates.set(rigidBody.handle, props.transformState ? props.transformState(state) : state);
|
1430
|
+
return rigidBody;
|
1431
|
+
}, rigidBody => {
|
1432
|
+
world.removeRigidBody(rigidBody);
|
1433
|
+
rigidBodyStates.delete(rigidBody.handle);
|
1434
|
+
});
|
1435
|
+
useUpdateRigidBodyOptions(getInstance, mergedOptions, rigidBodyStates);
|
1436
|
+
useRigidBodyEvents(getInstance, mergedOptions, rigidBodyEvents);
|
1437
|
+
useImperativeHandle(forwardedRef, () => getInstance());
|
1438
|
+
const contextValue = useMemo(() => {
|
1439
|
+
return {
|
1440
|
+
ref,
|
1441
|
+
getRigidBody: getInstance,
|
1442
|
+
options: mergedOptions
|
1443
|
+
};
|
1444
|
+
}, [mergedOptions]);
|
1464
1445
|
return /*#__PURE__*/React.createElement(RigidBodyContext.Provider, {
|
1465
1446
|
value: contextValue
|
1466
1447
|
}, /*#__PURE__*/React.createElement("object3D", _extends({
|
1467
|
-
ref:
|
1448
|
+
ref: ref
|
1468
1449
|
}, objectProps, {
|
1469
1450
|
position: position,
|
1470
1451
|
rotation: rotation,
|
@@ -1476,14 +1457,17 @@ const RigidBody = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, ref) => {
|
|
1476
1457
|
}));
|
1477
1458
|
RigidBody.displayName = "RigidBody";
|
1478
1459
|
|
1460
|
+
/**
|
1461
|
+
* A mesh collider is a collider that is automatically generated from the geometry of the children.
|
1462
|
+
* @category Colliders
|
1463
|
+
*/
|
1479
1464
|
const MeshCollider = /*#__PURE__*/memo(props => {
|
1480
1465
|
const {
|
1481
1466
|
children,
|
1482
1467
|
type
|
1483
1468
|
} = props;
|
1484
1469
|
const {
|
1485
|
-
physicsOptions
|
1486
|
-
world
|
1470
|
+
physicsOptions
|
1487
1471
|
} = useRapier();
|
1488
1472
|
const object = useRef(null);
|
1489
1473
|
const {
|
@@ -1597,155 +1581,119 @@ const Debug = /*#__PURE__*/memo(() => {
|
|
1597
1581
|
}, attractor))));
|
1598
1582
|
});
|
1599
1583
|
|
1600
|
-
const _excluded = ["
|
1601
|
-
const InstancedRigidBodies = /*#__PURE__*/forwardRef((props, ref) => {
|
1602
|
-
const {
|
1603
|
-
world,
|
1604
|
-
rigidBodyStates,
|
1605
|
-
physicsOptions,
|
1606
|
-
rigidBodyEvents
|
1607
|
-
} = useRapier();
|
1584
|
+
const _excluded = ["children", "instances", "colliderNodes", "position", "rotation", "quaternion", "scale"];
|
1585
|
+
const InstancedRigidBodies = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, ref) => {
|
1608
1586
|
const object = useRef(null);
|
1587
|
+
const instancedWrapper = useRef(null);
|
1609
1588
|
|
1610
1589
|
const {
|
1611
|
-
|
1612
|
-
|
1613
|
-
|
1590
|
+
// instanced props
|
1591
|
+
children,
|
1592
|
+
instances,
|
1593
|
+
colliderNodes = [],
|
1594
|
+
// wrapper object props
|
1595
|
+
position,
|
1596
|
+
rotation,
|
1597
|
+
quaternion,
|
1598
|
+
scale
|
1614
1599
|
} = props,
|
1615
|
-
|
1600
|
+
rigidBodyProps = _objectWithoutProperties(props, _excluded);
|
1616
1601
|
|
1617
|
-
const
|
1618
|
-
|
1619
|
-
const
|
1620
|
-
|
1621
|
-
|
1622
|
-
}
|
1602
|
+
const rigidBodyApis = useRef([]);
|
1603
|
+
useImperativeHandle(ref, () => rigidBodyApis.current, [instances]);
|
1604
|
+
const childColliderProps = useChildColliderProps(object, _objectSpread2(_objectSpread2({}, props), {}, {
|
1605
|
+
children: undefined
|
1606
|
+
}));
|
1623
1607
|
|
1624
|
-
|
1625
|
-
|
1626
|
-
const mergedOptions = useMemo(() => {
|
1627
|
-
return _objectSpread2(_objectSpread2({}, physicsOptions), options);
|
1628
|
-
}, [physicsOptions, options]);
|
1629
|
-
const childColliderProps = useChildColliderProps(object, mergedOptions);
|
1630
|
-
useLayoutEffect(() => {
|
1631
|
-
object.current.updateWorldMatrix(true, false);
|
1632
|
-
const instances = instancesRefGetter.current();
|
1633
|
-
const invertedWorld = object.current.matrixWorld.clone().invert();
|
1634
|
-
object.current.traverseVisible(mesh => {
|
1635
|
-
if (mesh instanceof InstancedMesh) {
|
1636
|
-
mesh.instanceMatrix.setUsage(DynamicDrawUsage);
|
1637
|
-
const worldScale = mesh.getWorldScale(_scale);
|
1638
|
-
|
1639
|
-
for (let index = 0; index < mesh.count; index++) {
|
1640
|
-
var _options$scales;
|
1641
|
-
|
1642
|
-
const desc = rigidBodyDescFromOptions(props);
|
1643
|
-
const rigidBody = world.createRigidBody(desc);
|
1644
|
-
rigidBodyRefs.current.push(rigidBody);
|
1645
|
-
const scale = ((_options$scales = options.scales) === null || _options$scales === void 0 ? void 0 : _options$scales[index]) || [1, 1, 1];
|
1646
|
-
const instanceScale = worldScale.clone().multiply(vectorArrayToVector3(scale));
|
1647
|
-
rigidBodyStates.set(rigidBody.handle, createRigidBodyState({
|
1648
|
-
rigidBody,
|
1649
|
-
object: mesh,
|
1650
|
-
setMatrix: matrix => mesh.setMatrixAt(index, matrix),
|
1651
|
-
getMatrix: matrix => {
|
1652
|
-
mesh.getMatrixAt(index, matrix);
|
1653
|
-
return matrix;
|
1654
|
-
},
|
1655
|
-
worldScale: instanceScale
|
1656
|
-
}));
|
1657
|
-
const [x, y, z] = (positions === null || positions === void 0 ? void 0 : positions[index]) || [0, 0, 0];
|
1658
|
-
const [rx, ry, rz] = (rotations === null || rotations === void 0 ? void 0 : rotations[index]) || [0, 0, 0];
|
1608
|
+
const getInstancedMesh = () => {
|
1609
|
+
const firstChild = instancedWrapper.current.children[0];
|
1659
1610
|
|
1660
|
-
|
1611
|
+
if (firstChild && "isInstancedMesh" in firstChild) {
|
1612
|
+
return firstChild;
|
1613
|
+
}
|
1661
1614
|
|
1662
|
-
|
1615
|
+
return undefined;
|
1616
|
+
};
|
1663
1617
|
|
1664
|
-
|
1618
|
+
useEffect(() => {
|
1619
|
+
const instancedMesh = getInstancedMesh();
|
1665
1620
|
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1671
|
-
|
1672
|
-
}
|
1621
|
+
if (instancedMesh) {
|
1622
|
+
instancedMesh.instanceMatrix.setUsage(DynamicDrawUsage);
|
1623
|
+
} else {
|
1624
|
+
console.warn("InstancedRigidBodies expects exactly one child, which must be an InstancedMesh");
|
1625
|
+
}
|
1626
|
+
}, []); // Update the RigidBodyStates whenever the instances change
|
1673
1627
|
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1678
|
-
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1628
|
+
const applyInstancedState = (state, index) => {
|
1629
|
+
const instancedMesh = getInstancedMesh();
|
1630
|
+
|
1631
|
+
if (instancedMesh) {
|
1632
|
+
return _objectSpread2(_objectSpread2({}, state), {}, {
|
1633
|
+
getMatrix: matrix => {
|
1634
|
+
instancedMesh.getMatrixAt(index, matrix);
|
1635
|
+
return matrix;
|
1636
|
+
},
|
1637
|
+
setMatrix: matrix => {
|
1638
|
+
instancedMesh.setMatrixAt(index, matrix);
|
1639
|
+
instancedMesh.instanceMatrix.needsUpdate = true;
|
1640
|
+
},
|
1641
|
+
meshType: "instancedMesh"
|
1686
1642
|
});
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
}
|
1691
|
-
|
1692
|
-
|
1693
|
-
useUpdateRigidBodyOptions(rigidBodyRefs, mergedOptions, rigidBodyStates, false);
|
1694
|
-
useRigidBodyEvents(rigidBodyRefs, mergedOptions, rigidBodyEvents);
|
1695
|
-
const contextValue = useMemo(() => {
|
1696
|
-
return {
|
1697
|
-
ref: object,
|
1698
|
-
api,
|
1699
|
-
options: mergedOptions
|
1700
|
-
};
|
1701
|
-
}, [api, mergedOptions]);
|
1702
|
-
return /*#__PURE__*/React.createElement(RigidBodyContext.Provider, {
|
1703
|
-
value: contextValue
|
1704
|
-
}, /*#__PURE__*/React.createElement("object3D", {
|
1643
|
+
}
|
1644
|
+
|
1645
|
+
return state;
|
1646
|
+
};
|
1647
|
+
|
1648
|
+
return /*#__PURE__*/React.createElement("object3D", _extends({
|
1705
1649
|
ref: object
|
1706
|
-
},
|
1650
|
+
}, rigidBodyProps, {
|
1651
|
+
position: position,
|
1652
|
+
rotation: rotation,
|
1653
|
+
quaternion: quaternion,
|
1654
|
+
scale: scale
|
1655
|
+
}), /*#__PURE__*/React.createElement("object3D", {
|
1656
|
+
ref: instancedWrapper
|
1657
|
+
}, children), instances === null || instances === void 0 ? void 0 : instances.map((instance, index) => /*#__PURE__*/React.createElement(RigidBody, _extends({}, rigidBodyProps, instance, {
|
1658
|
+
ref: body => rigidBodyApis.current[index] = body,
|
1659
|
+
transformState: state => applyInstancedState(state, index)
|
1660
|
+
}), /*#__PURE__*/React.createElement(React.Fragment, null, colliderNodes.map((node, index) => /*#__PURE__*/React.createElement(Fragment, {
|
1707
1661
|
key: index
|
1708
|
-
},
|
1709
|
-
|
1662
|
+
}, node)), childColliderProps.map((colliderProps, colliderIndex) => /*#__PURE__*/React.createElement(AnyCollider, _extends({
|
1663
|
+
key: colliderIndex
|
1664
|
+
}, colliderProps)))))));
|
1665
|
+
}));
|
1710
1666
|
InstancedRigidBodies.displayName = "InstancedRigidBodies";
|
1711
1667
|
|
1668
|
+
/**
|
1669
|
+
* @internal
|
1670
|
+
*/
|
1671
|
+
|
1712
1672
|
const useImpulseJoint = (body1, body2, params) => {
|
1713
1673
|
const {
|
1714
1674
|
world
|
1715
1675
|
} = useRapier();
|
1716
1676
|
const jointRef = useRef();
|
1717
|
-
|
1718
|
-
if (
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
}
|
1677
|
+
useImperativeInstance(() => {
|
1678
|
+
if (body1.current && body2.current) {
|
1679
|
+
const newJoint = world.createImpulseJoint(params, body1.current, body2.current);
|
1680
|
+
jointRef.current = newJoint;
|
1681
|
+
return newJoint;
|
1682
|
+
}
|
1683
|
+
}, joint => {
|
1684
|
+
if (joint) {
|
1685
|
+
jointRef.current = undefined;
|
1686
|
+
world.removeImpulseJoint(joint);
|
1728
1687
|
}
|
1729
|
-
|
1730
|
-
return jointRef.current;
|
1731
1688
|
});
|
1732
|
-
|
1733
|
-
const joint = getJointRef.current();
|
1734
|
-
return () => {
|
1735
|
-
if (joint) {
|
1736
|
-
world.removeImpulseJoint(joint);
|
1737
|
-
jointRef.current = undefined;
|
1738
|
-
}
|
1739
|
-
};
|
1740
|
-
}, []);
|
1741
|
-
const api = useMemo(() => createJointApi(getJointRef), []);
|
1742
|
-
return api;
|
1689
|
+
return jointRef;
|
1743
1690
|
};
|
1744
1691
|
/**
|
1745
|
-
*
|
1746
1692
|
* A fixed joint ensures that two rigid-bodies don't move relative to each other.
|
1747
1693
|
* Fixed joints are characterized by one local frame (represented by an isometry) on each rigid-body.
|
1748
1694
|
* The fixed-joint makes these frames coincide in world-space.
|
1695
|
+
*
|
1696
|
+
* @category Hooks - Joints
|
1749
1697
|
*/
|
1750
1698
|
|
1751
1699
|
const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor, body2LocalFrame]) => {
|
@@ -1759,6 +1707,8 @@ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor,
|
|
1759
1707
|
* translational motion at this points). This is typically used to simulate ragdolls arms, pendulums, etc.
|
1760
1708
|
* They are characterized by one local anchor on each rigid-body. Each anchor represents the location of the
|
1761
1709
|
* points that need to coincide on the local-space of each rigid-body.
|
1710
|
+
*
|
1711
|
+
* @category Hooks - Joints
|
1762
1712
|
*/
|
1763
1713
|
|
1764
1714
|
const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
@@ -1771,6 +1721,8 @@ const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
|
1771
1721
|
* The revolute joint prevents any relative movement between two rigid-bodies, except for relative
|
1772
1722
|
* rotations along one axis. This is typically used to simulate wheels, fans, etc.
|
1773
1723
|
* They are characterized by one local anchor as well as one local axis on each rigid-body.
|
1724
|
+
*
|
1725
|
+
* @category Hooks - Joints
|
1774
1726
|
*/
|
1775
1727
|
|
1776
1728
|
const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis, limits]) => {
|
@@ -1790,6 +1742,8 @@ const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis, limits]
|
|
1790
1742
|
* The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
|
1791
1743
|
* It is characterized by one local anchor as well as one local axis on each rigid-body. In 3D, an optional
|
1792
1744
|
* local tangent axis can be specified for each rigid-body.
|
1745
|
+
*
|
1746
|
+
* @category Hooks - Joints
|
1793
1747
|
*/
|
1794
1748
|
|
1795
1749
|
const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis, limits]) => {
|
@@ -1842,4 +1796,4 @@ const interactionGroups = (memberships, filters) => (bitmask(memberships) << 16)
|
|
1842
1796
|
|
1843
1797
|
const bitmask = groups => [groups].flat().reduce((acc, layer) => acc | 1 << layer, 0);
|
1844
1798
|
|
1845
|
-
export { AnyCollider, Attractor, BallCollider, CapsuleCollider, ConeCollider, ConvexHullCollider, CuboidCollider, CylinderCollider, Debug, HeightfieldCollider, InstancedRigidBodies, MeshCollider, Physics, RigidBody, RoundCuboidCollider, TrimeshCollider, interactionGroups, useAfterPhysicsStep, useBeforePhysicsStep, useFixedJoint, useImpulseJoint, usePrismaticJoint, useRapier, useRevoluteJoint, useSphericalJoint };
|
1799
|
+
export { AnyCollider, Attractor, BallCollider, CapsuleCollider, ConeCollider, ConvexHullCollider, CuboidCollider, CylinderCollider, Debug, HeightfieldCollider, InstancedRigidBodies, MeshCollider, Physics, RigidBody, RoundCuboidCollider, TrimeshCollider, euler, interactionGroups, quat, useAfterPhysicsStep, useBeforePhysicsStep, useFixedJoint, useImpulseJoint, usePrismaticJoint, useRapier, useRevoluteJoint, useSphericalJoint, vec3 };
|