@react-three/rapier 1.4.0 → 1.5.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/components/AnyCollider.d.ts +2 -2
- package/dist/declarations/src/components/InstancedRigidBodies.d.ts +2 -2
- package/dist/declarations/src/components/MeshCollider.d.ts +2 -2
- package/dist/declarations/src/components/Physics.d.ts +8 -4
- package/dist/declarations/src/components/RigidBody.d.ts +1 -1
- package/dist/declarations/src/hooks/hooks.d.ts +3 -3
- package/dist/declarations/src/hooks/joints.d.ts +1 -1
- package/dist/declarations/src/index.d.ts +15 -15
- package/dist/declarations/src/types.d.ts +2 -2
- package/dist/declarations/src/utils/interaction-groups.d.ts +1 -1
- package/dist/react-three-rapier.cjs.d.ts +1 -0
- package/dist/react-three-rapier.cjs.dev.js +148 -272
- package/dist/react-three-rapier.cjs.prod.js +148 -272
- package/dist/react-three-rapier.esm.js +148 -272
- package/package.json +8 -13
- package/readme.md +0 -2
- package/dist/declarations/src/components/Debug.d.ts +0 -2
- package/dist/declarations/src/components/FrameStepper.d.ts +0 -9
- package/dist/declarations/src/hooks/use-forwarded-ref.d.ts +0 -2
- package/dist/declarations/src/hooks/use-imperative-instance.d.ts +0 -5
- package/dist/declarations/src/utils/shared-objects.d.ts +0 -9
- package/dist/declarations/src/utils/singleton-proxy.d.ts +0 -11
- package/dist/declarations/src/utils/utils-collider.d.ts +0 -83
- package/dist/declarations/src/utils/utils-physics.d.ts +0 -1
- package/dist/declarations/src/utils/utils-rigidbody.d.ts +0 -24
- package/dist/declarations/src/utils/utils.d.ts +0 -14
@@ -31,45 +31,51 @@ function _interopNamespace(e) {
|
|
31
31
|
|
32
32
|
var React__default = /*#__PURE__*/_interopDefault(React);
|
33
33
|
|
34
|
-
function
|
35
|
-
if (
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
});
|
42
|
-
} else {
|
43
|
-
obj[key] = value;
|
34
|
+
function _toPrimitive(t, r) {
|
35
|
+
if ("object" != typeof t || !t) return t;
|
36
|
+
var e = t[Symbol.toPrimitive];
|
37
|
+
if (void 0 !== e) {
|
38
|
+
var i = e.call(t, r || "default");
|
39
|
+
if ("object" != typeof i) return i;
|
40
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
44
41
|
}
|
42
|
+
return ("string" === r ? String : Number)(t);
|
43
|
+
}
|
45
44
|
|
46
|
-
|
45
|
+
function _toPropertyKey(t) {
|
46
|
+
var i = _toPrimitive(t, "string");
|
47
|
+
return "symbol" == typeof i ? i : i + "";
|
47
48
|
}
|
48
49
|
|
49
|
-
function
|
50
|
-
|
50
|
+
function _defineProperty(e, r, t) {
|
51
|
+
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
52
|
+
value: t,
|
53
|
+
enumerable: !0,
|
54
|
+
configurable: !0,
|
55
|
+
writable: !0
|
56
|
+
}) : e[r] = t, e;
|
57
|
+
}
|
51
58
|
|
59
|
+
function ownKeys(e, r) {
|
60
|
+
var t = Object.keys(e);
|
52
61
|
if (Object.getOwnPropertySymbols) {
|
53
|
-
var
|
54
|
-
|
55
|
-
return Object.getOwnPropertyDescriptor(
|
56
|
-
})),
|
62
|
+
var o = Object.getOwnPropertySymbols(e);
|
63
|
+
r && (o = o.filter(function (r) {
|
64
|
+
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
65
|
+
})), t.push.apply(t, o);
|
57
66
|
}
|
58
|
-
|
59
|
-
return keys;
|
67
|
+
return t;
|
60
68
|
}
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
69
|
+
function _objectSpread2(e) {
|
70
|
+
for (var r = 1; r < arguments.length; r++) {
|
71
|
+
var t = null != arguments[r] ? arguments[r] : {};
|
72
|
+
r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
|
73
|
+
_defineProperty(e, r, t[r]);
|
74
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
|
75
|
+
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
69
76
|
});
|
70
77
|
}
|
71
|
-
|
72
|
-
return target;
|
78
|
+
return e;
|
73
79
|
}
|
74
80
|
|
75
81
|
const _quaternion = new three.Quaternion();
|
@@ -117,41 +123,33 @@ const rigidBodyTypeMap = {
|
|
117
123
|
const rigidBodyTypeFromString = type => rigidBodyTypeMap[type];
|
118
124
|
const scaleVertices = (vertices, scale) => {
|
119
125
|
const scaledVerts = Array.from(vertices);
|
120
|
-
|
121
126
|
for (let i = 0; i < vertices.length / 3; i++) {
|
122
127
|
scaledVerts[i * 3] *= scale.x;
|
123
128
|
scaledVerts[i * 3 + 1] *= scale.y;
|
124
129
|
scaledVerts[i * 3 + 2] *= scale.z;
|
125
130
|
}
|
126
|
-
|
127
131
|
return scaledVerts;
|
128
132
|
};
|
129
133
|
const vectorToTuple = v => {
|
130
134
|
if (!v) return [0];
|
131
|
-
|
132
135
|
if (v instanceof three.Quaternion) {
|
133
136
|
return [v.x, v.y, v.z, v.w];
|
134
137
|
}
|
135
|
-
|
136
138
|
if (v instanceof three.Vector3 || v instanceof three.Euler) {
|
137
139
|
return [v.x, v.y, v.z];
|
138
140
|
}
|
139
|
-
|
140
141
|
if (Array.isArray(v)) {
|
141
142
|
return v;
|
142
143
|
}
|
143
|
-
|
144
144
|
return [v];
|
145
145
|
};
|
146
146
|
function useConst(initialValue) {
|
147
147
|
const ref = React.useRef();
|
148
|
-
|
149
148
|
if (ref.current === undefined) {
|
150
149
|
ref.current = {
|
151
150
|
value: typeof initialValue === "function" ? initialValue() : initialValue
|
152
151
|
};
|
153
152
|
}
|
154
|
-
|
155
153
|
return ref.current.value;
|
156
154
|
}
|
157
155
|
|
@@ -170,7 +168,6 @@ const useRaf = callback => {
|
|
170
168
|
cb.current(delta / 1000);
|
171
169
|
lastFrame.current = now;
|
172
170
|
};
|
173
|
-
|
174
171
|
raf.current = requestAnimationFrame(loop);
|
175
172
|
return () => cancelAnimationFrame(raf.current);
|
176
173
|
}, []);
|
@@ -185,7 +182,6 @@ const UseFrameStepper = ({
|
|
185
182
|
}, updatePriority);
|
186
183
|
return null;
|
187
184
|
};
|
188
|
-
|
189
185
|
const RafStepper = ({
|
190
186
|
onStep
|
191
187
|
}) => {
|
@@ -194,7 +190,6 @@ const RafStepper = ({
|
|
194
190
|
});
|
195
191
|
return null;
|
196
192
|
};
|
197
|
-
|
198
193
|
const FrameStepper = ({
|
199
194
|
onStep,
|
200
195
|
type,
|
@@ -207,98 +202,80 @@ const FrameStepper = ({
|
|
207
202
|
updatePriority: updatePriority
|
208
203
|
});
|
209
204
|
};
|
210
|
-
|
211
205
|
var FrameStepper$1 = /*#__PURE__*/React.memo(FrameStepper);
|
212
206
|
|
213
|
-
function _objectWithoutPropertiesLoose(
|
214
|
-
if (
|
215
|
-
var
|
216
|
-
var
|
217
|
-
|
218
|
-
|
219
|
-
for (i = 0; i < sourceKeys.length; i++) {
|
220
|
-
key = sourceKeys[i];
|
221
|
-
if (excluded.indexOf(key) >= 0) continue;
|
222
|
-
target[key] = source[key];
|
207
|
+
function _objectWithoutPropertiesLoose(r, e) {
|
208
|
+
if (null == r) return {};
|
209
|
+
var t = {};
|
210
|
+
for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
|
211
|
+
if (e.includes(n)) continue;
|
212
|
+
t[n] = r[n];
|
223
213
|
}
|
224
|
-
|
225
|
-
return target;
|
214
|
+
return t;
|
226
215
|
}
|
227
216
|
|
228
|
-
function _objectWithoutProperties(
|
229
|
-
if (
|
230
|
-
var
|
231
|
-
|
232
|
-
|
217
|
+
function _objectWithoutProperties(e, t) {
|
218
|
+
if (null == e) return {};
|
219
|
+
var o,
|
220
|
+
r,
|
221
|
+
i = _objectWithoutPropertiesLoose(e, t);
|
233
222
|
if (Object.getOwnPropertySymbols) {
|
234
|
-
var
|
235
|
-
|
236
|
-
for (i = 0; i < sourceSymbolKeys.length; i++) {
|
237
|
-
key = sourceSymbolKeys[i];
|
238
|
-
if (excluded.indexOf(key) >= 0) continue;
|
239
|
-
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
240
|
-
target[key] = source[key];
|
241
|
-
}
|
223
|
+
var s = Object.getOwnPropertySymbols(e);
|
224
|
+
for (r = 0; r < s.length; r++) o = s[r], t.includes(o) || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
|
242
225
|
}
|
243
|
-
|
244
|
-
return target;
|
226
|
+
return i;
|
245
227
|
}
|
246
228
|
|
247
229
|
const _excluded$2 = ["mass", "linearDamping", "angularDamping", "type", "onCollisionEnter", "onCollisionExit", "onIntersectionEnter", "onIntersectionExit", "onContactForce", "children", "canSleep", "ccd", "gravityScale", "softCcdPrediction"];
|
248
230
|
const scaleColliderArgs = (shape, args, scale) => {
|
249
|
-
const newArgs = args.slice();
|
231
|
+
const newArgs = args.slice();
|
250
232
|
|
233
|
+
// Heightfield uses a vector
|
251
234
|
if (shape === "heightfield") {
|
252
235
|
const s = newArgs[3];
|
253
236
|
s.x *= scale.x;
|
254
237
|
s.x *= scale.y;
|
255
238
|
s.x *= scale.z;
|
256
239
|
return newArgs;
|
257
|
-
}
|
258
|
-
|
240
|
+
}
|
259
241
|
|
242
|
+
// Trimesh and convex scale the vertices
|
260
243
|
if (shape === "trimesh" || shape === "convexHull") {
|
261
244
|
newArgs[0] = scaleVertices(newArgs[0], scale);
|
262
245
|
return newArgs;
|
263
|
-
}
|
264
|
-
|
246
|
+
}
|
265
247
|
|
248
|
+
// Prepfill with some extra
|
266
249
|
const scaleArray = [scale.x, scale.y, scale.z, scale.x, scale.x];
|
267
250
|
return newArgs.map((arg, index) => scaleArray[index] * arg);
|
268
251
|
};
|
269
252
|
const createColliderFromOptions = (options, world, scale, getRigidBody) => {
|
270
|
-
const scaledArgs = scaleColliderArgs(options.shape, options.args, scale);
|
271
|
-
|
253
|
+
const scaledArgs = scaleColliderArgs(options.shape, options.args, scale);
|
254
|
+
// @ts-ignore
|
272
255
|
const desc = rapier3dCompat.ColliderDesc[options.shape](...scaledArgs);
|
273
256
|
return world.createCollider(desc, getRigidBody === null || getRigidBody === void 0 ? void 0 : getRigidBody());
|
274
257
|
};
|
275
258
|
const immutableColliderOptions = ["shape", "args"];
|
276
259
|
const massPropertiesConflictError = "Please pick ONLY ONE of the `density`, `mass` and `massProperties` options.";
|
277
|
-
|
278
260
|
const setColliderMassOptions = (collider, options) => {
|
279
261
|
if (options.density !== undefined) {
|
280
262
|
if (options.mass !== undefined || options.massProperties !== undefined) {
|
281
263
|
throw new Error(massPropertiesConflictError);
|
282
264
|
}
|
283
|
-
|
284
265
|
collider.setDensity(options.density);
|
285
266
|
return;
|
286
267
|
}
|
287
|
-
|
288
268
|
if (options.mass !== undefined) {
|
289
269
|
if (options.massProperties !== undefined) {
|
290
270
|
throw new Error(massPropertiesConflictError);
|
291
271
|
}
|
292
|
-
|
293
272
|
collider.setMass(options.mass);
|
294
273
|
return;
|
295
274
|
}
|
296
|
-
|
297
275
|
if (options.massProperties !== undefined) {
|
298
276
|
collider.setMassProperties(options.massProperties.mass, options.massProperties.centerOfMass, options.massProperties.principalAngularInertia, options.massProperties.angularInertiaLocalFrame);
|
299
277
|
}
|
300
278
|
};
|
301
|
-
|
302
279
|
const mutableColliderOptions = {
|
303
280
|
sensor: (collider, value) => {
|
304
281
|
collider.setSensor(value);
|
@@ -336,23 +313,17 @@ const mutableColliderOptions = {
|
|
336
313
|
const mutableColliderOptionKeys = Object.keys(mutableColliderOptions);
|
337
314
|
const setColliderOptions = (collider, options, states) => {
|
338
315
|
const state = states.get(collider.handle);
|
339
|
-
|
340
316
|
if (state) {
|
341
317
|
var _state$worldParent;
|
342
|
-
|
343
318
|
// Update collider position based on the object's position
|
344
319
|
const parentWorldScale = state.object.parent.getWorldScale(_vector3);
|
345
320
|
const parentInvertedWorldMatrix = (_state$worldParent = state.worldParent) === null || _state$worldParent === void 0 ? void 0 : _state$worldParent.matrixWorld.clone().invert();
|
346
321
|
state.object.updateWorldMatrix(true, false);
|
347
|
-
|
348
322
|
_matrix4.copy(state.object.matrixWorld);
|
349
|
-
|
350
323
|
if (parentInvertedWorldMatrix) {
|
351
324
|
_matrix4.premultiply(parentInvertedWorldMatrix);
|
352
325
|
}
|
353
|
-
|
354
326
|
_matrix4.decompose(_position, _rotation, _scale);
|
355
|
-
|
356
327
|
if (collider.parent()) {
|
357
328
|
collider.setTranslationWrtParent({
|
358
329
|
x: _position.x * parentWorldScale.x,
|
@@ -368,16 +339,17 @@ const setColliderOptions = (collider, options, states) => {
|
|
368
339
|
});
|
369
340
|
collider.setRotation(_rotation);
|
370
341
|
}
|
371
|
-
|
372
342
|
mutableColliderOptionKeys.forEach(key => {
|
373
343
|
if (key in options) {
|
374
344
|
const option = options[key];
|
375
|
-
mutableColliderOptions[key](collider,
|
345
|
+
mutableColliderOptions[key](collider,
|
346
|
+
// @ts-ignore Option does not want to fit into the function, but it will
|
376
347
|
option, options);
|
377
348
|
}
|
378
|
-
});
|
379
|
-
// are exclusive.
|
349
|
+
});
|
380
350
|
|
351
|
+
// handle mass separately, because the assignments
|
352
|
+
// are exclusive.
|
381
353
|
setColliderMassOptions(collider, options);
|
382
354
|
}
|
383
355
|
};
|
@@ -391,7 +363,6 @@ const useUpdateColliderOptions = (getCollider, props, states) => {
|
|
391
363
|
setColliderOptions(collider, props, states);
|
392
364
|
}, [...mutablePropsAsFlatArray, getCollider]);
|
393
365
|
};
|
394
|
-
|
395
366
|
const isChildOfMeshCollider = child => {
|
396
367
|
let flag = false;
|
397
368
|
child.traverseAncestors(a => {
|
@@ -399,7 +370,6 @@ const isChildOfMeshCollider = child => {
|
|
399
370
|
});
|
400
371
|
return flag;
|
401
372
|
};
|
402
|
-
|
403
373
|
const createColliderState = (collider, object, rigidBodyObject) => {
|
404
374
|
return {
|
405
375
|
collider,
|
@@ -421,16 +391,13 @@ const createColliderPropsFromChildren = ({
|
|
421
391
|
const childColliderProps = [];
|
422
392
|
object.updateWorldMatrix(true, false);
|
423
393
|
const invertedParentMatrixWorld = object.matrixWorld.clone().invert();
|
424
|
-
|
425
394
|
const colliderFromChild = child => {
|
426
395
|
if ("isMesh" in child) {
|
427
396
|
if (_ignoreMeshColliders && isChildOfMeshCollider(child)) return;
|
428
397
|
const worldScale = child.getWorldScale(_scale);
|
429
398
|
const shape = autoColliderMap[options.colliders || "cuboid"];
|
430
399
|
child.updateWorldMatrix(true, false);
|
431
|
-
|
432
400
|
_matrix4.copy(child.matrixWorld).premultiply(invertedParentMatrixWorld).decompose(_position, _rotation, _scale);
|
433
|
-
|
434
401
|
const rotationEuler = new three.Euler().setFromQuaternion(_rotation, "XYZ");
|
435
402
|
const {
|
436
403
|
geometry
|
@@ -439,7 +406,6 @@ const createColliderPropsFromChildren = ({
|
|
439
406
|
args,
|
440
407
|
offset
|
441
408
|
} = getColliderArgsFromGeometry(geometry, options.colliders || "cuboid");
|
442
|
-
|
443
409
|
const colliderProps = _objectSpread2(_objectSpread2({}, cleanRigidBodyPropsForCollider(options)), {}, {
|
444
410
|
args: args,
|
445
411
|
shape: shape,
|
@@ -447,17 +413,14 @@ const createColliderPropsFromChildren = ({
|
|
447
413
|
position: [_position.x + offset.x * worldScale.x, _position.y + offset.y * worldScale.y, _position.z + offset.z * worldScale.z],
|
448
414
|
scale: [worldScale.x, worldScale.y, worldScale.z]
|
449
415
|
});
|
450
|
-
|
451
416
|
childColliderProps.push(colliderProps);
|
452
417
|
}
|
453
418
|
};
|
454
|
-
|
455
419
|
if (options.includeInvisible) {
|
456
420
|
object.traverse(colliderFromChild);
|
457
421
|
} else {
|
458
422
|
object.traverseVisible(colliderFromChild);
|
459
423
|
}
|
460
|
-
|
461
424
|
return childColliderProps;
|
462
425
|
};
|
463
426
|
const getColliderArgsFromGeometry = (geometry, colliders) => {
|
@@ -474,7 +437,6 @@ const getColliderArgsFromGeometry = (geometry, colliders) => {
|
|
474
437
|
offset: boundingBox.getCenter(new three.Vector3())
|
475
438
|
};
|
476
439
|
}
|
477
|
-
|
478
440
|
case "ball":
|
479
441
|
{
|
480
442
|
geometry.computeBoundingSphere();
|
@@ -487,18 +449,15 @@ const getColliderArgsFromGeometry = (geometry, colliders) => {
|
|
487
449
|
offset: boundingSphere.center
|
488
450
|
};
|
489
451
|
}
|
490
|
-
|
491
452
|
case "trimesh":
|
492
453
|
{
|
493
454
|
var _clonedGeometry$index;
|
494
|
-
|
495
455
|
const clonedGeometry = geometry.index ? geometry.clone() : threeStdlib.mergeVertices(geometry);
|
496
456
|
return {
|
497
457
|
args: [clonedGeometry.attributes.position.array, (_clonedGeometry$index = clonedGeometry.index) === null || _clonedGeometry$index === void 0 ? void 0 : _clonedGeometry$index.array],
|
498
458
|
offset: new three.Vector3()
|
499
459
|
};
|
500
460
|
}
|
501
|
-
|
502
461
|
case "hull":
|
503
462
|
{
|
504
463
|
const g = geometry.clone();
|
@@ -508,7 +467,6 @@ const getColliderArgsFromGeometry = (geometry, colliders) => {
|
|
508
467
|
};
|
509
468
|
}
|
510
469
|
}
|
511
|
-
|
512
470
|
return {
|
513
471
|
args: [],
|
514
472
|
offset: new three.Vector3()
|
@@ -534,7 +492,6 @@ activeEvents = {}) => {
|
|
534
492
|
} = props;
|
535
493
|
React.useEffect(() => {
|
536
494
|
const collider = getCollider();
|
537
|
-
|
538
495
|
if (collider) {
|
539
496
|
const {
|
540
497
|
collision: collisionEventsActive,
|
@@ -542,7 +499,6 @@ activeEvents = {}) => {
|
|
542
499
|
} = getActiveCollisionEventsFromProps(props);
|
543
500
|
const hasCollisionEvent = collisionEventsActive || activeEvents.collision;
|
544
501
|
const hasContactForceEvent = contactForceEventsActive || activeEvents.contactForce;
|
545
|
-
|
546
502
|
if (hasCollisionEvent && hasContactForceEvent) {
|
547
503
|
collider.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS | rapier3dCompat.ActiveEvents.CONTACT_FORCE_EVENTS);
|
548
504
|
} else if (hasCollisionEvent) {
|
@@ -550,7 +506,6 @@ activeEvents = {}) => {
|
|
550
506
|
} else if (hasContactForceEvent) {
|
551
507
|
collider.setActiveEvents(rapier3dCompat.ActiveEvents.CONTACT_FORCE_EVENTS);
|
552
508
|
}
|
553
|
-
|
554
509
|
events.set(collider.handle, {
|
555
510
|
onCollisionEnter,
|
556
511
|
onCollisionExit,
|
@@ -559,7 +514,6 @@ activeEvents = {}) => {
|
|
559
514
|
onContactForce
|
560
515
|
});
|
561
516
|
}
|
562
|
-
|
563
517
|
return () => {
|
564
518
|
if (collider) {
|
565
519
|
events.delete(collider.handle);
|
@@ -569,34 +523,33 @@ activeEvents = {}) => {
|
|
569
523
|
};
|
570
524
|
const cleanRigidBodyPropsForCollider = (props = {}) => {
|
571
525
|
const rest = _objectWithoutProperties(props, _excluded$2);
|
572
|
-
|
573
526
|
return rest;
|
574
527
|
};
|
575
528
|
|
529
|
+
// Utils
|
576
530
|
const useMutableCallback = fn => {
|
577
531
|
const ref = React.useRef(fn);
|
578
532
|
React.useEffect(() => {
|
579
533
|
ref.current = fn;
|
580
534
|
}, [fn]);
|
581
535
|
return ref;
|
582
|
-
};
|
536
|
+
};
|
583
537
|
|
538
|
+
// External hooks
|
584
539
|
/**
|
585
540
|
* Exposes the Rapier context, and world
|
586
541
|
* @category Hooks
|
587
542
|
*/
|
588
|
-
|
589
|
-
|
590
543
|
const useRapier = () => {
|
591
544
|
const rapier = React.useContext(rapierContext);
|
592
545
|
if (!rapier) throw new Error("react-three-rapier: useRapier must be used within <Physics />!");
|
593
546
|
return rapier;
|
594
547
|
};
|
548
|
+
|
595
549
|
/**
|
596
550
|
* Registers a callback to be called before the physics step
|
597
551
|
* @category Hooks
|
598
552
|
*/
|
599
|
-
|
600
553
|
const useBeforePhysicsStep = callback => {
|
601
554
|
const {
|
602
555
|
beforeStepCallbacks
|
@@ -609,11 +562,11 @@ const useBeforePhysicsStep = callback => {
|
|
609
562
|
};
|
610
563
|
}, []);
|
611
564
|
};
|
565
|
+
|
612
566
|
/**
|
613
567
|
* Registers a callback to be called after the physics step
|
614
568
|
* @category Hooks
|
615
569
|
*/
|
616
|
-
|
617
570
|
const useAfterPhysicsStep = callback => {
|
618
571
|
const {
|
619
572
|
afterStepCallbacks
|
@@ -625,17 +578,16 @@ const useAfterPhysicsStep = callback => {
|
|
625
578
|
afterStepCallbacks.delete(ref);
|
626
579
|
};
|
627
580
|
}, []);
|
628
|
-
};
|
581
|
+
};
|
629
582
|
|
583
|
+
// Internal hooks
|
630
584
|
/**
|
631
585
|
* @internal
|
632
586
|
*/
|
633
|
-
|
634
587
|
const useChildColliderProps = (ref, options, ignoreMeshColliders = true) => {
|
635
588
|
const [colliderProps, setColliderProps] = React.useState([]);
|
636
589
|
React.useEffect(() => {
|
637
590
|
const object = ref.current;
|
638
|
-
|
639
591
|
if (object && options.colliders !== false) {
|
640
592
|
setColliderProps(createColliderPropsFromChildren({
|
641
593
|
object: ref.current,
|
@@ -681,33 +633,26 @@ const createSingletonProxy = createInstance => {
|
|
681
633
|
if (!instance) {
|
682
634
|
instance = createInstance();
|
683
635
|
}
|
684
|
-
|
685
636
|
return Reflect.get(instance, prop);
|
686
637
|
},
|
687
|
-
|
688
638
|
set(target, prop, value) {
|
689
639
|
if (!instance) {
|
690
640
|
instance = createInstance();
|
691
641
|
}
|
692
|
-
|
693
642
|
return Reflect.set(instance, prop, value);
|
694
643
|
}
|
695
|
-
|
696
644
|
};
|
697
645
|
const proxy = new Proxy({}, handler);
|
698
|
-
|
699
646
|
const reset = () => {
|
700
647
|
instance = undefined;
|
701
648
|
};
|
702
|
-
|
703
649
|
const set = newInstance => {
|
704
650
|
instance = newInstance;
|
705
651
|
};
|
652
|
+
|
706
653
|
/**
|
707
654
|
* Return the proxy and a reset function
|
708
655
|
*/
|
709
|
-
|
710
|
-
|
711
656
|
return {
|
712
657
|
proxy,
|
713
658
|
reset,
|
@@ -716,10 +661,8 @@ const createSingletonProxy = createInstance => {
|
|
716
661
|
};
|
717
662
|
|
718
663
|
const rapierContext = /*#__PURE__*/React.createContext(undefined);
|
719
|
-
|
720
664
|
const getCollisionPayloadFromSource = (target, other) => {
|
721
665
|
var _target$collider$stat, _target$rigidBody$sta, _other$collider$state, _other$rigidBody$stat, _other$collider$state2, _other$rigidBody$stat2;
|
722
|
-
|
723
666
|
return {
|
724
667
|
target: {
|
725
668
|
rigidBody: target.rigidBody.object,
|
@@ -739,13 +682,11 @@ const getCollisionPayloadFromSource = (target, other) => {
|
|
739
682
|
rigidBodyObject: (_other$rigidBody$stat2 = other.rigidBody.state) === null || _other$rigidBody$stat2 === void 0 ? void 0 : _other$rigidBody$stat2.object
|
740
683
|
};
|
741
684
|
};
|
742
|
-
|
743
685
|
const importRapier = async () => {
|
744
686
|
let r = await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('@dimforge/rapier3d-compat')); });
|
745
687
|
await r.init();
|
746
688
|
return r;
|
747
689
|
};
|
748
|
-
|
749
690
|
/**
|
750
691
|
* The main physics component used to create a physics world.
|
751
692
|
* @category Components
|
@@ -768,7 +709,7 @@ const Physics = props => {
|
|
768
709
|
numInternalPgsIterations = 1,
|
769
710
|
minIslandSize = 128,
|
770
711
|
maxCcdSubsteps = 1,
|
771
|
-
|
712
|
+
contactNaturalFrequency = 30,
|
772
713
|
lengthUnit = 1
|
773
714
|
} = props;
|
774
715
|
const rapier = suspendReact.suspend(importRapier, ["@react-thee/rapier", importRapier]);
|
@@ -782,12 +723,12 @@ const Physics = props => {
|
|
782
723
|
const eventQueue = useConst(() => new rapier3dCompat.EventQueue(false));
|
783
724
|
const beforeStepCallbacks = useConst(() => new Set());
|
784
725
|
const afterStepCallbacks = useConst(() => new Set());
|
726
|
+
|
785
727
|
/**
|
786
728
|
* Initiate the world
|
787
729
|
* This creates a singleton proxy, so that the world is only created when
|
788
730
|
* something within it is accessed.
|
789
731
|
*/
|
790
|
-
|
791
732
|
const {
|
792
733
|
proxy: worldProxy,
|
793
734
|
reset: resetWorldProxy,
|
@@ -798,8 +739,9 @@ const Physics = props => {
|
|
798
739
|
worldProxy.free();
|
799
740
|
resetWorldProxy();
|
800
741
|
};
|
801
|
-
}, []);
|
742
|
+
}, []);
|
802
743
|
|
744
|
+
// Update mutable props
|
803
745
|
React.useEffect(() => {
|
804
746
|
worldProxy.gravity = vector3ToRapierVector(gravity);
|
805
747
|
worldProxy.integrationParameters.numSolverIterations = numSolverIterations;
|
@@ -809,12 +751,11 @@ const Physics = props => {
|
|
809
751
|
worldProxy.integrationParameters.minIslandSize = minIslandSize;
|
810
752
|
worldProxy.integrationParameters.maxCcdSubsteps = maxCcdSubsteps;
|
811
753
|
worldProxy.integrationParameters.normalizedPredictionDistance = predictionDistance;
|
812
|
-
worldProxy.integrationParameters.erp = erp;
|
813
754
|
worldProxy.lengthUnit = lengthUnit;
|
814
|
-
|
755
|
+
worldProxy.integrationParameters.contact_natural_frequency = contactNaturalFrequency;
|
756
|
+
}, [worldProxy, ...gravity, numSolverIterations, numAdditionalFrictionIterations, numInternalPgsIterations, allowedLinearError, minIslandSize, maxCcdSubsteps, predictionDistance, lengthUnit, contactNaturalFrequency]);
|
815
757
|
const getSourceFromColliderHandle = React.useCallback(handle => {
|
816
758
|
var _collider$parent;
|
817
|
-
|
818
759
|
const collider = worldProxy.getCollider(handle);
|
819
760
|
const colEvents = colliderEvents.get(handle);
|
820
761
|
const colliderState = colliderStates.get(handle);
|
@@ -842,37 +783,36 @@ const Physics = props => {
|
|
842
783
|
});
|
843
784
|
const step = React.useCallback(dt => {
|
844
785
|
const world = worldProxy;
|
786
|
+
|
845
787
|
/* Check if the timestep is supposed to be variable. We'll do this here
|
846
788
|
once so we don't have to string-check every frame. */
|
847
|
-
|
848
789
|
const timeStepVariable = timeStep === "vary";
|
790
|
+
|
849
791
|
/**
|
850
792
|
* Fixed timeStep simulation progression
|
851
793
|
* @see https://gafferongames.com/post/fix_your_timestep/
|
852
794
|
*/
|
853
795
|
|
854
796
|
const clampedDelta = three.MathUtils.clamp(dt, 0, 0.5);
|
855
|
-
|
856
797
|
const stepWorld = delta => {
|
857
798
|
// Trigger beforeStep callbacks
|
858
799
|
beforeStepCallbacks.forEach(callback => {
|
859
800
|
callback.current(world);
|
860
801
|
});
|
861
802
|
world.timestep = delta;
|
862
|
-
world.step(eventQueue);
|
803
|
+
world.step(eventQueue);
|
863
804
|
|
805
|
+
// Trigger afterStep callbacks
|
864
806
|
afterStepCallbacks.forEach(callback => {
|
865
807
|
callback.current(world);
|
866
808
|
});
|
867
809
|
};
|
868
|
-
|
869
810
|
if (timeStepVariable) {
|
870
811
|
stepWorld(clampedDelta);
|
871
812
|
} else {
|
872
813
|
// don't step time forwards if paused
|
873
814
|
// Increase accumulator
|
874
815
|
steppingState.accumulator += clampedDelta;
|
875
|
-
|
876
816
|
while (steppingState.accumulator >= timeStep) {
|
877
817
|
// Set up previous state
|
878
818
|
// needed for accurate interpolations if the world steps more than once
|
@@ -885,57 +825,48 @@ const Physics = props => {
|
|
885
825
|
};
|
886
826
|
});
|
887
827
|
}
|
888
|
-
|
889
828
|
stepWorld(timeStep);
|
890
829
|
steppingState.accumulator -= timeStep;
|
891
830
|
}
|
892
831
|
}
|
832
|
+
const interpolationAlpha = timeStepVariable || !interpolate || paused ? 1 : steppingState.accumulator / timeStep;
|
893
833
|
|
894
|
-
|
895
|
-
|
834
|
+
// Update meshes
|
896
835
|
rigidBodyStates.forEach((state, handle) => {
|
897
836
|
const rigidBody = world.getRigidBody(handle);
|
898
837
|
const events = rigidBodyEvents.get(handle);
|
899
|
-
|
900
838
|
if (events !== null && events !== void 0 && events.onSleep || events !== null && events !== void 0 && events.onWake) {
|
901
839
|
if (rigidBody.isSleeping() && !state.isSleeping) {
|
902
840
|
var _events$onSleep;
|
903
|
-
|
904
841
|
events === null || events === void 0 ? void 0 : (_events$onSleep = events.onSleep) === null || _events$onSleep === void 0 ? void 0 : _events$onSleep.call(events);
|
905
842
|
}
|
906
|
-
|
907
843
|
if (!rigidBody.isSleeping() && state.isSleeping) {
|
908
844
|
var _events$onWake;
|
909
|
-
|
910
845
|
events === null || events === void 0 ? void 0 : (_events$onWake = events.onWake) === null || _events$onWake === void 0 ? void 0 : _events$onWake.call(events);
|
911
846
|
}
|
912
|
-
|
913
847
|
state.isSleeping = rigidBody.isSleeping();
|
914
848
|
}
|
915
|
-
|
916
849
|
if (!rigidBody || rigidBody.isSleeping() && !("isInstancedMesh" in state.object) || !state.setMatrix) {
|
917
850
|
return;
|
918
|
-
}
|
919
|
-
|
851
|
+
}
|
920
852
|
|
853
|
+
// New states
|
921
854
|
let t = rigidBody.translation();
|
922
855
|
let r = rigidBody.rotation();
|
923
856
|
let previousState = steppingState.previousState[handle];
|
924
|
-
|
925
857
|
if (previousState) {
|
926
858
|
// Get previous simulated world position
|
927
|
-
_matrix4.compose(previousState.position, rapierQuaternionToQuaternion(previousState.rotation), state.scale).premultiply(state.invertedWorldMatrix).decompose(_position, _rotation, _scale);
|
928
|
-
|
859
|
+
_matrix4.compose(previousState.position, rapierQuaternionToQuaternion(previousState.rotation), state.scale).premultiply(state.invertedWorldMatrix).decompose(_position, _rotation, _scale);
|
929
860
|
|
861
|
+
// Apply previous tick position
|
930
862
|
if (state.meshType == "mesh") {
|
931
863
|
state.object.position.copy(_position);
|
932
864
|
state.object.quaternion.copy(_rotation);
|
933
865
|
}
|
934
|
-
}
|
935
|
-
|
866
|
+
}
|
936
867
|
|
868
|
+
// Get new position
|
937
869
|
_matrix4.compose(t, rapierQuaternionToQuaternion(r), state.scale).premultiply(state.invertedWorldMatrix).decompose(_position, _rotation, _scale);
|
938
|
-
|
939
870
|
if (state.meshType == "instancedMesh") {
|
940
871
|
state.setMatrix(_matrix4);
|
941
872
|
} else {
|
@@ -946,19 +877,17 @@ const Physics = props => {
|
|
946
877
|
});
|
947
878
|
eventQueue.drainCollisionEvents((handle1, handle2, started) => {
|
948
879
|
const source1 = getSourceFromColliderHandle(handle1);
|
949
|
-
const source2 = getSourceFromColliderHandle(handle2);
|
880
|
+
const source2 = getSourceFromColliderHandle(handle2);
|
950
881
|
|
882
|
+
// Collision Events
|
951
883
|
if (!(source1 !== null && source1 !== void 0 && source1.collider.object) || !(source2 !== null && source2 !== void 0 && source2.collider.object)) {
|
952
884
|
return;
|
953
885
|
}
|
954
|
-
|
955
886
|
const collisionPayload1 = getCollisionPayloadFromSource(source1, source2);
|
956
887
|
const collisionPayload2 = getCollisionPayloadFromSource(source2, source1);
|
957
|
-
|
958
888
|
if (started) {
|
959
889
|
world.contactPair(source1.collider.object, source2.collider.object, (manifold, flipped) => {
|
960
890
|
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;
|
961
|
-
|
962
891
|
/* RigidBody events */
|
963
892
|
(_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), {}, {
|
964
893
|
manifold,
|
@@ -968,8 +897,8 @@ const Physics = props => {
|
|
968
897
|
manifold,
|
969
898
|
flipped
|
970
899
|
}));
|
971
|
-
/* Collider events */
|
972
900
|
|
901
|
+
/* Collider events */
|
973
902
|
(_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), {}, {
|
974
903
|
manifold,
|
975
904
|
flipped
|
@@ -981,18 +910,16 @@ const Physics = props => {
|
|
981
910
|
});
|
982
911
|
} else {
|
983
912
|
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;
|
984
|
-
|
985
913
|
(_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);
|
986
914
|
(_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);
|
987
915
|
(_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);
|
988
916
|
(_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);
|
989
|
-
}
|
990
|
-
|
917
|
+
}
|
991
918
|
|
919
|
+
// Sensor Intersections
|
992
920
|
if (started) {
|
993
921
|
if (world.intersectionPair(source1.collider.object, source2.collider.object)) {
|
994
922
|
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;
|
995
|
-
|
996
923
|
(_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);
|
997
924
|
(_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);
|
998
925
|
(_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);
|
@@ -1000,7 +927,6 @@ const Physics = props => {
|
|
1000
927
|
}
|
1001
928
|
} else {
|
1002
929
|
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;
|
1003
|
-
|
1004
930
|
(_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);
|
1005
931
|
(_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);
|
1006
932
|
(_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);
|
@@ -1009,14 +935,13 @@ const Physics = props => {
|
|
1009
935
|
});
|
1010
936
|
eventQueue.drainContactForceEvents(event => {
|
1011
937
|
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;
|
1012
|
-
|
1013
938
|
const source1 = getSourceFromColliderHandle(event.collider1());
|
1014
|
-
const source2 = getSourceFromColliderHandle(event.collider2());
|
939
|
+
const source2 = getSourceFromColliderHandle(event.collider2());
|
1015
940
|
|
941
|
+
// Collision Events
|
1016
942
|
if (!(source1 !== null && source1 !== void 0 && source1.collider.object) || !(source2 !== null && source2 !== void 0 && source2.collider.object)) {
|
1017
943
|
return;
|
1018
944
|
}
|
1019
|
-
|
1020
945
|
const collisionPayload1 = getCollisionPayloadFromSource(source1, source2);
|
1021
946
|
const collisionPayload2 = getCollisionPayloadFromSource(source2, source1);
|
1022
947
|
(_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), {}, {
|
@@ -1083,41 +1008,30 @@ const Physics = props => {
|
|
1083
1008
|
};
|
1084
1009
|
|
1085
1010
|
function _extends() {
|
1086
|
-
_extends = Object.assign ? Object.assign.bind() : function (
|
1087
|
-
for (var
|
1088
|
-
var
|
1089
|
-
|
1090
|
-
for (var key in source) {
|
1091
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
1092
|
-
target[key] = source[key];
|
1093
|
-
}
|
1094
|
-
}
|
1011
|
+
return _extends = Object.assign ? Object.assign.bind() : function (n) {
|
1012
|
+
for (var e = 1; e < arguments.length; e++) {
|
1013
|
+
var t = arguments[e];
|
1014
|
+
for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
|
1095
1015
|
}
|
1096
|
-
|
1097
|
-
|
1098
|
-
};
|
1099
|
-
return _extends.apply(this, arguments);
|
1016
|
+
return n;
|
1017
|
+
}, _extends.apply(null, arguments);
|
1100
1018
|
}
|
1101
1019
|
|
1102
1020
|
/**
|
1103
1021
|
* Initiate an instance and return a safe getter
|
1104
1022
|
*/
|
1105
|
-
|
1106
1023
|
const useImperativeInstance = (createFn, destroyFn, dependencyList) => {
|
1107
1024
|
const ref = React.useRef();
|
1108
1025
|
const getInstance = React.useCallback(() => {
|
1109
1026
|
if (!ref.current) {
|
1110
1027
|
ref.current = createFn();
|
1111
1028
|
}
|
1112
|
-
|
1113
1029
|
return ref.current;
|
1114
1030
|
}, dependencyList);
|
1115
1031
|
React.useEffect(() => {
|
1116
1032
|
// Save the destroy function and instance
|
1117
1033
|
const instance = getInstance();
|
1118
|
-
|
1119
1034
|
const destroy = () => destroyFn(instance);
|
1120
|
-
|
1121
1035
|
return () => {
|
1122
1036
|
destroy();
|
1123
1037
|
ref.current = undefined;
|
@@ -1130,7 +1044,6 @@ const useImperativeInstance = (createFn, destroyFn, dependencyList) => {
|
|
1130
1044
|
* Takes an object resembling a Vector3 and returs a Three.Vector3
|
1131
1045
|
* @category Math helpers
|
1132
1046
|
*/
|
1133
|
-
|
1134
1047
|
const vec3 = ({
|
1135
1048
|
x,
|
1136
1049
|
y,
|
@@ -1142,11 +1055,11 @@ const vec3 = ({
|
|
1142
1055
|
}) => {
|
1143
1056
|
return new three.Vector3(x, y, z);
|
1144
1057
|
};
|
1058
|
+
|
1145
1059
|
/**
|
1146
1060
|
* Takes an object resembling a Quaternion and returs a Three.Quaternion
|
1147
1061
|
* @category Math helpers
|
1148
1062
|
*/
|
1149
|
-
|
1150
1063
|
const quat = ({
|
1151
1064
|
x,
|
1152
1065
|
y,
|
@@ -1160,11 +1073,11 @@ const quat = ({
|
|
1160
1073
|
}) => {
|
1161
1074
|
return new three.Quaternion(x, y, z, w);
|
1162
1075
|
};
|
1076
|
+
|
1163
1077
|
/**
|
1164
1078
|
* Takes an object resembling an Euler and returs a Three.Euler
|
1165
1079
|
* @category Math helpers
|
1166
1080
|
*/
|
1167
|
-
|
1168
1081
|
const euler = ({
|
1169
1082
|
x,
|
1170
1083
|
y,
|
@@ -1177,17 +1090,17 @@ const euler = ({
|
|
1177
1090
|
return new three.Euler(x, y, z);
|
1178
1091
|
};
|
1179
1092
|
|
1093
|
+
// Need to catch the case where forwardedRef is a function... how to do that?
|
1180
1094
|
const useForwardedRef = (forwardedRef, defaultValue = null) => {
|
1181
|
-
const innerRef = React.useRef(defaultValue);
|
1095
|
+
const innerRef = React.useRef(defaultValue);
|
1182
1096
|
|
1097
|
+
// Update the forwarded ref when the inner ref changes
|
1183
1098
|
if (forwardedRef && typeof forwardedRef !== "function") {
|
1184
1099
|
if (!forwardedRef.current) {
|
1185
1100
|
forwardedRef.current = innerRef.current;
|
1186
1101
|
}
|
1187
|
-
|
1188
1102
|
return forwardedRef;
|
1189
1103
|
}
|
1190
|
-
|
1191
1104
|
return innerRef;
|
1192
1105
|
};
|
1193
1106
|
|
@@ -1195,7 +1108,7 @@ const useForwardedRef = (forwardedRef, defaultValue = null) => {
|
|
1195
1108
|
* A collider is a shape that can be attached to a rigid body to define its physical properties.
|
1196
1109
|
* @internal
|
1197
1110
|
*/
|
1198
|
-
const AnyCollider = /*#__PURE__*/React.memo(
|
1111
|
+
const AnyCollider = /*#__PURE__*/React.memo(/*#__PURE__*/React.forwardRef((props, forwardedRef) => {
|
1199
1112
|
const {
|
1200
1113
|
children,
|
1201
1114
|
position,
|
@@ -1211,17 +1124,16 @@ const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((prop
|
|
1211
1124
|
} = useRapier();
|
1212
1125
|
const rigidBodyContext = useRigidBodyContext();
|
1213
1126
|
const colliderRef = useForwardedRef(forwardedRef);
|
1214
|
-
const objectRef = React.useRef(null);
|
1127
|
+
const objectRef = React.useRef(null);
|
1215
1128
|
|
1129
|
+
// We spread the props out here to make sure that the ref is updated when the props change.
|
1216
1130
|
const immutablePropArray = immutableColliderOptions.flatMap(key => Array.isArray(props[key]) ? [...props[key]] : props[key]);
|
1217
1131
|
const getInstance = useImperativeInstance(() => {
|
1218
1132
|
const worldScale = objectRef.current.getWorldScale(vec3());
|
1219
1133
|
const collider = createColliderFromOptions(props, world, worldScale, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.getRigidBody);
|
1220
|
-
|
1221
1134
|
if (typeof forwardedRef == "function") {
|
1222
1135
|
forwardedRef(collider);
|
1223
1136
|
}
|
1224
|
-
|
1225
1137
|
colliderRef.current = collider;
|
1226
1138
|
return collider;
|
1227
1139
|
}, collider => {
|
@@ -1250,7 +1162,6 @@ const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((prop
|
|
1250
1162
|
name: name
|
1251
1163
|
}, children);
|
1252
1164
|
}));
|
1253
|
-
|
1254
1165
|
/**
|
1255
1166
|
* A cuboid collider shape
|
1256
1167
|
* @category Colliders
|
@@ -1262,7 +1173,6 @@ const CuboidCollider = /*#__PURE__*/React__default["default"].forwardRef((props,
|
|
1262
1173
|
}));
|
1263
1174
|
});
|
1264
1175
|
CuboidCollider.displayName = "CuboidCollider";
|
1265
|
-
|
1266
1176
|
/**
|
1267
1177
|
* A round cuboid collider shape
|
1268
1178
|
* @category Colliders
|
@@ -1272,7 +1182,6 @@ const RoundCuboidCollider = /*#__PURE__*/React__default["default"].forwardRef((p
|
|
1272
1182
|
ref: ref
|
1273
1183
|
})));
|
1274
1184
|
RoundCuboidCollider.displayName = "RoundCuboidCollider";
|
1275
|
-
|
1276
1185
|
/**
|
1277
1186
|
* A ball collider shape
|
1278
1187
|
* @category Colliders
|
@@ -1282,7 +1191,6 @@ const BallCollider = /*#__PURE__*/React__default["default"].forwardRef((props, r
|
|
1282
1191
|
ref: ref
|
1283
1192
|
})));
|
1284
1193
|
BallCollider.displayName = "BallCollider";
|
1285
|
-
|
1286
1194
|
/**
|
1287
1195
|
* A capsule collider shape
|
1288
1196
|
* @category Colliders
|
@@ -1292,7 +1200,6 @@ const CapsuleCollider = /*#__PURE__*/React__default["default"].forwardRef((props
|
|
1292
1200
|
ref: ref
|
1293
1201
|
})));
|
1294
1202
|
CapsuleCollider.displayName = "CapsuleCollider";
|
1295
|
-
|
1296
1203
|
/**
|
1297
1204
|
* A heightfield collider shape
|
1298
1205
|
* @category Colliders
|
@@ -1302,7 +1209,6 @@ const HeightfieldCollider = /*#__PURE__*/React__default["default"].forwardRef((p
|
|
1302
1209
|
ref: ref
|
1303
1210
|
})));
|
1304
1211
|
HeightfieldCollider.displayName = "HeightfieldCollider";
|
1305
|
-
|
1306
1212
|
/**
|
1307
1213
|
* A trimesh collider shape
|
1308
1214
|
* @category Colliders
|
@@ -1312,7 +1218,6 @@ const TrimeshCollider = /*#__PURE__*/React__default["default"].forwardRef((props
|
|
1312
1218
|
ref: ref
|
1313
1219
|
})));
|
1314
1220
|
TrimeshCollider.displayName = "TrimeshCollider";
|
1315
|
-
|
1316
1221
|
/**
|
1317
1222
|
* A cone collider shape
|
1318
1223
|
* @category Colliders
|
@@ -1322,7 +1227,6 @@ const ConeCollider = /*#__PURE__*/React__default["default"].forwardRef((props, r
|
|
1322
1227
|
ref: ref
|
1323
1228
|
})));
|
1324
1229
|
ConeCollider.displayName = "ConeCollider";
|
1325
|
-
|
1326
1230
|
/**
|
1327
1231
|
* A round cylinder collider shape
|
1328
1232
|
* @category Colliders
|
@@ -1332,7 +1236,6 @@ const RoundConeCollider = /*#__PURE__*/React__default["default"].forwardRef((pro
|
|
1332
1236
|
ref: ref
|
1333
1237
|
})));
|
1334
1238
|
RoundConeCollider.displayName = "RoundConeCollider";
|
1335
|
-
|
1336
1239
|
/**
|
1337
1240
|
* A cylinder collider shape
|
1338
1241
|
* @category Colliders
|
@@ -1342,7 +1245,6 @@ const CylinderCollider = /*#__PURE__*/React__default["default"].forwardRef((prop
|
|
1342
1245
|
ref: ref
|
1343
1246
|
})));
|
1344
1247
|
CylinderCollider.displayName = "CylinderCollider";
|
1345
|
-
|
1346
1248
|
/**
|
1347
1249
|
* A round cylinder collider shape
|
1348
1250
|
* @category Colliders
|
@@ -1352,7 +1254,6 @@ const RoundCylinderCollider = /*#__PURE__*/React__default["default"].forwardRef(
|
|
1352
1254
|
ref: ref
|
1353
1255
|
})));
|
1354
1256
|
CylinderCollider.displayName = "RoundCylinderCollider";
|
1355
|
-
|
1356
1257
|
/**
|
1357
1258
|
* A convex hull collider shape
|
1358
1259
|
* @category Colliders
|
@@ -1365,10 +1266,10 @@ ConvexHullCollider.displayName = "ConvexHullCollider";
|
|
1365
1266
|
|
1366
1267
|
const rigidBodyDescFromOptions = options => {
|
1367
1268
|
var _options$canSleep;
|
1368
|
-
|
1369
1269
|
const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
|
1370
|
-
const desc = new rapier3dCompat.RigidBodyDesc(type);
|
1270
|
+
const desc = new rapier3dCompat.RigidBodyDesc(type);
|
1371
1271
|
|
1272
|
+
// Apply immutable options
|
1372
1273
|
desc.canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
|
1373
1274
|
return desc;
|
1374
1275
|
};
|
@@ -1400,11 +1301,9 @@ const mutableRigidBodyOptions = {
|
|
1400
1301
|
gravityScale: (rb, value) => {
|
1401
1302
|
rb.setGravityScale(value, true);
|
1402
1303
|
},
|
1403
|
-
|
1404
1304
|
additionalSolverIterations(rb, value) {
|
1405
1305
|
rb.setAdditionalSolverIterations(value);
|
1406
1306
|
},
|
1407
|
-
|
1408
1307
|
linearDamping: (rb, value) => {
|
1409
1308
|
rb.setLinearDamping(value);
|
1410
1309
|
},
|
@@ -1449,11 +1348,9 @@ const mutableRigidBodyOptions = {
|
|
1449
1348
|
userData: (rb, value) => {
|
1450
1349
|
rb.userData = value;
|
1451
1350
|
},
|
1452
|
-
|
1453
1351
|
type(rb, value) {
|
1454
1352
|
rb.setBodyType(rigidBodyTypeFromString(value), true);
|
1455
1353
|
},
|
1456
|
-
|
1457
1354
|
position: () => {},
|
1458
1355
|
rotation: () => {},
|
1459
1356
|
quaternion: () => {},
|
@@ -1464,19 +1361,14 @@ const setRigidBodyOptions = (rigidBody, options, states, updateTranslations = tr
|
|
1464
1361
|
if (!rigidBody) {
|
1465
1362
|
return;
|
1466
1363
|
}
|
1467
|
-
|
1468
1364
|
const state = states.get(rigidBody.handle);
|
1469
|
-
|
1470
1365
|
if (state) {
|
1471
1366
|
if (updateTranslations) {
|
1472
1367
|
state.object.updateWorldMatrix(true, false);
|
1473
|
-
|
1474
1368
|
_matrix4.copy(state.object.matrixWorld).decompose(_position, _rotation, _scale);
|
1475
|
-
|
1476
1369
|
rigidBody.setTranslation(_position, false);
|
1477
1370
|
rigidBody.setRotation(_rotation, false);
|
1478
1371
|
}
|
1479
|
-
|
1480
1372
|
mutableRigidBodyOptionKeys.forEach(key => {
|
1481
1373
|
if (key in options) {
|
1482
1374
|
mutableRigidBodyOptions[key](rigidBody, options[key]);
|
@@ -1525,23 +1417,21 @@ const useRigidBodyEvents = (getRigidBody, props, events) => {
|
|
1525
1417
|
const _excluded$1 = ["children", "type", "position", "rotation", "scale", "quaternion", "transformState"];
|
1526
1418
|
const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
|
1527
1419
|
const useRigidBodyContext = () => React.useContext(RigidBodyContext);
|
1528
|
-
|
1529
1420
|
/**
|
1530
1421
|
* A rigid body is a physical object that can be simulated by the physics engine.
|
1531
1422
|
* @category Components
|
1532
1423
|
*/
|
1533
|
-
const RigidBody = /*#__PURE__*/React.memo(
|
1424
|
+
const RigidBody = /*#__PURE__*/React.memo(/*#__PURE__*/React.forwardRef((props, forwardedRef) => {
|
1534
1425
|
const {
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1426
|
+
children,
|
1427
|
+
type,
|
1428
|
+
position,
|
1429
|
+
rotation,
|
1430
|
+
scale,
|
1431
|
+
quaternion,
|
1432
|
+
transformState
|
1433
|
+
} = props,
|
1434
|
+
objectProps = _objectWithoutProperties(props, _excluded$1);
|
1545
1435
|
const objectRef = React.useRef(null);
|
1546
1436
|
const rigidBodyRef = useForwardedRef(forwardedRef);
|
1547
1437
|
const {
|
@@ -1558,24 +1448,24 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
|
|
1558
1448
|
const immutablePropArray = immutableRigidBodyOptions.flatMap(key => {
|
1559
1449
|
return Array.isArray(mergedOptions[key]) ? [...mergedOptions[key]] : mergedOptions[key];
|
1560
1450
|
});
|
1561
|
-
const childColliderProps = useChildColliderProps(objectRef, mergedOptions);
|
1451
|
+
const childColliderProps = useChildColliderProps(objectRef, mergedOptions);
|
1562
1452
|
|
1453
|
+
// Provide a way to eagerly create rigidbody
|
1563
1454
|
const getRigidBody = useImperativeInstance(() => {
|
1564
1455
|
const desc = rigidBodyDescFromOptions(mergedOptions);
|
1565
1456
|
const rigidBody = world.createRigidBody(desc);
|
1566
|
-
|
1567
1457
|
if (typeof forwardedRef === "function") {
|
1568
1458
|
forwardedRef(rigidBody);
|
1569
1459
|
}
|
1570
|
-
|
1571
1460
|
rigidBodyRef.current = rigidBody;
|
1572
1461
|
return rigidBody;
|
1573
1462
|
}, rigidBody => {
|
1574
1463
|
if (world.getRigidBody(rigidBody.handle)) {
|
1575
1464
|
world.removeRigidBody(rigidBody);
|
1576
1465
|
}
|
1577
|
-
}, immutablePropArray);
|
1466
|
+
}, immutablePropArray);
|
1578
1467
|
|
1468
|
+
// Only provide a object state after the ref has been set
|
1579
1469
|
React.useEffect(() => {
|
1580
1470
|
const rigidBody = getRigidBody();
|
1581
1471
|
const state = createRigidBodyState({
|
@@ -1646,51 +1536,46 @@ const MeshCollider = /*#__PURE__*/React.memo(props => {
|
|
1646
1536
|
MeshCollider.displayName = "MeshCollider";
|
1647
1537
|
|
1648
1538
|
const _excluded = ["children", "instances", "colliderNodes", "position", "rotation", "quaternion", "scale"];
|
1649
|
-
const InstancedRigidBodies = /*#__PURE__*/React.memo(
|
1539
|
+
const InstancedRigidBodies = /*#__PURE__*/React.memo(/*#__PURE__*/React.forwardRef((props, forwardedRef) => {
|
1650
1540
|
const rigidBodiesRef = useForwardedRef(forwardedRef, []);
|
1651
1541
|
const objectRef = React.useRef(null);
|
1652
1542
|
const instanceWrapperRef = React.useRef(null);
|
1653
|
-
|
1654
1543
|
const {
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1544
|
+
// instanced props
|
1545
|
+
children,
|
1546
|
+
instances,
|
1547
|
+
colliderNodes = [],
|
1548
|
+
// wrapper object props
|
1549
|
+
position,
|
1550
|
+
rotation,
|
1551
|
+
quaternion,
|
1552
|
+
scale
|
1553
|
+
|
1554
|
+
// rigid body specific props, and r3f-object props
|
1555
|
+
} = props,
|
1556
|
+
rigidBodyProps = _objectWithoutProperties(props, _excluded);
|
1667
1557
|
const childColliderProps = useChildColliderProps(objectRef, _objectSpread2(_objectSpread2({}, props), {}, {
|
1668
1558
|
children: undefined
|
1669
1559
|
}));
|
1670
|
-
|
1671
1560
|
const getInstancedMesh = () => {
|
1672
1561
|
const firstChild = instanceWrapperRef.current.children[0];
|
1673
|
-
|
1674
1562
|
if (firstChild && "isInstancedMesh" in firstChild) {
|
1675
1563
|
return firstChild;
|
1676
1564
|
}
|
1677
|
-
|
1678
1565
|
return undefined;
|
1679
1566
|
};
|
1680
|
-
|
1681
1567
|
React.useEffect(() => {
|
1682
1568
|
const instancedMesh = getInstancedMesh();
|
1683
|
-
|
1684
1569
|
if (instancedMesh) {
|
1685
1570
|
instancedMesh.instanceMatrix.setUsage(three.DynamicDrawUsage);
|
1686
1571
|
} else {
|
1687
1572
|
console.warn("InstancedRigidBodies expects exactly one child, which must be an InstancedMesh");
|
1688
1573
|
}
|
1689
|
-
}, []);
|
1574
|
+
}, []);
|
1690
1575
|
|
1576
|
+
// Update the RigidBodyStates whenever the instances change
|
1691
1577
|
const applyInstancedState = (state, index) => {
|
1692
1578
|
const instancedMesh = getInstancedMesh();
|
1693
|
-
|
1694
1579
|
if (instancedMesh) {
|
1695
1580
|
return _objectSpread2(_objectSpread2({}, state), {}, {
|
1696
1581
|
getMatrix: matrix => {
|
@@ -1704,10 +1589,8 @@ const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forward
|
|
1704
1589
|
meshType: "instancedMesh"
|
1705
1590
|
});
|
1706
1591
|
}
|
1707
|
-
|
1708
1592
|
return state;
|
1709
1593
|
};
|
1710
|
-
|
1711
1594
|
return /*#__PURE__*/React__default["default"].createElement("object3D", _extends({
|
1712
1595
|
ref: objectRef
|
1713
1596
|
}, rigidBodyProps, {
|
@@ -1731,7 +1614,6 @@ InstancedRigidBodies.displayName = "InstancedRigidBodies";
|
|
1731
1614
|
/**
|
1732
1615
|
* @internal
|
1733
1616
|
*/
|
1734
|
-
|
1735
1617
|
const useImpulseJoint = (body1, body2, params) => {
|
1736
1618
|
const {
|
1737
1619
|
world
|
@@ -1746,7 +1628,6 @@ const useImpulseJoint = (body1, body2, params) => {
|
|
1746
1628
|
}, joint => {
|
1747
1629
|
if (joint) {
|
1748
1630
|
jointRef.current = undefined;
|
1749
|
-
|
1750
1631
|
if (world.getImpulseJoint(joint.handle)) {
|
1751
1632
|
world.removeImpulseJoint(joint, true);
|
1752
1633
|
}
|
@@ -1754,6 +1635,7 @@ const useImpulseJoint = (body1, body2, params) => {
|
|
1754
1635
|
}, []);
|
1755
1636
|
return jointRef;
|
1756
1637
|
};
|
1638
|
+
|
1757
1639
|
/**
|
1758
1640
|
* A fixed joint ensures that two rigid-bodies don't move relative to each other.
|
1759
1641
|
* Fixed joints are characterized by one local frame (represented by an isometry) on each rigid-body.
|
@@ -1761,13 +1643,13 @@ const useImpulseJoint = (body1, body2, params) => {
|
|
1761
1643
|
*
|
1762
1644
|
* @category Hooks - Joints
|
1763
1645
|
*/
|
1764
|
-
|
1765
1646
|
const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor, body2LocalFrame]) => {
|
1766
1647
|
const {
|
1767
1648
|
rapier
|
1768
1649
|
} = useRapier();
|
1769
1650
|
return useImpulseJoint(body1, body2, rapier.JointData.fixed(vector3ToRapierVector(body1Anchor), quaternionToRapierQuaternion(body1LocalFrame), vector3ToRapierVector(body2Anchor), quaternionToRapierQuaternion(body2LocalFrame)));
|
1770
1651
|
};
|
1652
|
+
|
1771
1653
|
/**
|
1772
1654
|
* The spherical joint ensures that two points on the local-spaces of two rigid-bodies always coincide (it prevents any relative
|
1773
1655
|
* translational motion at this points). This is typically used to simulate ragdolls arms, pendulums, etc.
|
@@ -1776,13 +1658,13 @@ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor,
|
|
1776
1658
|
*
|
1777
1659
|
* @category Hooks - Joints
|
1778
1660
|
*/
|
1779
|
-
|
1780
1661
|
const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
1781
1662
|
const {
|
1782
1663
|
rapier
|
1783
1664
|
} = useRapier();
|
1784
1665
|
return useImpulseJoint(body1, body2, rapier.JointData.spherical(vector3ToRapierVector(body1Anchor), vector3ToRapierVector(body2Anchor)));
|
1785
1666
|
};
|
1667
|
+
|
1786
1668
|
/**
|
1787
1669
|
* The revolute joint prevents any relative movement between two rigid-bodies, except for relative
|
1788
1670
|
* rotations along one axis. This is typically used to simulate wheels, fans, etc.
|
@@ -1790,20 +1672,18 @@ const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
|
1790
1672
|
*
|
1791
1673
|
* @category Hooks - Joints
|
1792
1674
|
*/
|
1793
|
-
|
1794
1675
|
const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis, limits]) => {
|
1795
1676
|
const {
|
1796
1677
|
rapier
|
1797
1678
|
} = useRapier();
|
1798
1679
|
const params = rapier.JointData.revolute(vector3ToRapierVector(body1Anchor), vector3ToRapierVector(body2Anchor), vector3ToRapierVector(axis));
|
1799
|
-
|
1800
1680
|
if (limits) {
|
1801
1681
|
params.limitsEnabled = true;
|
1802
1682
|
params.limits = limits;
|
1803
1683
|
}
|
1804
|
-
|
1805
1684
|
return useImpulseJoint(body1, body2, params);
|
1806
1685
|
};
|
1686
|
+
|
1807
1687
|
/**
|
1808
1688
|
* The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
|
1809
1689
|
* It is characterized by one local anchor as well as one local axis on each rigid-body. In 3D, an optional
|
@@ -1811,25 +1691,22 @@ const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis, limits]
|
|
1811
1691
|
*
|
1812
1692
|
* @category Hooks - Joints
|
1813
1693
|
*/
|
1814
|
-
|
1815
1694
|
const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis, limits]) => {
|
1816
1695
|
const {
|
1817
1696
|
rapier
|
1818
1697
|
} = useRapier();
|
1819
1698
|
const params = rapier.JointData.prismatic(vector3ToRapierVector(body1Anchor), vector3ToRapierVector(body2Anchor), vector3ToRapierVector(axis));
|
1820
|
-
|
1821
1699
|
if (limits) {
|
1822
1700
|
params.limitsEnabled = true;
|
1823
1701
|
params.limits = limits;
|
1824
1702
|
}
|
1825
|
-
|
1826
1703
|
return useImpulseJoint(body1, body2, params);
|
1827
1704
|
};
|
1705
|
+
|
1828
1706
|
/**
|
1829
1707
|
* The rope joint limits the max distance between two bodies.
|
1830
1708
|
* @category Hooks - Joints
|
1831
1709
|
*/
|
1832
|
-
|
1833
1710
|
const useRopeJoint = (body1, body2, [body1Anchor, body2Anchor, length]) => {
|
1834
1711
|
const {
|
1835
1712
|
rapier
|
@@ -1839,11 +1716,11 @@ const useRopeJoint = (body1, body2, [body1Anchor, body2Anchor, length]) => {
|
|
1839
1716
|
const params = rapier.JointData.rope(length, vBody1Anchor, vBody2Anchor);
|
1840
1717
|
return useImpulseJoint(body1, body2, params);
|
1841
1718
|
};
|
1719
|
+
|
1842
1720
|
/**
|
1843
1721
|
* The spring joint applies a force proportional to the distance between two objects.
|
1844
1722
|
* @category Hooks - Joints
|
1845
1723
|
*/
|
1846
|
-
|
1847
1724
|
const useSpringJoint = (body1, body2, [body1Anchor, body2Anchor, restLength, stiffness, damping]) => {
|
1848
1725
|
const {
|
1849
1726
|
rapier
|
@@ -1887,7 +1764,6 @@ const useSpringJoint = (body1, body2, [body1Anchor, body2Anchor, restLength, sti
|
|
1887
1764
|
* @returns An InteractionGroup bitmask.
|
1888
1765
|
*/
|
1889
1766
|
const interactionGroups = (memberships, filters) => (bitmask(memberships) << 16) + (filters !== undefined ? bitmask(filters) : 0b1111111111111111);
|
1890
|
-
|
1891
1767
|
const bitmask = groups => [groups].flat().reduce((acc, layer) => acc | 1 << layer, 0);
|
1892
1768
|
|
1893
1769
|
Object.defineProperty(exports, 'CoefficientCombineRule', {
|