@react-three/rapier 0.8.2 → 0.10.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/Attractor.d.ts +51 -0
- package/dist/declarations/src/MeshCollider.d.ts +4 -1
- package/dist/declarations/src/Physics.d.ts +43 -6
- package/dist/declarations/src/index.d.ts +2 -1
- package/dist/declarations/src/{bitmasks.d.ts → interaction-groups.d.ts} +0 -0
- package/dist/declarations/src/types.d.ts +35 -9
- package/dist/declarations/src/utils-collider.d.ts +1 -1
- package/dist/react-three-rapier.cjs.dev.js +946 -706
- package/dist/react-three-rapier.cjs.prod.js +946 -706
- package/dist/react-three-rapier.esm.js +948 -709
- package/package.json +1 -1
- package/readme.md +143 -39
@@ -1,10 +1,51 @@
|
|
1
|
-
import {
|
1
|
+
import { ColliderDesc, ActiveEvents, RigidBodyDesc, EventQueue } from '@dimforge/rapier3d-compat';
|
2
2
|
export { CoefficientCombineRule, Collider as RapierCollider, RigidBody as RapierRigidBody } from '@dimforge/rapier3d-compat';
|
3
|
-
import
|
4
|
-
import {
|
5
|
-
import { useFrame } from '@react-three/fiber';
|
3
|
+
import { useFrame, useThree } from '@react-three/fiber';
|
4
|
+
import React, { useMemo, useEffect, useContext, useState, useRef, memo, createContext, useCallback, forwardRef, useImperativeHandle, useLayoutEffect } from 'react';
|
6
5
|
import { Quaternion, Euler, Vector3, Object3D, Matrix4, MathUtils, InstancedMesh, BufferAttribute, DynamicDrawUsage } from 'three';
|
7
|
-
import {
|
6
|
+
import { useAsset } from 'use-asset';
|
7
|
+
import { mergeVertices, VertexNormalsHelper } from 'three-stdlib';
|
8
|
+
|
9
|
+
function _defineProperty(obj, key, value) {
|
10
|
+
if (key in obj) {
|
11
|
+
Object.defineProperty(obj, key, {
|
12
|
+
value: value,
|
13
|
+
enumerable: true,
|
14
|
+
configurable: true,
|
15
|
+
writable: true
|
16
|
+
});
|
17
|
+
} else {
|
18
|
+
obj[key] = value;
|
19
|
+
}
|
20
|
+
|
21
|
+
return obj;
|
22
|
+
}
|
23
|
+
|
24
|
+
function ownKeys(object, enumerableOnly) {
|
25
|
+
var keys = Object.keys(object);
|
26
|
+
|
27
|
+
if (Object.getOwnPropertySymbols) {
|
28
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
29
|
+
enumerableOnly && (symbols = symbols.filter(function (sym) {
|
30
|
+
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
31
|
+
})), keys.push.apply(keys, symbols);
|
32
|
+
}
|
33
|
+
|
34
|
+
return keys;
|
35
|
+
}
|
36
|
+
|
37
|
+
function _objectSpread2(target) {
|
38
|
+
for (var i = 1; i < arguments.length; i++) {
|
39
|
+
var source = null != arguments[i] ? arguments[i] : {};
|
40
|
+
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
|
41
|
+
_defineProperty(target, key, source[key]);
|
42
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
|
43
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
44
|
+
});
|
45
|
+
}
|
46
|
+
|
47
|
+
return target;
|
48
|
+
}
|
8
49
|
|
9
50
|
const _quaternion = new Quaternion();
|
10
51
|
new Euler();
|
@@ -213,375 +254,304 @@ const createJointApi = ref => {
|
|
213
254
|
};
|
214
255
|
};
|
215
256
|
|
216
|
-
const
|
217
|
-
|
218
|
-
const importRapier = async () => {
|
219
|
-
let r = await import('@dimforge/rapier3d-compat');
|
220
|
-
await r.init();
|
221
|
-
return r;
|
222
|
-
};
|
223
|
-
|
224
|
-
const Physics = ({
|
225
|
-
colliders: _colliders = "cuboid",
|
226
|
-
gravity: _gravity = [0, -9.81, 0],
|
227
|
-
children,
|
228
|
-
timeStep: _timeStep = 1 / 60,
|
229
|
-
paused: _paused = false,
|
230
|
-
updatePriority
|
231
|
-
}) => {
|
232
|
-
const rapier = useAsset(importRapier);
|
233
|
-
const worldRef = useRef();
|
234
|
-
const getWorldRef = useRef(() => {
|
235
|
-
if (!worldRef.current) {
|
236
|
-
const world = new rapier.World(vectorArrayToVector3(_gravity));
|
237
|
-
worldRef.current = world;
|
238
|
-
}
|
239
|
-
|
240
|
-
return worldRef.current;
|
241
|
-
});
|
242
|
-
const [rigidBodyStates] = useState(() => new Map());
|
243
|
-
const [colliderStates] = useState(() => new Map());
|
244
|
-
const [rigidBodyEvents] = useState(() => new Map());
|
245
|
-
const [colliderEvents] = useState(() => new Map());
|
246
|
-
const [eventQueue] = useState(() => new EventQueue(false)); // Init world
|
247
|
-
|
248
|
-
useEffect(() => {
|
249
|
-
const world = getWorldRef.current();
|
250
|
-
return () => {
|
251
|
-
if (world) {
|
252
|
-
world.free();
|
253
|
-
worldRef.current = undefined;
|
254
|
-
}
|
255
|
-
};
|
256
|
-
}, []); // Update gravity
|
257
|
+
const scaleColliderArgs = (shape, args, scale) => {
|
258
|
+
const newArgs = args.slice(); // Heightfield uses a vector
|
257
259
|
|
258
|
-
|
259
|
-
const
|
260
|
+
if (shape === "heightfield") {
|
261
|
+
const s = newArgs[3];
|
262
|
+
s.x *= scale.x;
|
263
|
+
s.x *= scale.y;
|
264
|
+
s.x *= scale.z;
|
265
|
+
return newArgs;
|
266
|
+
} // Trimesh and convex scale the vertices
|
260
267
|
|
261
|
-
if (world) {
|
262
|
-
world.gravity = vectorArrayToVector3(_gravity);
|
263
|
-
}
|
264
|
-
}, [_gravity]);
|
265
|
-
const [steppingState] = useState({
|
266
|
-
accumulator: 0
|
267
|
-
});
|
268
|
-
/* Check if the timestep is supposed to be variable. We'll do this here
|
269
|
-
once so we don't have to string-check every frame. */
|
270
268
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
/**
|
276
|
-
* Fixed timeStep simulation progression
|
277
|
-
* @see https://gafferongames.com/post/fix_your_timestep/
|
278
|
-
*/
|
269
|
+
if (shape === "trimesh" || shape === "convexHull") {
|
270
|
+
newArgs[0] = scaleVertices(newArgs[0], scale);
|
271
|
+
return newArgs;
|
272
|
+
} // Prepfill with some extra
|
279
273
|
|
280
|
-
const clampedDelta = MathUtils.clamp(dt, 0, 0.2);
|
281
274
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
// Increase accumulator
|
275
|
+
const scaleArray = [scale.x, scale.y, scale.z, scale.x, scale.x];
|
276
|
+
return newArgs.map((arg, index) => scaleArray[index] * arg);
|
277
|
+
};
|
278
|
+
const createColliderFromOptions = (options, world, scale, rigidBody) => {
|
279
|
+
const scaledArgs = scaleColliderArgs(options.shape, options.args, scale); // @ts-ignore
|
288
280
|
|
289
|
-
|
281
|
+
const desc = ColliderDesc[options.shape](...scaledArgs);
|
282
|
+
return world.createCollider(desc, rigidBody);
|
283
|
+
};
|
284
|
+
const massPropertiesConflictError = "Please pick ONLY ONE of the `density`, `mass` and `massProperties` options.";
|
290
285
|
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
}
|
296
|
-
}
|
286
|
+
const setColliderMassOptions = (collider, options) => {
|
287
|
+
if (options.density !== undefined) {
|
288
|
+
if (options.mass !== undefined || options.massProperties !== undefined) {
|
289
|
+
throw new Error(massPropertiesConflictError);
|
297
290
|
}
|
298
291
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
const rigidBody = world.getRigidBody(handle);
|
303
|
-
const events = rigidBodyEvents.get(handle);
|
292
|
+
collider.setDensity(options.density);
|
293
|
+
return;
|
294
|
+
}
|
304
295
|
|
305
|
-
|
306
|
-
|
307
|
-
|
296
|
+
if (options.mass !== undefined) {
|
297
|
+
if (options.massProperties !== undefined) {
|
298
|
+
throw new Error(massPropertiesConflictError);
|
299
|
+
}
|
308
300
|
|
309
|
-
|
310
|
-
|
301
|
+
collider.setMass(options.mass);
|
302
|
+
return;
|
303
|
+
}
|
311
304
|
|
312
|
-
|
313
|
-
|
305
|
+
if (options.massProperties !== undefined) {
|
306
|
+
collider.setMassProperties(options.massProperties.mass, options.massProperties.centerOfMass, options.massProperties.principalAngularInertia, options.massProperties.angularInertiaLocalFrame);
|
307
|
+
}
|
308
|
+
};
|
314
309
|
|
315
|
-
|
316
|
-
|
310
|
+
const mutableColliderOptions = {
|
311
|
+
sensor: (collider, value) => {
|
312
|
+
collider.setSensor(value);
|
313
|
+
},
|
314
|
+
collisionGroups: (collider, value) => {
|
315
|
+
collider.setCollisionGroups(value);
|
316
|
+
},
|
317
|
+
solverGroups: (collider, value) => {
|
318
|
+
collider.setSolverGroups(value);
|
319
|
+
},
|
320
|
+
friction: (collider, value) => {
|
321
|
+
collider.setFriction(value);
|
322
|
+
},
|
323
|
+
frictionCombineRule: (collider, value) => {
|
324
|
+
collider.setFrictionCombineRule(value);
|
325
|
+
},
|
326
|
+
restitution: (collider, value) => {
|
327
|
+
collider.setRestitution(value);
|
328
|
+
},
|
329
|
+
restitutionCombineRule: (collider, value) => {
|
330
|
+
collider.setRestitutionCombineRule(value);
|
331
|
+
},
|
332
|
+
// To make sure the options all mutalbe options are listed
|
333
|
+
quaternion: () => {},
|
334
|
+
position: () => {},
|
335
|
+
rotation: () => {},
|
336
|
+
scale: () => {}
|
337
|
+
};
|
338
|
+
const mutableColliderOptionKeys = Object.keys(mutableColliderOptions);
|
339
|
+
const setColliderOptions = (collider, options, states) => {
|
340
|
+
const state = states.get(collider.handle);
|
317
341
|
|
318
|
-
|
319
|
-
|
342
|
+
if (state) {
|
343
|
+
var _state$worldParent;
|
320
344
|
|
321
|
-
|
322
|
-
|
323
|
-
|
345
|
+
// Update collider position based on the object's position
|
346
|
+
const parentWorldScale = state.object.parent.getWorldScale(_vector3);
|
347
|
+
const parentInvertedWorldMatrix = (_state$worldParent = state.worldParent) === null || _state$worldParent === void 0 ? void 0 : _state$worldParent.matrixWorld.clone().invert();
|
348
|
+
state.object.updateWorldMatrix(true, false);
|
324
349
|
|
325
|
-
|
326
|
-
let r = rigidBody.rotation(); // Get new position
|
350
|
+
_matrix4.copy(state.object.matrixWorld);
|
327
351
|
|
328
|
-
|
352
|
+
if (parentInvertedWorldMatrix) {
|
353
|
+
_matrix4.premultiply(parentInvertedWorldMatrix);
|
354
|
+
}
|
329
355
|
|
330
|
-
|
331
|
-
state.setMatrix(_matrix4);
|
332
|
-
state.object.instanceMatrix.needsUpdate = true;
|
333
|
-
} else {
|
334
|
-
// Interpolate from last position
|
335
|
-
state.object.position.lerp(_position, interpolationAlpha);
|
336
|
-
state.object.quaternion.slerp(_rotation, interpolationAlpha);
|
337
|
-
}
|
338
|
-
});
|
339
|
-
eventQueue.drainCollisionEvents((handle1, handle2, started) => {
|
340
|
-
var _collider1$parent, _collider2$parent;
|
356
|
+
_matrix4.decompose(_position, _rotation, _scale);
|
341
357
|
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
358
|
+
if (collider.parent()) {
|
359
|
+
collider.setTranslationWrtParent({
|
360
|
+
x: _position.x * parentWorldScale.x,
|
361
|
+
y: _position.y * parentWorldScale.y,
|
362
|
+
z: _position.z * parentWorldScale.z
|
363
|
+
});
|
364
|
+
collider.setRotationWrtParent(_rotation);
|
365
|
+
} else {
|
366
|
+
collider.setTranslation({
|
367
|
+
x: _position.x * parentWorldScale.x,
|
368
|
+
y: _position.y * parentWorldScale.y,
|
369
|
+
z: _position.z * parentWorldScale.z
|
370
|
+
});
|
371
|
+
collider.setRotation(_rotation);
|
372
|
+
}
|
346
373
|
|
347
|
-
|
348
|
-
|
374
|
+
mutableColliderOptionKeys.forEach(key => {
|
375
|
+
if (key in options) {
|
376
|
+
const option = options[key];
|
377
|
+
mutableColliderOptions[key](collider, // @ts-ignore Option does not want to fit into the function, but it will
|
378
|
+
option, options);
|
349
379
|
}
|
380
|
+
}); // handle mass separately, because the assignments
|
381
|
+
// are exclusive.
|
350
382
|
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
383
|
+
setColliderMassOptions(collider, options);
|
384
|
+
}
|
385
|
+
};
|
386
|
+
const useUpdateColliderOptions = (collidersRef, props, states) => {
|
387
|
+
// TODO: Improve this, split each prop into its own effect
|
388
|
+
const mutablePropsAsFlatArray = useMemo(() => mutableColliderOptionKeys.flatMap(key => {
|
389
|
+
return vectorToTuple(props[key]);
|
390
|
+
}), [props]);
|
391
|
+
useEffect(() => {
|
392
|
+
collidersRef.current.forEach(collider => {
|
393
|
+
setColliderOptions(collider, props, states);
|
394
|
+
});
|
395
|
+
}, mutablePropsAsFlatArray);
|
396
|
+
};
|
361
397
|
|
362
|
-
|
363
|
-
|
364
|
-
|
398
|
+
const isChildOfMeshCollider = child => {
|
399
|
+
let flag = false;
|
400
|
+
child.traverseAncestors(a => {
|
401
|
+
if (a.userData.r3RapierType === "MeshCollider") flag = true;
|
402
|
+
});
|
403
|
+
return flag;
|
404
|
+
};
|
365
405
|
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
colliderObject: collider1State === null || collider1State === void 0 ? void 0 : collider1State.object,
|
379
|
-
rigidBodyObject: rigidBody1State === null || rigidBody1State === void 0 ? void 0 : rigidBody1State.object,
|
380
|
-
manifold,
|
381
|
-
flipped
|
382
|
-
});
|
383
|
-
/* Collider events */
|
384
|
-
|
385
|
-
collider1Events === null || collider1Events === void 0 ? void 0 : (_collider1Events$onCo = collider1Events.onCollisionEnter) === null || _collider1Events$onCo === void 0 ? void 0 : _collider1Events$onCo.call(collider1Events, {
|
386
|
-
rigidBody: rigidBody2,
|
387
|
-
collider: collider2,
|
388
|
-
colliderObject: collider2State === null || collider2State === void 0 ? void 0 : collider2State.object,
|
389
|
-
rigidBodyObject: rigidBody2State === null || rigidBody2State === void 0 ? void 0 : rigidBody2State.object,
|
390
|
-
manifold,
|
391
|
-
flipped
|
392
|
-
});
|
393
|
-
collider2Events === null || collider2Events === void 0 ? void 0 : (_collider2Events$onCo = collider2Events.onCollisionEnter) === null || _collider2Events$onCo === void 0 ? void 0 : _collider2Events$onCo.call(collider2Events, {
|
394
|
-
rigidBody: rigidBody1,
|
395
|
-
collider: collider1,
|
396
|
-
colliderObject: collider1State === null || collider1State === void 0 ? void 0 : collider1State.object,
|
397
|
-
rigidBodyObject: rigidBody1State === null || rigidBody1State === void 0 ? void 0 : rigidBody1State.object,
|
398
|
-
manifold,
|
399
|
-
flipped
|
400
|
-
});
|
401
|
-
});
|
402
|
-
} else {
|
403
|
-
var _rigidBody1Events$onC2, _rigidBody2Events$onC2, _collider1Events$onCo2, _collider2Events$onCo2;
|
404
|
-
|
405
|
-
rigidBody1Events === null || rigidBody1Events === void 0 ? void 0 : (_rigidBody1Events$onC2 = rigidBody1Events.onCollisionExit) === null || _rigidBody1Events$onC2 === void 0 ? void 0 : _rigidBody1Events$onC2.call(rigidBody1Events, {
|
406
|
-
rigidBody: rigidBody2,
|
407
|
-
collider: collider2
|
408
|
-
});
|
409
|
-
rigidBody2Events === null || rigidBody2Events === void 0 ? void 0 : (_rigidBody2Events$onC2 = rigidBody2Events.onCollisionExit) === null || _rigidBody2Events$onC2 === void 0 ? void 0 : _rigidBody2Events$onC2.call(rigidBody2Events, {
|
410
|
-
rigidBody: rigidBody1,
|
411
|
-
collider: collider1
|
412
|
-
});
|
413
|
-
collider1Events === null || collider1Events === void 0 ? void 0 : (_collider1Events$onCo2 = collider1Events.onCollisionExit) === null || _collider1Events$onCo2 === void 0 ? void 0 : _collider1Events$onCo2.call(collider1Events, {
|
414
|
-
rigidBody: rigidBody2,
|
415
|
-
collider: collider2
|
416
|
-
});
|
417
|
-
collider2Events === null || collider2Events === void 0 ? void 0 : (_collider2Events$onCo2 = collider2Events.onCollisionExit) === null || _collider2Events$onCo2 === void 0 ? void 0 : _collider2Events$onCo2.call(collider2Events, {
|
418
|
-
rigidBody: rigidBody1,
|
419
|
-
collider: collider1
|
420
|
-
});
|
421
|
-
} // Sensor Intersections
|
422
|
-
|
423
|
-
|
424
|
-
if (started) {
|
425
|
-
if (world.intersectionPair(collider1, collider2)) {
|
426
|
-
var _rigidBody1Events$onI, _rigidBody2Events$onI, _collider1Events$onIn, _collider2Events$onIn;
|
427
|
-
|
428
|
-
rigidBody1Events === null || rigidBody1Events === void 0 ? void 0 : (_rigidBody1Events$onI = rigidBody1Events.onIntersectionEnter) === null || _rigidBody1Events$onI === void 0 ? void 0 : _rigidBody1Events$onI.call(rigidBody1Events, {
|
429
|
-
rigidBody: rigidBody2,
|
430
|
-
collider: collider2,
|
431
|
-
colliderObject: collider2State === null || collider2State === void 0 ? void 0 : collider2State.object,
|
432
|
-
rigidBodyObject: rigidBody2State === null || rigidBody2State === void 0 ? void 0 : rigidBody2State.object
|
433
|
-
});
|
434
|
-
rigidBody2Events === null || rigidBody2Events === void 0 ? void 0 : (_rigidBody2Events$onI = rigidBody2Events.onIntersectionEnter) === null || _rigidBody2Events$onI === void 0 ? void 0 : _rigidBody2Events$onI.call(rigidBody2Events, {
|
435
|
-
rigidBody: rigidBody1,
|
436
|
-
collider: collider1,
|
437
|
-
colliderObject: collider1State === null || collider1State === void 0 ? void 0 : collider1State.object,
|
438
|
-
rigidBodyObject: rigidBody1State === null || rigidBody1State === void 0 ? void 0 : rigidBody1State.object
|
439
|
-
});
|
440
|
-
collider1Events === null || collider1Events === void 0 ? void 0 : (_collider1Events$onIn = collider1Events.onIntersectionEnter) === null || _collider1Events$onIn === void 0 ? void 0 : _collider1Events$onIn.call(collider1Events, {
|
441
|
-
rigidBody: rigidBody2,
|
442
|
-
collider: collider2,
|
443
|
-
colliderObject: collider2State === null || collider2State === void 0 ? void 0 : collider2State.object,
|
444
|
-
rigidBodyObject: rigidBody2State === null || rigidBody2State === void 0 ? void 0 : rigidBody2State.object
|
445
|
-
});
|
446
|
-
collider2Events === null || collider2Events === void 0 ? void 0 : (_collider2Events$onIn = collider2Events.onIntersectionEnter) === null || _collider2Events$onIn === void 0 ? void 0 : _collider2Events$onIn.call(collider2Events, {
|
447
|
-
rigidBody: rigidBody1,
|
448
|
-
collider: collider1,
|
449
|
-
colliderObject: collider1State === null || collider1State === void 0 ? void 0 : collider1State.object,
|
450
|
-
rigidBodyObject: rigidBody1State === null || rigidBody1State === void 0 ? void 0 : rigidBody1State.object
|
451
|
-
});
|
452
|
-
}
|
453
|
-
} else {
|
454
|
-
var _rigidBody1Events$onI2, _rigidBody2Events$onI2, _collider1Events$onIn2, _collider2Events$onIn2;
|
455
|
-
|
456
|
-
rigidBody1Events === null || rigidBody1Events === void 0 ? void 0 : (_rigidBody1Events$onI2 = rigidBody1Events.onIntersectionExit) === null || _rigidBody1Events$onI2 === void 0 ? void 0 : _rigidBody1Events$onI2.call(rigidBody1Events, {
|
457
|
-
rigidBody: rigidBody2,
|
458
|
-
collider: collider2
|
459
|
-
});
|
460
|
-
rigidBody2Events === null || rigidBody2Events === void 0 ? void 0 : (_rigidBody2Events$onI2 = rigidBody2Events.onIntersectionExit) === null || _rigidBody2Events$onI2 === void 0 ? void 0 : _rigidBody2Events$onI2.call(rigidBody2Events, {
|
461
|
-
rigidBody: rigidBody1,
|
462
|
-
collider: collider1
|
463
|
-
});
|
464
|
-
collider1Events === null || collider1Events === void 0 ? void 0 : (_collider1Events$onIn2 = collider1Events.onIntersectionExit) === null || _collider1Events$onIn2 === void 0 ? void 0 : _collider1Events$onIn2.call(collider1Events, {
|
465
|
-
rigidBody: rigidBody2,
|
466
|
-
collider: collider2
|
467
|
-
});
|
468
|
-
collider2Events === null || collider2Events === void 0 ? void 0 : (_collider2Events$onIn2 = collider2Events.onIntersectionExit) === null || _collider2Events$onIn2 === void 0 ? void 0 : _collider2Events$onIn2.call(collider2Events, {
|
469
|
-
rigidBody: rigidBody1,
|
470
|
-
collider: collider1
|
471
|
-
});
|
472
|
-
}
|
473
|
-
});
|
474
|
-
}, updatePriority);
|
475
|
-
const api = useMemo(() => createWorldApi(getWorldRef), []);
|
476
|
-
const context = useMemo(() => ({
|
477
|
-
rapier,
|
478
|
-
world: api,
|
479
|
-
physicsOptions: {
|
480
|
-
colliders: _colliders,
|
481
|
-
gravity: _gravity
|
482
|
-
},
|
483
|
-
rigidBodyStates,
|
484
|
-
colliderStates,
|
485
|
-
rigidBodyEvents,
|
486
|
-
colliderEvents,
|
487
|
-
isPaused: _paused
|
488
|
-
}), [_paused]);
|
489
|
-
return /*#__PURE__*/React.createElement(RapierContext.Provider, {
|
490
|
-
value: context
|
491
|
-
}, children);
|
406
|
+
const createColliderState = (collider, object, rigidBodyObject) => {
|
407
|
+
return {
|
408
|
+
collider,
|
409
|
+
worldParent: rigidBodyObject || undefined,
|
410
|
+
object
|
411
|
+
};
|
412
|
+
};
|
413
|
+
const autoColliderMap = {
|
414
|
+
cuboid: "cuboid",
|
415
|
+
ball: "ball",
|
416
|
+
hull: "convexHull",
|
417
|
+
trimesh: "trimesh"
|
492
418
|
};
|
419
|
+
const createColliderPropsFromChildren = ({
|
420
|
+
object,
|
421
|
+
ignoreMeshColliders: _ignoreMeshColliders = true,
|
422
|
+
options
|
423
|
+
}) => {
|
424
|
+
const colliderProps = [];
|
425
|
+
object.updateWorldMatrix(true, false);
|
426
|
+
const invertedParentMatrixWorld = object.matrixWorld.clone().invert();
|
493
427
|
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
428
|
+
const colliderFromChild = child => {
|
429
|
+
if ("isMesh" in child) {
|
430
|
+
if (_ignoreMeshColliders && isChildOfMeshCollider(child)) return;
|
431
|
+
const worldScale = child.getWorldScale(_scale);
|
432
|
+
const shape = autoColliderMap[options.colliders || "cuboid"];
|
433
|
+
child.updateWorldMatrix(true, false);
|
498
434
|
|
499
|
-
|
500
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
501
|
-
target[key] = source[key];
|
502
|
-
}
|
503
|
-
}
|
504
|
-
}
|
435
|
+
_matrix4.copy(child.matrixWorld).premultiply(invertedParentMatrixWorld).decompose(_position, _rotation, _scale);
|
505
436
|
|
506
|
-
|
437
|
+
const rotationEuler = new Euler().setFromQuaternion(_rotation, "XYZ");
|
438
|
+
const {
|
439
|
+
geometry
|
440
|
+
} = child;
|
441
|
+
const {
|
442
|
+
args,
|
443
|
+
offset
|
444
|
+
} = getColliderArgsFromGeometry(geometry, options.colliders || "cuboid");
|
445
|
+
colliderProps.push(_objectSpread2(_objectSpread2({}, options), {}, {
|
446
|
+
args: args,
|
447
|
+
shape: shape,
|
448
|
+
rotation: [rotationEuler.x, rotationEuler.y, rotationEuler.z],
|
449
|
+
position: [_position.x + offset.x * worldScale.x, _position.y + offset.y * worldScale.y, _position.z + offset.z * worldScale.z],
|
450
|
+
scale: [worldScale.x, worldScale.y, worldScale.z]
|
451
|
+
}));
|
452
|
+
}
|
507
453
|
};
|
508
|
-
return _extends.apply(this, arguments);
|
509
|
-
}
|
510
|
-
|
511
|
-
function _objectWithoutPropertiesLoose(source, excluded) {
|
512
|
-
if (source == null) return {};
|
513
|
-
var target = {};
|
514
|
-
var sourceKeys = Object.keys(source);
|
515
|
-
var key, i;
|
516
454
|
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
455
|
+
if (options.includeInvisible) {
|
456
|
+
object.traverse(colliderFromChild);
|
457
|
+
} else {
|
458
|
+
object.traverseVisible(colliderFromChild);
|
521
459
|
}
|
522
460
|
|
523
|
-
return
|
524
|
-
}
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
461
|
+
return colliderProps;
|
462
|
+
};
|
463
|
+
const getColliderArgsFromGeometry = (geometry, colliders) => {
|
464
|
+
switch (colliders) {
|
465
|
+
case "cuboid":
|
466
|
+
{
|
467
|
+
geometry.computeBoundingBox();
|
468
|
+
const {
|
469
|
+
boundingBox
|
470
|
+
} = geometry;
|
471
|
+
const size = boundingBox.getSize(new Vector3());
|
472
|
+
return {
|
473
|
+
args: [size.x / 2, size.y / 2, size.z / 2],
|
474
|
+
offset: boundingBox.getCenter(new Vector3())
|
475
|
+
};
|
476
|
+
}
|
530
477
|
|
531
|
-
|
532
|
-
|
478
|
+
case "ball":
|
479
|
+
{
|
480
|
+
geometry.computeBoundingSphere();
|
481
|
+
const {
|
482
|
+
boundingSphere
|
483
|
+
} = geometry;
|
484
|
+
const radius = boundingSphere.radius;
|
485
|
+
return {
|
486
|
+
args: [radius],
|
487
|
+
offset: boundingSphere.center
|
488
|
+
};
|
489
|
+
}
|
533
490
|
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
538
|
-
target[key] = source[key];
|
539
|
-
}
|
540
|
-
}
|
491
|
+
case "trimesh":
|
492
|
+
{
|
493
|
+
var _clonedGeometry$index;
|
541
494
|
|
542
|
-
|
543
|
-
|
495
|
+
const clonedGeometry = geometry.index ? geometry.clone() : mergeVertices(geometry);
|
496
|
+
return {
|
497
|
+
args: [clonedGeometry.attributes.position.array, (_clonedGeometry$index = clonedGeometry.index) === null || _clonedGeometry$index === void 0 ? void 0 : _clonedGeometry$index.array],
|
498
|
+
offset: new Vector3()
|
499
|
+
};
|
500
|
+
}
|
544
501
|
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
} else {
|
554
|
-
obj[key] = value;
|
502
|
+
case "hull":
|
503
|
+
{
|
504
|
+
const g = geometry.clone();
|
505
|
+
return {
|
506
|
+
args: [g.attributes.position.array],
|
507
|
+
offset: new Vector3()
|
508
|
+
};
|
509
|
+
}
|
555
510
|
}
|
556
511
|
|
557
|
-
return
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
512
|
+
return {
|
513
|
+
args: [],
|
514
|
+
offset: new Vector3()
|
515
|
+
};
|
516
|
+
};
|
517
|
+
const useColliderEvents = (collidersRef, props, events) => {
|
518
|
+
const {
|
519
|
+
onCollisionEnter,
|
520
|
+
onCollisionExit,
|
521
|
+
onIntersectionEnter,
|
522
|
+
onIntersectionExit,
|
523
|
+
onContactForce
|
524
|
+
} = props;
|
525
|
+
useEffect(() => {
|
526
|
+
var _collidersRef$current;
|
562
527
|
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
567
|
-
})), keys.push.apply(keys, symbols);
|
568
|
-
}
|
528
|
+
(_collidersRef$current = collidersRef.current) === null || _collidersRef$current === void 0 ? void 0 : _collidersRef$current.forEach(collider => {
|
529
|
+
const hasCollisionEvent = !!(onCollisionEnter || onCollisionExit || onIntersectionEnter || onIntersectionExit);
|
530
|
+
const hasContactForceEvent = !!onContactForce;
|
569
531
|
|
570
|
-
|
571
|
-
|
532
|
+
if (hasCollisionEvent && hasContactForceEvent) {
|
533
|
+
collider.setActiveEvents(ActiveEvents.COLLISION_EVENTS | ActiveEvents.CONTACT_FORCE_EVENTS);
|
534
|
+
} else if (hasCollisionEvent) {
|
535
|
+
collider.setActiveEvents(ActiveEvents.COLLISION_EVENTS);
|
536
|
+
} else if (hasContactForceEvent) {
|
537
|
+
collider.setActiveEvents(ActiveEvents.CONTACT_FORCE_EVENTS);
|
538
|
+
}
|
572
539
|
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
540
|
+
events.set(collider.handle, {
|
541
|
+
onCollisionEnter,
|
542
|
+
onCollisionExit,
|
543
|
+
onIntersectionEnter,
|
544
|
+
onIntersectionExit,
|
545
|
+
onContactForce
|
546
|
+
});
|
580
547
|
});
|
581
|
-
|
548
|
+
return () => {
|
549
|
+
var _collidersRef$current2;
|
582
550
|
|
583
|
-
|
584
|
-
}
|
551
|
+
(_collidersRef$current2 = collidersRef.current) === null || _collidersRef$current2 === void 0 ? void 0 : _collidersRef$current2.forEach(collider => events.delete(collider.handle));
|
552
|
+
};
|
553
|
+
}, [onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit, onContactForce]);
|
554
|
+
};
|
585
555
|
|
586
556
|
const rigidBodyDescFromOptions = options => {
|
587
557
|
const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
|
@@ -642,6 +612,9 @@ const mutableRigidBodyOptions = {
|
|
642
612
|
ccd: (rb, value) => {
|
643
613
|
rb.enableCcd(value);
|
644
614
|
},
|
615
|
+
userData: (rb, value) => {
|
616
|
+
rb.userData = value;
|
617
|
+
},
|
645
618
|
position: () => {},
|
646
619
|
rotation: () => {},
|
647
620
|
quaternion: () => {},
|
@@ -725,443 +698,626 @@ const useRigidBodyEvents = (rigidBodyRef, props, events) => {
|
|
725
698
|
}, [onWake, onSleep, onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit]);
|
726
699
|
};
|
727
700
|
|
728
|
-
const
|
729
|
-
|
701
|
+
const useRapier = () => {
|
702
|
+
return useContext(RapierContext);
|
703
|
+
};
|
704
|
+
const useChildColliderProps = (ref, options, ignoreMeshColliders = true) => {
|
705
|
+
const [colliderProps, setColliderProps] = useState([]);
|
706
|
+
useEffect(() => {
|
707
|
+
const object = ref.current;
|
730
708
|
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
709
|
+
if (object && options.colliders !== false) {
|
710
|
+
setColliderProps(createColliderPropsFromChildren({
|
711
|
+
object: ref.current,
|
712
|
+
options,
|
713
|
+
ignoreMeshColliders
|
714
|
+
}));
|
715
|
+
}
|
716
|
+
}, [options.colliders]);
|
717
|
+
return colliderProps;
|
718
|
+
};
|
719
|
+
const useRigidBody = (options = {}) => {
|
720
|
+
const {
|
721
|
+
world,
|
722
|
+
rigidBodyStates,
|
723
|
+
physicsOptions,
|
724
|
+
rigidBodyEvents
|
725
|
+
} = useRapier();
|
726
|
+
const ref = useRef();
|
727
|
+
const mergedOptions = useMemo(() => {
|
728
|
+
return _objectSpread2(_objectSpread2(_objectSpread2({}, physicsOptions), options), {}, {
|
729
|
+
children: undefined
|
730
|
+
});
|
731
|
+
}, [physicsOptions, options]);
|
732
|
+
const childColliderProps = useChildColliderProps(ref, mergedOptions); // Create rigidbody
|
738
733
|
|
734
|
+
const rigidBodyRef = useRef();
|
735
|
+
const getRigidBodyRef = useRef(() => {
|
736
|
+
if (!rigidBodyRef.current) {
|
737
|
+
const desc = rigidBodyDescFromOptions(options);
|
738
|
+
const rigidBody = world.createRigidBody(desc);
|
739
|
+
rigidBodyRef.current = world.getRigidBody(rigidBody.handle);
|
740
|
+
}
|
739
741
|
|
740
|
-
|
741
|
-
|
742
|
-
return newArgs;
|
743
|
-
} // Prepfill with some extra
|
742
|
+
return rigidBodyRef.current;
|
743
|
+
}); // Setup
|
744
744
|
|
745
|
+
useEffect(() => {
|
746
|
+
const rigidBody = getRigidBodyRef.current();
|
747
|
+
rigidBodyRef.current = rigidBody;
|
745
748
|
|
746
|
-
|
747
|
-
|
748
|
-
}
|
749
|
-
const createColliderFromOptions = (options, world, scale, rigidBody) => {
|
750
|
-
const scaledArgs = scaleColliderArgs(options.shape, options.args, scale); // @ts-ignore
|
749
|
+
if (!ref.current) {
|
750
|
+
ref.current = new Object3D();
|
751
|
+
}
|
751
752
|
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
753
|
+
rigidBodyStates.set(rigidBody.handle, createRigidBodyState({
|
754
|
+
rigidBody,
|
755
|
+
object: ref.current
|
756
|
+
}));
|
757
|
+
return () => {
|
758
|
+
world.removeRigidBody(rigidBody);
|
759
|
+
rigidBodyStates.delete(rigidBody.handle);
|
760
|
+
rigidBodyRef.current = undefined;
|
761
|
+
};
|
762
|
+
}, []);
|
763
|
+
useUpdateRigidBodyOptions(rigidBodyRef, mergedOptions, rigidBodyStates);
|
764
|
+
useRigidBodyEvents(rigidBodyRef, mergedOptions, rigidBodyEvents);
|
765
|
+
const api = useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
|
766
|
+
return [ref, api, childColliderProps];
|
767
|
+
}; // Joints
|
756
768
|
|
757
|
-
const
|
758
|
-
|
759
|
-
|
760
|
-
|
769
|
+
const useImpulseJoint = (body1, body2, params) => {
|
770
|
+
const {
|
771
|
+
world
|
772
|
+
} = useRapier();
|
773
|
+
const jointRef = useRef();
|
774
|
+
const getJointRef = useRef(() => {
|
775
|
+
if (!jointRef.current) {
|
776
|
+
let rb1;
|
777
|
+
let rb2;
|
778
|
+
|
779
|
+
if ("current" in body1 && body1.current && "current" in body2 && body2.current) {
|
780
|
+
rb1 = world.getRigidBody(body1.current.handle);
|
781
|
+
rb2 = world.getRigidBody(body2.current.handle);
|
782
|
+
const newJoint = world.createImpulseJoint(params, rb1, rb2);
|
783
|
+
jointRef.current = newJoint;
|
784
|
+
}
|
761
785
|
}
|
762
786
|
|
763
|
-
|
764
|
-
|
765
|
-
|
787
|
+
return jointRef.current;
|
788
|
+
});
|
789
|
+
useEffect(() => {
|
790
|
+
const joint = getJointRef.current();
|
791
|
+
return () => {
|
792
|
+
if (joint) {
|
793
|
+
world.removeImpulseJoint(joint);
|
794
|
+
jointRef.current = undefined;
|
795
|
+
}
|
796
|
+
};
|
797
|
+
}, []);
|
798
|
+
const api = useMemo(() => createJointApi(getJointRef), []);
|
799
|
+
return api;
|
800
|
+
};
|
801
|
+
/**
|
802
|
+
*
|
803
|
+
* A fixed joint ensures that two rigid-bodies don't move relative to each other.
|
804
|
+
* Fixed joints are characterized by one local frame (represented by an isometry) on each rigid-body.
|
805
|
+
* The fixed-joint makes these frames coincide in world-space.
|
806
|
+
*/
|
766
807
|
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
808
|
+
const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor, body2LocalFrame]) => {
|
809
|
+
const {
|
810
|
+
rapier
|
811
|
+
} = useRapier();
|
812
|
+
return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToVector3(body1Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body1LocalFrame)), {}, {
|
813
|
+
w: 1
|
814
|
+
}), vectorArrayToVector3(body2Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body2LocalFrame)), {}, {
|
815
|
+
w: 1
|
816
|
+
})));
|
817
|
+
};
|
818
|
+
/**
|
819
|
+
* The spherical joint ensures that two points on the local-spaces of two rigid-bodies always coincide (it prevents any relative
|
820
|
+
* translational motion at this points). This is typically used to simulate ragdolls arms, pendulums, etc.
|
821
|
+
* They are characterized by one local anchor on each rigid-body. Each anchor represents the location of the
|
822
|
+
* points that need to coincide on the local-space of each rigid-body.
|
823
|
+
*/
|
771
824
|
|
772
|
-
|
773
|
-
|
774
|
-
|
825
|
+
const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
826
|
+
const {
|
827
|
+
rapier
|
828
|
+
} = useRapier();
|
829
|
+
return useImpulseJoint(body1, body2, rapier.JointData.spherical(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor)));
|
830
|
+
};
|
831
|
+
/**
|
832
|
+
* The revolute joint prevents any relative movement between two rigid-bodies, except for relative
|
833
|
+
* rotations along one axis. This is typically used to simulate wheels, fans, etc.
|
834
|
+
* They are characterized by one local anchor as well as one local axis on each rigid-body.
|
835
|
+
*/
|
775
836
|
|
776
|
-
|
777
|
-
|
778
|
-
|
837
|
+
const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
838
|
+
const {
|
839
|
+
rapier
|
840
|
+
} = useRapier();
|
841
|
+
return useImpulseJoint(body1, body2, rapier.JointData.revolute(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
|
779
842
|
};
|
843
|
+
/**
|
844
|
+
* The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
|
845
|
+
* It is characterized by one local anchor as well as one local axis on each rigid-body. In 3D, an optional
|
846
|
+
* local tangent axis can be specified for each rigid-body.
|
847
|
+
*/
|
780
848
|
|
781
|
-
const
|
782
|
-
|
783
|
-
|
784
|
-
}
|
785
|
-
|
786
|
-
collider.setCollisionGroups(value);
|
787
|
-
},
|
788
|
-
solverGroups: (collider, value) => {
|
789
|
-
collider.setSolverGroups(value);
|
790
|
-
},
|
791
|
-
friction: (collider, value) => {
|
792
|
-
collider.setFriction(value);
|
793
|
-
},
|
794
|
-
frictionCombineRule: (collider, value) => {
|
795
|
-
collider.setFrictionCombineRule(value);
|
796
|
-
},
|
797
|
-
restitution: (collider, value) => {
|
798
|
-
collider.setRestitution(value);
|
799
|
-
},
|
800
|
-
restitutionCombineRule: (collider, value) => {
|
801
|
-
collider.setRestitutionCombineRule(value);
|
802
|
-
},
|
803
|
-
// To make sure the options all mutalbe options are listed
|
804
|
-
quaternion: () => {},
|
805
|
-
position: () => {},
|
806
|
-
rotation: () => {},
|
807
|
-
scale: () => {}
|
849
|
+
const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
850
|
+
const {
|
851
|
+
rapier
|
852
|
+
} = useRapier();
|
853
|
+
return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
|
808
854
|
};
|
809
|
-
const mutableColliderOptionKeys = Object.keys(mutableColliderOptions);
|
810
|
-
const setColliderOptions = (collider, options, states) => {
|
811
|
-
const state = states.get(collider.handle);
|
812
855
|
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
856
|
+
const calcForceByType = {
|
857
|
+
static: (s, m2, r, d, G) => s,
|
858
|
+
linear: (s, m2, r, d, G) => s * (d / r),
|
859
|
+
newtonian: (s, m2, r, d, G) => G * s * m2 / Math.pow(d, 2)
|
860
|
+
};
|
861
|
+
const applyAttractorForceOnRigidBody = (rigidBody, {
|
862
|
+
object,
|
863
|
+
strength,
|
864
|
+
range,
|
865
|
+
gravitationalConstant,
|
866
|
+
collisionGroups,
|
867
|
+
type
|
868
|
+
}) => {
|
869
|
+
const rbPosition = rigidBody.translation();
|
817
870
|
|
818
|
-
|
871
|
+
_position.set(rbPosition.x, rbPosition.y, rbPosition.z);
|
819
872
|
|
820
|
-
|
821
|
-
|
822
|
-
x: _position.x * parentWorldScale.x,
|
823
|
-
y: _position.y * parentWorldScale.y,
|
824
|
-
z: _position.z * parentWorldScale.z
|
825
|
-
});
|
826
|
-
collider.setRotationWrtParent(_rotation);
|
827
|
-
} else {
|
828
|
-
collider.setTranslation({
|
829
|
-
x: _position.x * parentWorldScale.x,
|
830
|
-
y: _position.y * parentWorldScale.y,
|
831
|
-
z: _position.z * parentWorldScale.z
|
832
|
-
});
|
833
|
-
collider.setRotation(_rotation);
|
834
|
-
}
|
873
|
+
const worldPosition = object.getWorldPosition(new Vector3());
|
874
|
+
const distance = worldPosition.distanceTo(_position);
|
835
875
|
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
876
|
+
if (distance < range) {
|
877
|
+
let force = calcForceByType[type](strength, rigidBody.mass(), range, distance, gravitationalConstant); // Prevent wild forces when Attractors collide
|
878
|
+
|
879
|
+
force = force === Infinity ? strength : force; // Naively test if the rigidBody contains a collider in one of the collision groups
|
880
|
+
|
881
|
+
let isRigidBodyInCollisionGroup = collisionGroups === undefined ? true : false;
|
882
|
+
|
883
|
+
if (collisionGroups !== undefined) {
|
884
|
+
for (let i = 0; i < rigidBody.numColliders(); i++) {
|
885
|
+
const collider = rigidBody.collider(i);
|
886
|
+
const colliderCollisionGroups = collider.collisionGroups();
|
887
|
+
|
888
|
+
if ((collisionGroups >> 16 & colliderCollisionGroups) != 0 && (colliderCollisionGroups >> 16 & collisionGroups) != 0) {
|
889
|
+
isRigidBodyInCollisionGroup = true;
|
890
|
+
break;
|
891
|
+
}
|
841
892
|
}
|
842
|
-
}
|
843
|
-
// are exclusive.
|
893
|
+
}
|
844
894
|
|
845
|
-
|
895
|
+
if (isRigidBodyInCollisionGroup) {
|
896
|
+
_vector3.set(0, 0, 0).subVectors(worldPosition, _position).normalize().multiplyScalar(force);
|
897
|
+
|
898
|
+
rigidBody.applyImpulse(_vector3, true);
|
899
|
+
}
|
846
900
|
}
|
847
901
|
};
|
848
|
-
const
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
902
|
+
const Attractor = /*#__PURE__*/memo(props => {
|
903
|
+
const {
|
904
|
+
position = [0, 0, 0],
|
905
|
+
strength = 1,
|
906
|
+
range = 10,
|
907
|
+
type = "static",
|
908
|
+
gravitationalConstant = 6.673e-11,
|
909
|
+
collisionGroups
|
910
|
+
} = props;
|
911
|
+
const {
|
912
|
+
attractorStates
|
913
|
+
} = useRapier();
|
914
|
+
const object = useRef(null);
|
853
915
|
useEffect(() => {
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
916
|
+
var _object$current;
|
917
|
+
|
918
|
+
let uuid = ((_object$current = object.current) === null || _object$current === void 0 ? void 0 : _object$current.uuid) || "_";
|
919
|
+
|
920
|
+
if (object.current) {
|
921
|
+
attractorStates.set(uuid, {
|
922
|
+
object: object.current,
|
923
|
+
strength,
|
924
|
+
range,
|
925
|
+
type,
|
926
|
+
gravitationalConstant,
|
927
|
+
collisionGroups
|
928
|
+
});
|
929
|
+
}
|
859
930
|
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
931
|
+
return () => {
|
932
|
+
attractorStates.delete(uuid);
|
933
|
+
};
|
934
|
+
}, [props]);
|
935
|
+
return /*#__PURE__*/React.createElement("object3D", {
|
936
|
+
ref: object,
|
937
|
+
position: position
|
864
938
|
});
|
865
|
-
|
866
|
-
|
939
|
+
});
|
940
|
+
|
941
|
+
const RapierContext = /*#__PURE__*/createContext(undefined);
|
942
|
+
|
943
|
+
const getCollisionPayloadFromSource = (target, other) => {
|
944
|
+
var _target$collider$stat, _target$rigidBody$sta, _other$collider$state, _other$rigidBody$stat, _other$collider$state2, _other$rigidBody$stat2;
|
867
945
|
|
868
|
-
const createColliderState = (collider, object, rigidBodyObject) => {
|
869
946
|
return {
|
870
|
-
|
871
|
-
|
872
|
-
|
947
|
+
target: {
|
948
|
+
rigidBody: target.rigidBody.object,
|
949
|
+
collider: target.collider.object,
|
950
|
+
colliderObject: (_target$collider$stat = target.collider.state) === null || _target$collider$stat === void 0 ? void 0 : _target$collider$stat.object,
|
951
|
+
rigidBodyObject: (_target$rigidBody$sta = target.rigidBody.state) === null || _target$rigidBody$sta === void 0 ? void 0 : _target$rigidBody$sta.object
|
952
|
+
},
|
953
|
+
other: {
|
954
|
+
rigidBody: other.rigidBody.object,
|
955
|
+
collider: other.collider.object,
|
956
|
+
colliderObject: (_other$collider$state = other.collider.state) === null || _other$collider$state === void 0 ? void 0 : _other$collider$state.object,
|
957
|
+
rigidBodyObject: (_other$rigidBody$stat = other.rigidBody.state) === null || _other$rigidBody$stat === void 0 ? void 0 : _other$rigidBody$stat.object
|
958
|
+
},
|
959
|
+
rigidBody: other.rigidBody.object,
|
960
|
+
collider: other.collider.object,
|
961
|
+
colliderObject: (_other$collider$state2 = other.collider.state) === null || _other$collider$state2 === void 0 ? void 0 : _other$collider$state2.object,
|
962
|
+
rigidBodyObject: (_other$rigidBody$stat2 = other.rigidBody.state) === null || _other$rigidBody$stat2 === void 0 ? void 0 : _other$rigidBody$stat2.object
|
873
963
|
};
|
874
964
|
};
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
965
|
+
|
966
|
+
const importRapier = async () => {
|
967
|
+
let r = await import('@dimforge/rapier3d-compat');
|
968
|
+
await r.init();
|
969
|
+
return r;
|
880
970
|
};
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
971
|
+
|
972
|
+
const Physics = ({
|
973
|
+
colliders: _colliders = "cuboid",
|
974
|
+
gravity: _gravity = [0, -9.81, 0],
|
975
|
+
children,
|
976
|
+
timeStep: _timeStep = 1 / 60,
|
977
|
+
paused: _paused = false,
|
978
|
+
updatePriority,
|
979
|
+
interpolate: _interpolate = true
|
885
980
|
}) => {
|
886
|
-
const
|
887
|
-
|
888
|
-
const
|
981
|
+
const rapier = useAsset(importRapier);
|
982
|
+
const worldRef = useRef();
|
983
|
+
const getWorldRef = useRef(() => {
|
984
|
+
if (!worldRef.current) {
|
985
|
+
const world = new rapier.World(vectorArrayToVector3(_gravity));
|
986
|
+
worldRef.current = world;
|
987
|
+
}
|
889
988
|
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
989
|
+
return worldRef.current;
|
990
|
+
});
|
991
|
+
const [rigidBodyStates] = useState(() => new Map());
|
992
|
+
const [colliderStates] = useState(() => new Map());
|
993
|
+
const [rigidBodyEvents] = useState(() => new Map());
|
994
|
+
const [colliderEvents] = useState(() => new Map());
|
995
|
+
const [eventQueue] = useState(() => new EventQueue(false));
|
996
|
+
const [attractorStates] = useState(() => new Map()); // Init world
|
896
997
|
|
897
|
-
|
998
|
+
useEffect(() => {
|
999
|
+
const world = getWorldRef.current();
|
1000
|
+
return () => {
|
1001
|
+
if (world) {
|
1002
|
+
world.free();
|
1003
|
+
worldRef.current = undefined;
|
1004
|
+
}
|
1005
|
+
};
|
1006
|
+
}, []); // Update gravity
|
898
1007
|
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
args,
|
905
|
-
offset
|
906
|
-
} = getColliderArgsFromGeometry(geometry, options.colliders || "cuboid");
|
907
|
-
colliderProps.push(_objectSpread2(_objectSpread2({}, options), {}, {
|
908
|
-
args: args,
|
909
|
-
shape: shape,
|
910
|
-
rotation: [rotationEuler.x, rotationEuler.y, rotationEuler.z],
|
911
|
-
position: [_position.x + offset.x * worldScale.x, _position.y + offset.y * worldScale.y, _position.z + offset.z * worldScale.z],
|
912
|
-
scale: [worldScale.x, worldScale.y, worldScale.z]
|
913
|
-
}));
|
1008
|
+
useEffect(() => {
|
1009
|
+
const world = worldRef.current;
|
1010
|
+
|
1011
|
+
if (world) {
|
1012
|
+
world.gravity = vectorArrayToVector3(_gravity);
|
914
1013
|
}
|
915
|
-
};
|
1014
|
+
}, [_gravity]);
|
1015
|
+
const getSourceFromColliderHandle = useCallback(handle => {
|
1016
|
+
const world = worldRef.current;
|
916
1017
|
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
1018
|
+
if (world) {
|
1019
|
+
var _collider$parent;
|
1020
|
+
|
1021
|
+
const collider = world.getCollider(handle);
|
1022
|
+
const colEvents = colliderEvents.get(handle);
|
1023
|
+
const colliderState = colliderStates.get(handle);
|
1024
|
+
const rigidBodyHandle = collider === null || collider === void 0 ? void 0 : (_collider$parent = collider.parent()) === null || _collider$parent === void 0 ? void 0 : _collider$parent.handle;
|
1025
|
+
const rigidBody = rigidBodyHandle !== undefined ? world.getRigidBody(rigidBodyHandle) : undefined;
|
1026
|
+
const rbEvents = rigidBody && rigidBodyHandle !== undefined ? rigidBodyEvents.get(rigidBodyHandle) : undefined;
|
1027
|
+
const rigidBodyState = rigidBodyHandle !== undefined ? rigidBodyStates.get(rigidBodyHandle) : undefined;
|
1028
|
+
const source = {
|
1029
|
+
collider: {
|
1030
|
+
object: collider,
|
1031
|
+
events: colEvents,
|
1032
|
+
state: colliderState
|
1033
|
+
},
|
1034
|
+
rigidBody: {
|
1035
|
+
object: rigidBody,
|
1036
|
+
events: rbEvents,
|
1037
|
+
state: rigidBodyState
|
1038
|
+
}
|
1039
|
+
};
|
1040
|
+
return source;
|
1041
|
+
}
|
1042
|
+
}, []);
|
1043
|
+
const [steppingState] = useState({
|
1044
|
+
previousState: {},
|
1045
|
+
accumulator: 0
|
1046
|
+
});
|
1047
|
+
const step = useCallback(dt => {
|
1048
|
+
const world = worldRef.current;
|
1049
|
+
if (!world) return;
|
1050
|
+
/* Check if the timestep is supposed to be variable. We'll do this here
|
1051
|
+
once so we don't have to string-check every frame. */
|
922
1052
|
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
1053
|
+
const timeStepVariable = _timeStep === "vary";
|
1054
|
+
/**
|
1055
|
+
* Fixed timeStep simulation progression
|
1056
|
+
* @see https://gafferongames.com/post/fix_your_timestep/
|
1057
|
+
*/
|
1058
|
+
|
1059
|
+
const clampedDelta = MathUtils.clamp(dt, 0, 0.2);
|
1060
|
+
|
1061
|
+
if (timeStepVariable) {
|
1062
|
+
world.timestep = clampedDelta;
|
1063
|
+
world.step(eventQueue);
|
1064
|
+
} else {
|
1065
|
+
world.timestep = _timeStep; // don't step time forwards if paused
|
1066
|
+
// Increase accumulator
|
1067
|
+
|
1068
|
+
steppingState.accumulator += clampedDelta;
|
1069
|
+
|
1070
|
+
while (steppingState.accumulator >= _timeStep) {
|
1071
|
+
world.forEachRigidBody(body => {
|
1072
|
+
// Set up previous state
|
1073
|
+
// needed for accurate interpolations if the world steps more than once
|
1074
|
+
if (_interpolate) {
|
1075
|
+
steppingState.previousState = {};
|
1076
|
+
steppingState.previousState[body.handle] = {
|
1077
|
+
position: body.translation(),
|
1078
|
+
rotation: body.rotation()
|
1079
|
+
};
|
1080
|
+
} // Apply attractors
|
1081
|
+
|
1082
|
+
|
1083
|
+
attractorStates.forEach(attractorState => {
|
1084
|
+
applyAttractorForceOnRigidBody(body, attractorState);
|
1085
|
+
});
|
1086
|
+
});
|
1087
|
+
world.step(eventQueue);
|
1088
|
+
steppingState.accumulator -= _timeStep;
|
938
1089
|
}
|
1090
|
+
}
|
939
1091
|
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
1092
|
+
const interpolationAlpha = timeStepVariable || !_interpolate || _paused ? 1 : steppingState.accumulator / _timeStep; // Update meshes
|
1093
|
+
|
1094
|
+
rigidBodyStates.forEach((state, handle) => {
|
1095
|
+
const rigidBody = world.getRigidBody(handle);
|
1096
|
+
const events = rigidBodyEvents.get(handle);
|
1097
|
+
|
1098
|
+
if (events !== null && events !== void 0 && events.onSleep || events !== null && events !== void 0 && events.onWake) {
|
1099
|
+
if (rigidBody.isSleeping() && !state.isSleeping) {
|
1100
|
+
var _events$onSleep;
|
1101
|
+
|
1102
|
+
events === null || events === void 0 ? void 0 : (_events$onSleep = events.onSleep) === null || _events$onSleep === void 0 ? void 0 : _events$onSleep.call(events);
|
1103
|
+
}
|
1104
|
+
|
1105
|
+
if (!rigidBody.isSleeping() && state.isSleeping) {
|
1106
|
+
var _events$onWake;
|
1107
|
+
|
1108
|
+
events === null || events === void 0 ? void 0 : (_events$onWake = events.onWake) === null || _events$onWake === void 0 ? void 0 : _events$onWake.call(events);
|
1109
|
+
}
|
1110
|
+
|
1111
|
+
state.isSleeping = rigidBody.isSleeping();
|
951
1112
|
}
|
952
1113
|
|
953
|
-
|
954
|
-
|
955
|
-
|
1114
|
+
if (!rigidBody || rigidBody.isSleeping() || !state.setMatrix) {
|
1115
|
+
return;
|
1116
|
+
} // New states
|
956
1117
|
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
1118
|
+
|
1119
|
+
let t = rigidBody.translation();
|
1120
|
+
let r = rigidBody.rotation();
|
1121
|
+
let previousState = steppingState.previousState[handle];
|
1122
|
+
|
1123
|
+
if (previousState) {
|
1124
|
+
// Get previous simulated world position
|
1125
|
+
_matrix4.compose(previousState.position, rapierQuaternionToQuaternion(previousState.rotation), state.scale).premultiply(state.invertedWorldMatrix).decompose(_position, _rotation, _scale); // Apply previous tick position
|
1126
|
+
|
1127
|
+
|
1128
|
+
if (!(state.object instanceof InstancedMesh)) {
|
1129
|
+
state.object.position.copy(_position);
|
1130
|
+
state.object.quaternion.copy(_rotation);
|
1131
|
+
}
|
1132
|
+
} // Get new position
|
1133
|
+
|
1134
|
+
|
1135
|
+
_matrix4.compose(t, rapierQuaternionToQuaternion(r), state.scale).premultiply(state.invertedWorldMatrix).decompose(_position, _rotation, _scale);
|
1136
|
+
|
1137
|
+
if (state.object instanceof InstancedMesh) {
|
1138
|
+
state.setMatrix(_matrix4);
|
1139
|
+
state.object.instanceMatrix.needsUpdate = true;
|
1140
|
+
} else {
|
1141
|
+
// Interpolate to new position
|
1142
|
+
state.object.position.lerp(_position, interpolationAlpha);
|
1143
|
+
state.object.quaternion.slerp(_rotation, interpolationAlpha);
|
962
1144
|
}
|
1145
|
+
});
|
1146
|
+
eventQueue.drainCollisionEvents((handle1, handle2, started) => {
|
1147
|
+
const source1 = getSourceFromColliderHandle(handle1);
|
1148
|
+
const source2 = getSourceFromColliderHandle(handle2); // Collision Events
|
963
1149
|
|
964
|
-
|
965
|
-
|
966
|
-
const g = geometry.clone();
|
967
|
-
return {
|
968
|
-
args: [g.attributes.position.array],
|
969
|
-
offset: new Vector3()
|
970
|
-
};
|
1150
|
+
if (!(source1 !== null && source1 !== void 0 && source1.collider.object) || !(source2 !== null && source2 !== void 0 && source2.collider.object)) {
|
1151
|
+
return;
|
971
1152
|
}
|
972
|
-
}
|
973
1153
|
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
1154
|
+
const collisionPayload1 = getCollisionPayloadFromSource(source1, source2);
|
1155
|
+
const collisionPayload2 = getCollisionPayloadFromSource(source2, source1);
|
1156
|
+
|
1157
|
+
if (started) {
|
1158
|
+
world.contactPair(source1.collider.object, source2.collider.object, (manifold, flipped) => {
|
1159
|
+
var _source1$rigidBody$ev, _source1$rigidBody$ev2, _source2$rigidBody$ev, _source2$rigidBody$ev2, _source1$collider$eve, _source1$collider$eve2, _source2$collider$eve, _source2$collider$eve2;
|
1160
|
+
|
1161
|
+
/* RigidBody events */
|
1162
|
+
(_source1$rigidBody$ev = source1.rigidBody.events) === null || _source1$rigidBody$ev === void 0 ? void 0 : (_source1$rigidBody$ev2 = _source1$rigidBody$ev.onCollisionEnter) === null || _source1$rigidBody$ev2 === void 0 ? void 0 : _source1$rigidBody$ev2.call(_source1$rigidBody$ev, _objectSpread2(_objectSpread2({}, collisionPayload1), {}, {
|
1163
|
+
manifold,
|
1164
|
+
flipped
|
1165
|
+
}));
|
1166
|
+
(_source2$rigidBody$ev = source2.rigidBody.events) === null || _source2$rigidBody$ev === void 0 ? void 0 : (_source2$rigidBody$ev2 = _source2$rigidBody$ev.onCollisionEnter) === null || _source2$rigidBody$ev2 === void 0 ? void 0 : _source2$rigidBody$ev2.call(_source2$rigidBody$ev, _objectSpread2(_objectSpread2({}, collisionPayload2), {}, {
|
1167
|
+
manifold,
|
1168
|
+
flipped
|
1169
|
+
}));
|
1170
|
+
/* Collider events */
|
1171
|
+
|
1172
|
+
(_source1$collider$eve = source1.collider.events) === null || _source1$collider$eve === void 0 ? void 0 : (_source1$collider$eve2 = _source1$collider$eve.onCollisionEnter) === null || _source1$collider$eve2 === void 0 ? void 0 : _source1$collider$eve2.call(_source1$collider$eve, _objectSpread2(_objectSpread2({}, collisionPayload1), {}, {
|
1173
|
+
manifold,
|
1174
|
+
flipped
|
1175
|
+
}));
|
1176
|
+
(_source2$collider$eve = source2.collider.events) === null || _source2$collider$eve === void 0 ? void 0 : (_source2$collider$eve2 = _source2$collider$eve.onCollisionEnter) === null || _source2$collider$eve2 === void 0 ? void 0 : _source2$collider$eve2.call(_source2$collider$eve, _objectSpread2(_objectSpread2({}, collisionPayload2), {}, {
|
1177
|
+
manifold,
|
1178
|
+
flipped
|
1179
|
+
}));
|
1180
|
+
});
|
1181
|
+
} else {
|
1182
|
+
var _source1$rigidBody$ev3, _source1$rigidBody$ev4, _source2$rigidBody$ev3, _source2$rigidBody$ev4, _source1$collider$eve3, _source1$collider$eve4, _source2$collider$eve3, _source2$collider$eve4;
|
1183
|
+
|
1184
|
+
(_source1$rigidBody$ev3 = source1.rigidBody.events) === null || _source1$rigidBody$ev3 === void 0 ? void 0 : (_source1$rigidBody$ev4 = _source1$rigidBody$ev3.onCollisionExit) === null || _source1$rigidBody$ev4 === void 0 ? void 0 : _source1$rigidBody$ev4.call(_source1$rigidBody$ev3, collisionPayload1);
|
1185
|
+
(_source2$rigidBody$ev3 = source2.rigidBody.events) === null || _source2$rigidBody$ev3 === void 0 ? void 0 : (_source2$rigidBody$ev4 = _source2$rigidBody$ev3.onCollisionExit) === null || _source2$rigidBody$ev4 === void 0 ? void 0 : _source2$rigidBody$ev4.call(_source2$rigidBody$ev3, collisionPayload2);
|
1186
|
+
(_source1$collider$eve3 = source1.collider.events) === null || _source1$collider$eve3 === void 0 ? void 0 : (_source1$collider$eve4 = _source1$collider$eve3.onCollisionExit) === null || _source1$collider$eve4 === void 0 ? void 0 : _source1$collider$eve4.call(_source1$collider$eve3, collisionPayload1);
|
1187
|
+
(_source2$collider$eve3 = source2.collider.events) === null || _source2$collider$eve3 === void 0 ? void 0 : (_source2$collider$eve4 = _source2$collider$eve3.onCollisionExit) === null || _source2$collider$eve4 === void 0 ? void 0 : _source2$collider$eve4.call(_source2$collider$eve3, collisionPayload2);
|
1188
|
+
} // Sensor Intersections
|
988
1189
|
|
989
|
-
(_collidersRef$current = collidersRef.current) === null || _collidersRef$current === void 0 ? void 0 : _collidersRef$current.forEach(collider => {
|
990
|
-
if (onCollisionEnter || onCollisionExit || onIntersectionEnter || onIntersectionExit) {
|
991
|
-
collider.setActiveEvents(ActiveEvents.COLLISION_EVENTS);
|
992
|
-
}
|
993
1190
|
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1191
|
+
if (started) {
|
1192
|
+
if (world.intersectionPair(source1.collider.object, source2.collider.object)) {
|
1193
|
+
var _source1$rigidBody$ev5, _source1$rigidBody$ev6, _source2$rigidBody$ev5, _source2$rigidBody$ev6, _source1$collider$eve5, _source1$collider$eve6, _source2$collider$eve5, _source2$collider$eve6;
|
1194
|
+
|
1195
|
+
(_source1$rigidBody$ev5 = source1.rigidBody.events) === null || _source1$rigidBody$ev5 === void 0 ? void 0 : (_source1$rigidBody$ev6 = _source1$rigidBody$ev5.onIntersectionEnter) === null || _source1$rigidBody$ev6 === void 0 ? void 0 : _source1$rigidBody$ev6.call(_source1$rigidBody$ev5, collisionPayload1);
|
1196
|
+
(_source2$rigidBody$ev5 = source2.rigidBody.events) === null || _source2$rigidBody$ev5 === void 0 ? void 0 : (_source2$rigidBody$ev6 = _source2$rigidBody$ev5.onIntersectionEnter) === null || _source2$rigidBody$ev6 === void 0 ? void 0 : _source2$rigidBody$ev6.call(_source2$rigidBody$ev5, collisionPayload2);
|
1197
|
+
(_source1$collider$eve5 = source1.collider.events) === null || _source1$collider$eve5 === void 0 ? void 0 : (_source1$collider$eve6 = _source1$collider$eve5.onIntersectionEnter) === null || _source1$collider$eve6 === void 0 ? void 0 : _source1$collider$eve6.call(_source1$collider$eve5, collisionPayload1);
|
1198
|
+
(_source2$collider$eve5 = source2.collider.events) === null || _source2$collider$eve5 === void 0 ? void 0 : (_source2$collider$eve6 = _source2$collider$eve5.onIntersectionEnter) === null || _source2$collider$eve6 === void 0 ? void 0 : _source2$collider$eve6.call(_source2$collider$eve5, collisionPayload2);
|
1199
|
+
}
|
1200
|
+
} else {
|
1201
|
+
var _source1$rigidBody$ev7, _source1$rigidBody$ev8, _source2$rigidBody$ev7, _source2$rigidBody$ev8, _source1$collider$eve7, _source1$collider$eve8, _source2$collider$eve7, _source2$collider$eve8;
|
1202
|
+
|
1203
|
+
(_source1$rigidBody$ev7 = source1.rigidBody.events) === null || _source1$rigidBody$ev7 === void 0 ? void 0 : (_source1$rigidBody$ev8 = _source1$rigidBody$ev7.onIntersectionExit) === null || _source1$rigidBody$ev8 === void 0 ? void 0 : _source1$rigidBody$ev8.call(_source1$rigidBody$ev7, collisionPayload1);
|
1204
|
+
(_source2$rigidBody$ev7 = source2.rigidBody.events) === null || _source2$rigidBody$ev7 === void 0 ? void 0 : (_source2$rigidBody$ev8 = _source2$rigidBody$ev7.onIntersectionExit) === null || _source2$rigidBody$ev8 === void 0 ? void 0 : _source2$rigidBody$ev8.call(_source2$rigidBody$ev7, collisionPayload2);
|
1205
|
+
(_source1$collider$eve7 = source1.collider.events) === null || _source1$collider$eve7 === void 0 ? void 0 : (_source1$collider$eve8 = _source1$collider$eve7.onIntersectionExit) === null || _source1$collider$eve8 === void 0 ? void 0 : _source1$collider$eve8.call(_source1$collider$eve7, collisionPayload1);
|
1206
|
+
(_source2$collider$eve7 = source2.collider.events) === null || _source2$collider$eve7 === void 0 ? void 0 : (_source2$collider$eve8 = _source2$collider$eve7.onIntersectionExit) === null || _source2$collider$eve8 === void 0 ? void 0 : _source2$collider$eve8.call(_source2$collider$eve7, collisionPayload2);
|
1207
|
+
}
|
1000
1208
|
});
|
1001
|
-
|
1002
|
-
var
|
1209
|
+
eventQueue.drainContactForceEvents(event => {
|
1210
|
+
var _source1$rigidBody$ev9, _source1$rigidBody$ev10, _source2$rigidBody$ev9, _source2$rigidBody$ev10, _source1$collider$eve9, _source1$collider$eve10, _source2$collider$eve9, _source2$collider$eve10;
|
1003
1211
|
|
1004
|
-
|
1005
|
-
|
1006
|
-
}, [onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit]);
|
1007
|
-
};
|
1212
|
+
const source1 = getSourceFromColliderHandle(event.collider1());
|
1213
|
+
const source2 = getSourceFromColliderHandle(event.collider2()); // Collision Events
|
1008
1214
|
|
1009
|
-
|
1010
|
-
|
1011
|
-
}
|
1012
|
-
const useChildColliderProps = (ref, options, ignoreMeshColliders = true) => {
|
1013
|
-
const [colliderProps, setColliderProps] = useState([]);
|
1014
|
-
useEffect(() => {
|
1015
|
-
const object = ref.current;
|
1215
|
+
if (!(source1 !== null && source1 !== void 0 && source1.collider.object) || !(source2 !== null && source2 !== void 0 && source2.collider.object)) {
|
1216
|
+
return;
|
1217
|
+
}
|
1016
1218
|
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1219
|
+
const collisionPayload1 = getCollisionPayloadFromSource(source1, source2);
|
1220
|
+
const collisionPayload2 = getCollisionPayloadFromSource(source2, source1);
|
1221
|
+
(_source1$rigidBody$ev9 = source1.rigidBody.events) === null || _source1$rigidBody$ev9 === void 0 ? void 0 : (_source1$rigidBody$ev10 = _source1$rigidBody$ev9.onContactForce) === null || _source1$rigidBody$ev10 === void 0 ? void 0 : _source1$rigidBody$ev10.call(_source1$rigidBody$ev9, _objectSpread2(_objectSpread2({}, collisionPayload1), {}, {
|
1222
|
+
totalForce: event.totalForce(),
|
1223
|
+
totalForceMagnitude: event.totalForceMagnitude(),
|
1224
|
+
maxForceDirection: event.maxForceDirection(),
|
1225
|
+
maxForceMagnitude: event.maxForceMagnitude()
|
1226
|
+
}));
|
1227
|
+
(_source2$rigidBody$ev9 = source2.rigidBody.events) === null || _source2$rigidBody$ev9 === void 0 ? void 0 : (_source2$rigidBody$ev10 = _source2$rigidBody$ev9.onContactForce) === null || _source2$rigidBody$ev10 === void 0 ? void 0 : _source2$rigidBody$ev10.call(_source2$rigidBody$ev9, _objectSpread2(_objectSpread2({}, collisionPayload2), {}, {
|
1228
|
+
totalForce: event.totalForce(),
|
1229
|
+
totalForceMagnitude: event.totalForceMagnitude(),
|
1230
|
+
maxForceDirection: event.maxForceDirection(),
|
1231
|
+
maxForceMagnitude: event.maxForceMagnitude()
|
1232
|
+
}));
|
1233
|
+
(_source1$collider$eve9 = source1.collider.events) === null || _source1$collider$eve9 === void 0 ? void 0 : (_source1$collider$eve10 = _source1$collider$eve9.onContactForce) === null || _source1$collider$eve10 === void 0 ? void 0 : _source1$collider$eve10.call(_source1$collider$eve9, _objectSpread2(_objectSpread2({}, collisionPayload1), {}, {
|
1234
|
+
totalForce: event.totalForce(),
|
1235
|
+
totalForceMagnitude: event.totalForceMagnitude(),
|
1236
|
+
maxForceDirection: event.maxForceDirection(),
|
1237
|
+
maxForceMagnitude: event.maxForceMagnitude()
|
1238
|
+
}));
|
1239
|
+
(_source2$collider$eve9 = source2.collider.events) === null || _source2$collider$eve9 === void 0 ? void 0 : (_source2$collider$eve10 = _source2$collider$eve9.onContactForce) === null || _source2$collider$eve10 === void 0 ? void 0 : _source2$collider$eve10.call(_source2$collider$eve9, _objectSpread2(_objectSpread2({}, collisionPayload2), {}, {
|
1240
|
+
totalForce: event.totalForce(),
|
1241
|
+
totalForceMagnitude: event.totalForceMagnitude(),
|
1242
|
+
maxForceDirection: event.maxForceDirection(),
|
1243
|
+
maxForceMagnitude: event.maxForceMagnitude()
|
1022
1244
|
}));
|
1023
|
-
}
|
1024
|
-
}, [options.colliders]);
|
1025
|
-
return colliderProps;
|
1026
|
-
};
|
1027
|
-
const useRigidBody = (options = {}) => {
|
1028
|
-
const {
|
1029
|
-
world,
|
1030
|
-
rigidBodyStates,
|
1031
|
-
physicsOptions,
|
1032
|
-
rigidBodyEvents
|
1033
|
-
} = useRapier();
|
1034
|
-
const ref = useRef();
|
1035
|
-
const mergedOptions = useMemo(() => {
|
1036
|
-
return _objectSpread2(_objectSpread2(_objectSpread2({}, physicsOptions), options), {}, {
|
1037
|
-
children: undefined
|
1038
1245
|
});
|
1039
|
-
}, [
|
1040
|
-
|
1246
|
+
}, [_paused, _timeStep, _interpolate]);
|
1247
|
+
useFrame((_, dt) => {
|
1248
|
+
if (!_paused) step(dt);
|
1249
|
+
}, updatePriority);
|
1250
|
+
const api = useMemo(() => createWorldApi(getWorldRef), []);
|
1251
|
+
const context = useMemo(() => ({
|
1252
|
+
rapier,
|
1253
|
+
world: api,
|
1254
|
+
physicsOptions: {
|
1255
|
+
colliders: _colliders,
|
1256
|
+
gravity: _gravity
|
1257
|
+
},
|
1258
|
+
rigidBodyStates,
|
1259
|
+
colliderStates,
|
1260
|
+
rigidBodyEvents,
|
1261
|
+
colliderEvents,
|
1262
|
+
attractorStates,
|
1263
|
+
isPaused: _paused,
|
1264
|
+
step
|
1265
|
+
}), [_paused, step]);
|
1266
|
+
return /*#__PURE__*/React.createElement(RapierContext.Provider, {
|
1267
|
+
value: context
|
1268
|
+
}, children);
|
1269
|
+
};
|
1041
1270
|
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1271
|
+
function _extends() {
|
1272
|
+
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
1273
|
+
for (var i = 1; i < arguments.length; i++) {
|
1274
|
+
var source = arguments[i];
|
1275
|
+
|
1276
|
+
for (var key in source) {
|
1277
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
1278
|
+
target[key] = source[key];
|
1279
|
+
}
|
1280
|
+
}
|
1048
1281
|
}
|
1049
1282
|
|
1050
|
-
return
|
1051
|
-
}
|
1283
|
+
return target;
|
1284
|
+
};
|
1285
|
+
return _extends.apply(this, arguments);
|
1286
|
+
}
|
1052
1287
|
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1288
|
+
function _objectWithoutPropertiesLoose(source, excluded) {
|
1289
|
+
if (source == null) return {};
|
1290
|
+
var target = {};
|
1291
|
+
var sourceKeys = Object.keys(source);
|
1292
|
+
var key, i;
|
1056
1293
|
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1294
|
+
for (i = 0; i < sourceKeys.length; i++) {
|
1295
|
+
key = sourceKeys[i];
|
1296
|
+
if (excluded.indexOf(key) >= 0) continue;
|
1297
|
+
target[key] = source[key];
|
1298
|
+
}
|
1060
1299
|
|
1300
|
+
return target;
|
1301
|
+
}
|
1061
1302
|
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
}));
|
1067
|
-
return () => {
|
1068
|
-
world.removeRigidBody(rigidBody);
|
1069
|
-
rigidBodyStates.delete(rigidBody.handle);
|
1070
|
-
rigidBodyRef.current = undefined;
|
1071
|
-
};
|
1072
|
-
}, []);
|
1073
|
-
useUpdateRigidBodyOptions(rigidBodyRef, mergedOptions, rigidBodyStates);
|
1074
|
-
useRigidBodyEvents(rigidBodyRef, mergedOptions, rigidBodyEvents);
|
1075
|
-
const api = useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
|
1076
|
-
return [ref, api, childColliderProps];
|
1077
|
-
}; // Joints
|
1303
|
+
function _objectWithoutProperties(source, excluded) {
|
1304
|
+
if (source == null) return {};
|
1305
|
+
var target = _objectWithoutPropertiesLoose(source, excluded);
|
1306
|
+
var key, i;
|
1078
1307
|
|
1079
|
-
|
1080
|
-
|
1081
|
-
world
|
1082
|
-
} = useRapier();
|
1083
|
-
const jointRef = useRef();
|
1084
|
-
const getJointRef = useRef(() => {
|
1085
|
-
if (!jointRef.current) {
|
1086
|
-
let rb1;
|
1087
|
-
let rb2;
|
1308
|
+
if (Object.getOwnPropertySymbols) {
|
1309
|
+
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
|
1088
1310
|
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
}
|
1311
|
+
for (i = 0; i < sourceSymbolKeys.length; i++) {
|
1312
|
+
key = sourceSymbolKeys[i];
|
1313
|
+
if (excluded.indexOf(key) >= 0) continue;
|
1314
|
+
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
1315
|
+
target[key] = source[key];
|
1095
1316
|
}
|
1317
|
+
}
|
1096
1318
|
|
1097
|
-
|
1098
|
-
|
1099
|
-
useEffect(() => {
|
1100
|
-
const joint = getJointRef.current();
|
1101
|
-
return () => {
|
1102
|
-
if (joint) {
|
1103
|
-
world.removeImpulseJoint(joint);
|
1104
|
-
jointRef.current = undefined;
|
1105
|
-
}
|
1106
|
-
};
|
1107
|
-
}, []);
|
1108
|
-
const api = useMemo(() => createJointApi(getJointRef), []);
|
1109
|
-
return api;
|
1110
|
-
};
|
1111
|
-
/**
|
1112
|
-
*
|
1113
|
-
* A fixed joint ensures that two rigid-bodies don't move relative to each other.
|
1114
|
-
* Fixed joints are characterized by one local frame (represented by an isometry) on each rigid-body.
|
1115
|
-
* The fixed-joint makes these frames coincide in world-space.
|
1116
|
-
*/
|
1117
|
-
|
1118
|
-
const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor, body2LocalFrame]) => {
|
1119
|
-
const {
|
1120
|
-
rapier
|
1121
|
-
} = useRapier();
|
1122
|
-
return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToVector3(body1Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body1LocalFrame)), {}, {
|
1123
|
-
w: 1
|
1124
|
-
}), vectorArrayToVector3(body2Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body2LocalFrame)), {}, {
|
1125
|
-
w: 1
|
1126
|
-
})));
|
1127
|
-
};
|
1128
|
-
/**
|
1129
|
-
* The spherical joint ensures that two points on the local-spaces of two rigid-bodies always coincide (it prevents any relative
|
1130
|
-
* translational motion at this points). This is typically used to simulate ragdolls arms, pendulums, etc.
|
1131
|
-
* They are characterized by one local anchor on each rigid-body. Each anchor represents the location of the
|
1132
|
-
* points that need to coincide on the local-space of each rigid-body.
|
1133
|
-
*/
|
1134
|
-
|
1135
|
-
const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
1136
|
-
const {
|
1137
|
-
rapier
|
1138
|
-
} = useRapier();
|
1139
|
-
return useImpulseJoint(body1, body2, rapier.JointData.spherical(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor)));
|
1140
|
-
};
|
1141
|
-
/**
|
1142
|
-
* The revolute joint prevents any relative movement between two rigid-bodies, except for relative
|
1143
|
-
* rotations along one axis. This is typically used to simulate wheels, fans, etc.
|
1144
|
-
* They are characterized by one local anchor as well as one local axis on each rigid-body.
|
1145
|
-
*/
|
1146
|
-
|
1147
|
-
const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
1148
|
-
const {
|
1149
|
-
rapier
|
1150
|
-
} = useRapier();
|
1151
|
-
return useImpulseJoint(body1, body2, rapier.JointData.revolute(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
|
1152
|
-
};
|
1153
|
-
/**
|
1154
|
-
* The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
|
1155
|
-
* It is characterized by one local anchor as well as one local axis on each rigid-body. In 3D, an optional
|
1156
|
-
* local tangent axis can be specified for each rigid-body.
|
1157
|
-
*/
|
1158
|
-
|
1159
|
-
const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
1160
|
-
const {
|
1161
|
-
rapier
|
1162
|
-
} = useRapier();
|
1163
|
-
return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
|
1164
|
-
};
|
1319
|
+
return target;
|
1320
|
+
}
|
1165
1321
|
|
1166
1322
|
// Colliders
|
1167
1323
|
const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/React.forwardRef((props, forwardedRef) => {
|
@@ -1170,7 +1326,8 @@ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/React.forwardRef((props, for
|
|
1170
1326
|
position,
|
1171
1327
|
rotation,
|
1172
1328
|
quaternion,
|
1173
|
-
scale
|
1329
|
+
scale,
|
1330
|
+
name
|
1174
1331
|
} = props;
|
1175
1332
|
const {
|
1176
1333
|
world,
|
@@ -1230,7 +1387,8 @@ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/React.forwardRef((props, for
|
|
1230
1387
|
rotation: rotation,
|
1231
1388
|
quaternion: quaternion,
|
1232
1389
|
scale: scale,
|
1233
|
-
ref: ref
|
1390
|
+
ref: ref,
|
1391
|
+
name: name
|
1234
1392
|
}, children);
|
1235
1393
|
}));
|
1236
1394
|
const CuboidCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
|
@@ -1287,6 +1445,15 @@ const ConvexHullCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1287
1445
|
ref: ref
|
1288
1446
|
}));
|
1289
1447
|
});
|
1448
|
+
CuboidCollider.displayName = "CuboidCollider";
|
1449
|
+
RoundCuboidCollider.displayName = "RoundCuboidCollider";
|
1450
|
+
BallCollider.displayName = "BallCollider";
|
1451
|
+
CapsuleCollider.displayName = "CapsuleCollider";
|
1452
|
+
HeightfieldCollider.displayName = "HeightfieldCollider";
|
1453
|
+
TrimeshCollider.displayName = "TrimeshCollider";
|
1454
|
+
ConeCollider.displayName = "ConeCollider";
|
1455
|
+
CylinderCollider.displayName = "CylinderCollider";
|
1456
|
+
ConvexHullCollider.displayName = "ConvexHullCollider";
|
1290
1457
|
|
1291
1458
|
const _excluded$1 = ["children", "type", "position", "rotation", "scale", "quaternion"];
|
1292
1459
|
const RigidBodyContext = /*#__PURE__*/createContext(undefined);
|
@@ -1322,6 +1489,7 @@ const RigidBody = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, ref) => {
|
|
1322
1489
|
key: index
|
1323
1490
|
}, colliderProps)))));
|
1324
1491
|
}));
|
1492
|
+
RigidBody.displayName = "RigidBody";
|
1325
1493
|
|
1326
1494
|
const MeshCollider = props => {
|
1327
1495
|
const {
|
@@ -1352,26 +1520,96 @@ const MeshCollider = props => {
|
|
1352
1520
|
key: index
|
1353
1521
|
}, colliderProps))));
|
1354
1522
|
};
|
1523
|
+
MeshCollider.displayName = "MeshCollider";
|
1524
|
+
|
1525
|
+
function mapsEqual(map1, map2) {
|
1526
|
+
var testVal;
|
1527
|
+
|
1528
|
+
if (map1.size !== map2.size) {
|
1529
|
+
return false;
|
1530
|
+
}
|
1531
|
+
|
1532
|
+
for (var [key, val] of map1) {
|
1533
|
+
testVal = map2.get(key);
|
1534
|
+
|
1535
|
+
if (testVal !== val || testVal === undefined && !map2.has(key)) {
|
1536
|
+
return false;
|
1537
|
+
}
|
1538
|
+
}
|
1539
|
+
|
1540
|
+
return true;
|
1541
|
+
}
|
1542
|
+
|
1543
|
+
const AttractorHelper = props => {
|
1544
|
+
const {
|
1545
|
+
scene
|
1546
|
+
} = useThree();
|
1547
|
+
const ref = useRef(null);
|
1548
|
+
const normalsHelper = useRef();
|
1549
|
+
const color = props.strength > 0 ? 0x0000ff : 0xff0000;
|
1550
|
+
useEffect(() => {
|
1551
|
+
if (ref.current) {
|
1552
|
+
normalsHelper.current = new VertexNormalsHelper(ref.current, props.range, color);
|
1553
|
+
normalsHelper.current.frustumCulled = false;
|
1554
|
+
scene.add(normalsHelper.current);
|
1555
|
+
}
|
1556
|
+
|
1557
|
+
return () => {
|
1558
|
+
if (normalsHelper.current) {
|
1559
|
+
scene.remove(normalsHelper.current);
|
1560
|
+
}
|
1561
|
+
};
|
1562
|
+
}, [props]);
|
1563
|
+
useFrame(() => {
|
1564
|
+
if (ref.current) {
|
1565
|
+
var _normalsHelper$curren;
|
1566
|
+
|
1567
|
+
const worldPosition = props.object.getWorldPosition(_vector3);
|
1568
|
+
ref.current.position.copy(worldPosition);
|
1569
|
+
(_normalsHelper$curren = normalsHelper.current) === null || _normalsHelper$curren === void 0 ? void 0 : _normalsHelper$curren.update();
|
1570
|
+
}
|
1571
|
+
});
|
1572
|
+
return /*#__PURE__*/React.createElement("mesh", {
|
1573
|
+
ref: ref,
|
1574
|
+
position: props.object.position,
|
1575
|
+
frustumCulled: false
|
1576
|
+
}, /*#__PURE__*/React.createElement("sphereGeometry", {
|
1577
|
+
args: [0.2, 6, 6]
|
1578
|
+
}), /*#__PURE__*/React.createElement("meshBasicMaterial", {
|
1579
|
+
color: color,
|
1580
|
+
wireframe: true
|
1581
|
+
}));
|
1582
|
+
};
|
1355
1583
|
|
1356
1584
|
const Debug = () => {
|
1357
1585
|
const {
|
1358
|
-
world
|
1586
|
+
world,
|
1587
|
+
attractorStates
|
1359
1588
|
} = useRapier();
|
1360
1589
|
const ref = useRef(null);
|
1590
|
+
const [attractors, setAttractors] = useState([]);
|
1591
|
+
const currMap = useRef(new Map());
|
1361
1592
|
useFrame(() => {
|
1362
1593
|
const mesh = ref.current;
|
1363
1594
|
if (!mesh) return;
|
1364
1595
|
const buffers = world.debugRender();
|
1365
1596
|
mesh.geometry.setAttribute("position", new BufferAttribute(buffers.vertices, 3));
|
1366
|
-
mesh.geometry.setAttribute("color", new BufferAttribute(buffers.colors, 4));
|
1597
|
+
mesh.geometry.setAttribute("color", new BufferAttribute(buffers.colors, 4)); // Update attractors
|
1598
|
+
|
1599
|
+
if (!mapsEqual(currMap.current, attractorStates)) {
|
1600
|
+
setAttractors([...attractorStates.values()]);
|
1601
|
+
currMap.current = new Map(attractorStates);
|
1602
|
+
}
|
1367
1603
|
});
|
1368
|
-
return /*#__PURE__*/React.createElement("lineSegments", {
|
1604
|
+
return /*#__PURE__*/React.createElement("group", null, /*#__PURE__*/React.createElement("lineSegments", {
|
1369
1605
|
ref: ref,
|
1370
1606
|
frustumCulled: false
|
1371
1607
|
}, /*#__PURE__*/React.createElement("lineBasicMaterial", {
|
1372
1608
|
color: 0xffffff,
|
1373
1609
|
vertexColors: true
|
1374
|
-
}), /*#__PURE__*/React.createElement("bufferGeometry", null))
|
1610
|
+
}), /*#__PURE__*/React.createElement("bufferGeometry", null)), attractors.map((attractor, i) => /*#__PURE__*/React.createElement(AttractorHelper, _extends({
|
1611
|
+
key: attractor.object.uuid
|
1612
|
+
}, attractor))));
|
1375
1613
|
};
|
1376
1614
|
|
1377
1615
|
const _excluded = ["positions", "rotations", "children"];
|
@@ -1484,6 +1722,7 @@ const InstancedRigidBodies = /*#__PURE__*/forwardRef((props, ref) => {
|
|
1484
1722
|
key: index
|
1485
1723
|
}, colliderProps)))));
|
1486
1724
|
});
|
1725
|
+
InstancedRigidBodies.displayName = "InstancedRigidBodies";
|
1487
1726
|
|
1488
1727
|
/**
|
1489
1728
|
* Calculates an InteractionGroup bitmask for use in the `collisionGroups` or `solverGroups`
|
@@ -1521,4 +1760,4 @@ const interactionGroups = (memberships, filters) => (bitmask(memberships) << 16)
|
|
1521
1760
|
|
1522
1761
|
const bitmask = groups => [groups].flat().reduce((acc, layer) => acc | 1 << layer, 0);
|
1523
1762
|
|
1524
|
-
export { AnyCollider, BallCollider, CapsuleCollider, ConeCollider, ConvexHullCollider, CuboidCollider, CylinderCollider, Debug, HeightfieldCollider, InstancedRigidBodies, MeshCollider, Physics, RigidBody, RoundCuboidCollider, TrimeshCollider, interactionGroups, useChildColliderProps, useFixedJoint, useImpulseJoint, usePrismaticJoint, useRapier, useRevoluteJoint, useRigidBody, useSphericalJoint };
|
1763
|
+
export { AnyCollider, Attractor, BallCollider, CapsuleCollider, ConeCollider, ConvexHullCollider, CuboidCollider, CylinderCollider, Debug, HeightfieldCollider, InstancedRigidBodies, MeshCollider, Physics, RigidBody, RoundCuboidCollider, TrimeshCollider, interactionGroups, useChildColliderProps, useFixedJoint, useImpulseJoint, usePrismaticJoint, useRapier, useRevoluteJoint, useRigidBody, useSphericalJoint };
|