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