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