@react-three/rapier 1.4.0 → 2.0.0-canary.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 +16 -16
- package/dist/declarations/src/components/InstancedRigidBodies.d.ts +6 -5
- package/dist/declarations/src/components/MeshCollider.d.ts +2 -2
- package/dist/declarations/src/components/Physics.d.ts +14 -10
- package/dist/declarations/src/components/RigidBody.d.ts +9 -11
- package/dist/declarations/src/hooks/hooks.d.ts +4 -4
- package/dist/declarations/src/hooks/joints.d.ts +2 -2
- package/dist/declarations/src/index.d.ts +15 -15
- package/dist/declarations/src/types.d.ts +54 -66
- package/dist/react-three-rapier.cjs.d.ts +1 -0
- package/dist/react-three-rapier.cjs.dev.js +402 -516
- package/dist/react-three-rapier.cjs.prod.js +402 -516
- package/dist/react-three-rapier.esm.js +403 -517
- package/package.json +15 -19
- 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
|
-
const ref = React.useRef();
|
148
|
-
|
147
|
+
const ref = React.useRef(undefined);
|
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 (-1 !== e.indexOf(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 n = Object.getOwnPropertySymbols(e);
|
224
|
+
for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
|
242
225
|
}
|
243
|
-
|
244
|
-
return target;
|
226
|
+
return i;
|
245
227
|
}
|
246
228
|
|
247
|
-
const _excluded$2 = ["mass", "linearDamping", "angularDamping", "type", "onCollisionEnter", "onCollisionExit", "onIntersectionEnter", "onIntersectionExit", "onContactForce", "children", "canSleep", "ccd", "gravityScale", "softCcdPrediction"];
|
229
|
+
const _excluded$2 = ["mass", "linearDamping", "angularDamping", "type", "onCollisionEnter", "onCollisionExit", "onIntersectionEnter", "onIntersectionExit", "onContactForce", "children", "canSleep", "ccd", "gravityScale", "softCcdPrediction", "ref"];
|
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,44 @@ 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
|
|
1020
|
+
// Need to catch the case where forwardedRef is a function... how to do that?
|
1021
|
+
const useForwardedRef = (forwardedRef, defaultValue = null) => {
|
1022
|
+
const innerRef = React.useRef(defaultValue);
|
1023
|
+
|
1024
|
+
// Update the forwarded ref when the inner ref changes
|
1025
|
+
if (forwardedRef && typeof forwardedRef !== "function") {
|
1026
|
+
if (!forwardedRef.current) {
|
1027
|
+
forwardedRef.current = innerRef.current;
|
1028
|
+
}
|
1029
|
+
return forwardedRef;
|
1030
|
+
}
|
1031
|
+
return innerRef;
|
1032
|
+
};
|
1033
|
+
|
1102
1034
|
/**
|
1103
1035
|
* Initiate an instance and return a safe getter
|
1104
1036
|
*/
|
1105
|
-
|
1106
1037
|
const useImperativeInstance = (createFn, destroyFn, dependencyList) => {
|
1107
|
-
const ref = React.useRef();
|
1038
|
+
const ref = React.useRef(undefined);
|
1108
1039
|
const getInstance = React.useCallback(() => {
|
1109
1040
|
if (!ref.current) {
|
1110
1041
|
ref.current = createFn();
|
1111
1042
|
}
|
1112
|
-
|
1113
1043
|
return ref.current;
|
1114
1044
|
}, dependencyList);
|
1115
1045
|
React.useEffect(() => {
|
1116
1046
|
// Save the destroy function and instance
|
1117
1047
|
const instance = getInstance();
|
1118
|
-
|
1119
1048
|
const destroy = () => destroyFn(instance);
|
1120
|
-
|
1121
1049
|
return () => {
|
1122
1050
|
destroy();
|
1123
1051
|
ref.current = undefined;
|
@@ -1126,102 +1054,238 @@ const useImperativeInstance = (createFn, destroyFn, dependencyList) => {
|
|
1126
1054
|
return getInstance;
|
1127
1055
|
};
|
1128
1056
|
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
const vec3 = ({
|
1135
|
-
x,
|
1136
|
-
y,
|
1137
|
-
z
|
1138
|
-
} = {
|
1139
|
-
x: 0,
|
1140
|
-
y: 0,
|
1141
|
-
z: 0
|
1142
|
-
}) => {
|
1143
|
-
return new three.Vector3(x, y, z);
|
1144
|
-
};
|
1145
|
-
/**
|
1146
|
-
* Takes an object resembling a Quaternion and returs a Three.Quaternion
|
1147
|
-
* @category Math helpers
|
1148
|
-
*/
|
1057
|
+
const rigidBodyDescFromOptions = options => {
|
1058
|
+
var _options$canSleep;
|
1059
|
+
const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
|
1060
|
+
const desc = new rapier3dCompat.RigidBodyDesc(type);
|
1149
1061
|
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
z,
|
1154
|
-
w
|
1155
|
-
} = {
|
1156
|
-
x: 0,
|
1157
|
-
y: 0,
|
1158
|
-
z: 0,
|
1159
|
-
w: 1
|
1160
|
-
}) => {
|
1161
|
-
return new three.Quaternion(x, y, z, w);
|
1062
|
+
// Apply immutable options
|
1063
|
+
desc.canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
|
1064
|
+
return desc;
|
1162
1065
|
};
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
y,
|
1171
|
-
z
|
1172
|
-
} = {
|
1173
|
-
x: 0,
|
1174
|
-
y: 0,
|
1175
|
-
z: 0
|
1066
|
+
const createRigidBodyState = ({
|
1067
|
+
rigidBody,
|
1068
|
+
object,
|
1069
|
+
setMatrix,
|
1070
|
+
getMatrix,
|
1071
|
+
worldScale,
|
1072
|
+
meshType: _meshType = "mesh"
|
1176
1073
|
}) => {
|
1177
|
-
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
return innerRef;
|
1074
|
+
object.updateWorldMatrix(true, false);
|
1075
|
+
const invertedWorldMatrix = object.parent.matrixWorld.clone().invert();
|
1076
|
+
return {
|
1077
|
+
object,
|
1078
|
+
rigidBody,
|
1079
|
+
invertedWorldMatrix,
|
1080
|
+
setMatrix: setMatrix ? setMatrix : matrix => {
|
1081
|
+
object.matrix.copy(matrix);
|
1082
|
+
},
|
1083
|
+
getMatrix: getMatrix ? getMatrix : matrix => matrix.copy(object.matrix),
|
1084
|
+
scale: worldScale || object.getWorldScale(_scale).clone(),
|
1085
|
+
isSleeping: false,
|
1086
|
+
meshType: _meshType
|
1087
|
+
};
|
1192
1088
|
};
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
}
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1089
|
+
const immutableRigidBodyOptions = ["args", "colliders", "canSleep"];
|
1090
|
+
const mutableRigidBodyOptions = {
|
1091
|
+
gravityScale: (rb, value) => {
|
1092
|
+
rb.setGravityScale(value, true);
|
1093
|
+
},
|
1094
|
+
additionalSolverIterations(rb, value) {
|
1095
|
+
rb.setAdditionalSolverIterations(value);
|
1096
|
+
},
|
1097
|
+
linearDamping: (rb, value) => {
|
1098
|
+
rb.setLinearDamping(value);
|
1099
|
+
},
|
1100
|
+
angularDamping: (rb, value) => {
|
1101
|
+
rb.setAngularDamping(value);
|
1102
|
+
},
|
1103
|
+
dominanceGroup: (rb, value) => {
|
1104
|
+
rb.setDominanceGroup(value);
|
1105
|
+
},
|
1106
|
+
enabledRotations: (rb, [x, y, z]) => {
|
1107
|
+
rb.setEnabledRotations(x, y, z, true);
|
1108
|
+
},
|
1109
|
+
enabledTranslations: (rb, [x, y, z]) => {
|
1110
|
+
rb.setEnabledTranslations(x, y, z, true);
|
1111
|
+
},
|
1112
|
+
lockRotations: (rb, value) => {
|
1113
|
+
rb.lockRotations(value, true);
|
1114
|
+
},
|
1115
|
+
lockTranslations: (rb, value) => {
|
1116
|
+
rb.lockTranslations(value, true);
|
1117
|
+
},
|
1118
|
+
angularVelocity: (rb, [x, y, z]) => {
|
1119
|
+
rb.setAngvel({
|
1120
|
+
x,
|
1121
|
+
y,
|
1122
|
+
z
|
1123
|
+
}, true);
|
1124
|
+
},
|
1125
|
+
linearVelocity: (rb, [x, y, z]) => {
|
1126
|
+
rb.setLinvel({
|
1127
|
+
x,
|
1128
|
+
y,
|
1129
|
+
z
|
1130
|
+
}, true);
|
1131
|
+
},
|
1132
|
+
ccd: (rb, value) => {
|
1133
|
+
rb.enableCcd(value);
|
1134
|
+
},
|
1135
|
+
softCcdPrediction: (rb, value) => {
|
1136
|
+
rb.setSoftCcdPrediction(value);
|
1137
|
+
},
|
1138
|
+
userData: (rb, value) => {
|
1139
|
+
rb.userData = value;
|
1140
|
+
},
|
1141
|
+
type(rb, value) {
|
1142
|
+
rb.setBodyType(rigidBodyTypeFromString(value), true);
|
1143
|
+
},
|
1144
|
+
position: () => {},
|
1145
|
+
rotation: () => {},
|
1146
|
+
quaternion: () => {},
|
1147
|
+
scale: () => {}
|
1148
|
+
};
|
1149
|
+
const mutableRigidBodyOptionKeys = Object.keys(mutableRigidBodyOptions);
|
1150
|
+
const setRigidBodyOptions = (rigidBody, options, states, updateTranslations = true) => {
|
1151
|
+
if (!rigidBody) {
|
1152
|
+
return;
|
1153
|
+
}
|
1154
|
+
const state = states.get(rigidBody.handle);
|
1155
|
+
if (state) {
|
1156
|
+
if (updateTranslations) {
|
1157
|
+
state.object.updateWorldMatrix(true, false);
|
1158
|
+
_matrix4.copy(state.object.matrixWorld).decompose(_position, _rotation, _scale);
|
1159
|
+
rigidBody.setTranslation(_position, false);
|
1160
|
+
rigidBody.setRotation(_rotation, false);
|
1161
|
+
}
|
1162
|
+
mutableRigidBodyOptionKeys.forEach(key => {
|
1163
|
+
if (key in options) {
|
1164
|
+
mutableRigidBodyOptions[key](rigidBody, options[key]);
|
1165
|
+
}
|
1166
|
+
});
|
1167
|
+
}
|
1168
|
+
};
|
1169
|
+
const useUpdateRigidBodyOptions = (getRigidBody, props, states, updateTranslations = true) => {
|
1170
|
+
// TODO: Improve this, split each prop into its own effect
|
1171
|
+
const mutablePropsAsFlatArray = React.useMemo(() => mutableRigidBodyOptionKeys.flatMap(key => {
|
1172
|
+
return vectorToTuple(props[key]);
|
1173
|
+
}), [props]);
|
1174
|
+
React.useEffect(() => {
|
1175
|
+
const rigidBody = getRigidBody();
|
1176
|
+
setRigidBodyOptions(rigidBody, props, states, updateTranslations);
|
1177
|
+
}, mutablePropsAsFlatArray);
|
1178
|
+
};
|
1179
|
+
const useRigidBodyEvents = (getRigidBody, props, events) => {
|
1180
|
+
const {
|
1181
|
+
onWake,
|
1182
|
+
onSleep,
|
1183
|
+
onCollisionEnter,
|
1184
|
+
onCollisionExit,
|
1185
|
+
onIntersectionEnter,
|
1186
|
+
onIntersectionExit,
|
1187
|
+
onContactForce
|
1188
|
+
} = props;
|
1189
|
+
const eventHandlers = {
|
1190
|
+
onWake,
|
1191
|
+
onSleep,
|
1192
|
+
onCollisionEnter,
|
1193
|
+
onCollisionExit,
|
1194
|
+
onIntersectionEnter,
|
1195
|
+
onIntersectionExit,
|
1196
|
+
onContactForce
|
1197
|
+
};
|
1198
|
+
React.useEffect(() => {
|
1199
|
+
const rigidBody = getRigidBody();
|
1200
|
+
events.set(rigidBody.handle, eventHandlers);
|
1201
|
+
return () => {
|
1202
|
+
events.delete(rigidBody.handle);
|
1203
|
+
};
|
1204
|
+
}, [onWake, onSleep, onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit, onContactForce]);
|
1205
|
+
};
|
1206
|
+
|
1207
|
+
/**
|
1208
|
+
* Takes an object resembling a Vector3 and returs a Three.Vector3
|
1209
|
+
* @category Math helpers
|
1210
|
+
*/
|
1211
|
+
const vec3 = ({
|
1212
|
+
x,
|
1213
|
+
y,
|
1214
|
+
z
|
1215
|
+
} = {
|
1216
|
+
x: 0,
|
1217
|
+
y: 0,
|
1218
|
+
z: 0
|
1219
|
+
}) => {
|
1220
|
+
return new three.Vector3(x, y, z);
|
1221
|
+
};
|
1222
|
+
|
1223
|
+
/**
|
1224
|
+
* Takes an object resembling a Quaternion and returs a Three.Quaternion
|
1225
|
+
* @category Math helpers
|
1226
|
+
*/
|
1227
|
+
const quat = ({
|
1228
|
+
x,
|
1229
|
+
y,
|
1230
|
+
z,
|
1231
|
+
w
|
1232
|
+
} = {
|
1233
|
+
x: 0,
|
1234
|
+
y: 0,
|
1235
|
+
z: 0,
|
1236
|
+
w: 1
|
1237
|
+
}) => {
|
1238
|
+
return new three.Quaternion(x, y, z, w);
|
1239
|
+
};
|
1240
|
+
|
1241
|
+
/**
|
1242
|
+
* Takes an object resembling an Euler and returs a Three.Euler
|
1243
|
+
* @category Math helpers
|
1244
|
+
*/
|
1245
|
+
const euler = ({
|
1246
|
+
x,
|
1247
|
+
y,
|
1248
|
+
z
|
1249
|
+
} = {
|
1250
|
+
x: 0,
|
1251
|
+
y: 0,
|
1252
|
+
z: 0
|
1253
|
+
}) => {
|
1254
|
+
return new three.Euler(x, y, z);
|
1255
|
+
};
|
1256
|
+
|
1257
|
+
/**
|
1258
|
+
* A collider is a shape that can be attached to a rigid body to define its physical properties.
|
1259
|
+
* @internal
|
1260
|
+
*/
|
1261
|
+
const AnyCollider = /*#__PURE__*/React.memo(props => {
|
1262
|
+
const {
|
1263
|
+
children,
|
1264
|
+
position,
|
1265
|
+
rotation,
|
1266
|
+
quaternion,
|
1267
|
+
scale,
|
1268
|
+
name
|
1269
|
+
} = props;
|
1270
|
+
const {
|
1271
|
+
world,
|
1272
|
+
colliderEvents,
|
1273
|
+
colliderStates
|
1274
|
+
} = useRapier();
|
1275
|
+
const rigidBodyContext = useRigidBodyContext();
|
1276
|
+
const colliderRef = useForwardedRef(props.ref);
|
1277
|
+
const objectRef = React.useRef(null);
|
1278
|
+
|
1279
|
+
// We spread the props out here to make sure that the ref is updated when the props change.
|
1280
|
+
const immutablePropArray = immutableColliderOptions.flatMap(key =>
|
1281
|
+
// Array.isArray(props[key]) ? [...props[key]] : props[key]
|
1282
|
+
Array.isArray(props[key]) ? props[key] : [props[key]]);
|
1283
|
+
const getInstance = useImperativeInstance(() => {
|
1284
|
+
const worldScale = objectRef.current.getWorldScale(vec3());
|
1285
|
+
const collider = createColliderFromOptions(props, world, worldScale, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.getRigidBody);
|
1286
|
+
if (typeof props.ref == "function") {
|
1287
|
+
props.ref(collider);
|
1288
|
+
}
|
1225
1289
|
colliderRef.current = collider;
|
1226
1290
|
return collider;
|
1227
1291
|
}, collider => {
|
@@ -1249,8 +1313,7 @@ const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((prop
|
|
1249
1313
|
ref: objectRef,
|
1250
1314
|
name: name
|
1251
1315
|
}, children);
|
1252
|
-
})
|
1253
|
-
|
1316
|
+
});
|
1254
1317
|
/**
|
1255
1318
|
* A cuboid collider shape
|
1256
1319
|
* @category Colliders
|
@@ -1262,7 +1325,6 @@ const CuboidCollider = /*#__PURE__*/React__default["default"].forwardRef((props,
|
|
1262
1325
|
}));
|
1263
1326
|
});
|
1264
1327
|
CuboidCollider.displayName = "CuboidCollider";
|
1265
|
-
|
1266
1328
|
/**
|
1267
1329
|
* A round cuboid collider shape
|
1268
1330
|
* @category Colliders
|
@@ -1272,7 +1334,6 @@ const RoundCuboidCollider = /*#__PURE__*/React__default["default"].forwardRef((p
|
|
1272
1334
|
ref: ref
|
1273
1335
|
})));
|
1274
1336
|
RoundCuboidCollider.displayName = "RoundCuboidCollider";
|
1275
|
-
|
1276
1337
|
/**
|
1277
1338
|
* A ball collider shape
|
1278
1339
|
* @category Colliders
|
@@ -1282,7 +1343,6 @@ const BallCollider = /*#__PURE__*/React__default["default"].forwardRef((props, r
|
|
1282
1343
|
ref: ref
|
1283
1344
|
})));
|
1284
1345
|
BallCollider.displayName = "BallCollider";
|
1285
|
-
|
1286
1346
|
/**
|
1287
1347
|
* A capsule collider shape
|
1288
1348
|
* @category Colliders
|
@@ -1292,7 +1352,6 @@ const CapsuleCollider = /*#__PURE__*/React__default["default"].forwardRef((props
|
|
1292
1352
|
ref: ref
|
1293
1353
|
})));
|
1294
1354
|
CapsuleCollider.displayName = "CapsuleCollider";
|
1295
|
-
|
1296
1355
|
/**
|
1297
1356
|
* A heightfield collider shape
|
1298
1357
|
* @category Colliders
|
@@ -1302,7 +1361,6 @@ const HeightfieldCollider = /*#__PURE__*/React__default["default"].forwardRef((p
|
|
1302
1361
|
ref: ref
|
1303
1362
|
})));
|
1304
1363
|
HeightfieldCollider.displayName = "HeightfieldCollider";
|
1305
|
-
|
1306
1364
|
/**
|
1307
1365
|
* A trimesh collider shape
|
1308
1366
|
* @category Colliders
|
@@ -1312,7 +1370,6 @@ const TrimeshCollider = /*#__PURE__*/React__default["default"].forwardRef((props
|
|
1312
1370
|
ref: ref
|
1313
1371
|
})));
|
1314
1372
|
TrimeshCollider.displayName = "TrimeshCollider";
|
1315
|
-
|
1316
1373
|
/**
|
1317
1374
|
* A cone collider shape
|
1318
1375
|
* @category Colliders
|
@@ -1322,7 +1379,6 @@ const ConeCollider = /*#__PURE__*/React__default["default"].forwardRef((props, r
|
|
1322
1379
|
ref: ref
|
1323
1380
|
})));
|
1324
1381
|
ConeCollider.displayName = "ConeCollider";
|
1325
|
-
|
1326
1382
|
/**
|
1327
1383
|
* A round cylinder collider shape
|
1328
1384
|
* @category Colliders
|
@@ -1332,7 +1388,6 @@ const RoundConeCollider = /*#__PURE__*/React__default["default"].forwardRef((pro
|
|
1332
1388
|
ref: ref
|
1333
1389
|
})));
|
1334
1390
|
RoundConeCollider.displayName = "RoundConeCollider";
|
1335
|
-
|
1336
1391
|
/**
|
1337
1392
|
* A cylinder collider shape
|
1338
1393
|
* @category Colliders
|
@@ -1342,7 +1397,6 @@ const CylinderCollider = /*#__PURE__*/React__default["default"].forwardRef((prop
|
|
1342
1397
|
ref: ref
|
1343
1398
|
})));
|
1344
1399
|
CylinderCollider.displayName = "CylinderCollider";
|
1345
|
-
|
1346
1400
|
/**
|
1347
1401
|
* A round cylinder collider shape
|
1348
1402
|
* @category Colliders
|
@@ -1352,7 +1406,6 @@ const RoundCylinderCollider = /*#__PURE__*/React__default["default"].forwardRef(
|
|
1352
1406
|
ref: ref
|
1353
1407
|
})));
|
1354
1408
|
CylinderCollider.displayName = "RoundCylinderCollider";
|
1355
|
-
|
1356
1409
|
/**
|
1357
1410
|
* A convex hull collider shape
|
1358
1411
|
* @category Colliders
|
@@ -1363,187 +1416,27 @@ const ConvexHullCollider = /*#__PURE__*/React__default["default"].forwardRef((pr
|
|
1363
1416
|
})));
|
1364
1417
|
ConvexHullCollider.displayName = "ConvexHullCollider";
|
1365
1418
|
|
1366
|
-
const
|
1367
|
-
var _options$canSleep;
|
1368
|
-
|
1369
|
-
const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
|
1370
|
-
const desc = new rapier3dCompat.RigidBodyDesc(type); // Apply immutable options
|
1371
|
-
|
1372
|
-
desc.canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
|
1373
|
-
return desc;
|
1374
|
-
};
|
1375
|
-
const createRigidBodyState = ({
|
1376
|
-
rigidBody,
|
1377
|
-
object,
|
1378
|
-
setMatrix,
|
1379
|
-
getMatrix,
|
1380
|
-
worldScale,
|
1381
|
-
meshType: _meshType = "mesh"
|
1382
|
-
}) => {
|
1383
|
-
object.updateWorldMatrix(true, false);
|
1384
|
-
const invertedWorldMatrix = object.parent.matrixWorld.clone().invert();
|
1385
|
-
return {
|
1386
|
-
object,
|
1387
|
-
rigidBody,
|
1388
|
-
invertedWorldMatrix,
|
1389
|
-
setMatrix: setMatrix ? setMatrix : matrix => {
|
1390
|
-
object.matrix.copy(matrix);
|
1391
|
-
},
|
1392
|
-
getMatrix: getMatrix ? getMatrix : matrix => matrix.copy(object.matrix),
|
1393
|
-
scale: worldScale || object.getWorldScale(_scale).clone(),
|
1394
|
-
isSleeping: false,
|
1395
|
-
meshType: _meshType
|
1396
|
-
};
|
1397
|
-
};
|
1398
|
-
const immutableRigidBodyOptions = ["args", "colliders", "canSleep"];
|
1399
|
-
const mutableRigidBodyOptions = {
|
1400
|
-
gravityScale: (rb, value) => {
|
1401
|
-
rb.setGravityScale(value, true);
|
1402
|
-
},
|
1403
|
-
|
1404
|
-
additionalSolverIterations(rb, value) {
|
1405
|
-
rb.setAdditionalSolverIterations(value);
|
1406
|
-
},
|
1407
|
-
|
1408
|
-
linearDamping: (rb, value) => {
|
1409
|
-
rb.setLinearDamping(value);
|
1410
|
-
},
|
1411
|
-
angularDamping: (rb, value) => {
|
1412
|
-
rb.setAngularDamping(value);
|
1413
|
-
},
|
1414
|
-
dominanceGroup: (rb, value) => {
|
1415
|
-
rb.setDominanceGroup(value);
|
1416
|
-
},
|
1417
|
-
enabledRotations: (rb, [x, y, z]) => {
|
1418
|
-
rb.setEnabledRotations(x, y, z, true);
|
1419
|
-
},
|
1420
|
-
enabledTranslations: (rb, [x, y, z]) => {
|
1421
|
-
rb.setEnabledTranslations(x, y, z, true);
|
1422
|
-
},
|
1423
|
-
lockRotations: (rb, value) => {
|
1424
|
-
rb.lockRotations(value, true);
|
1425
|
-
},
|
1426
|
-
lockTranslations: (rb, value) => {
|
1427
|
-
rb.lockTranslations(value, true);
|
1428
|
-
},
|
1429
|
-
angularVelocity: (rb, [x, y, z]) => {
|
1430
|
-
rb.setAngvel({
|
1431
|
-
x,
|
1432
|
-
y,
|
1433
|
-
z
|
1434
|
-
}, true);
|
1435
|
-
},
|
1436
|
-
linearVelocity: (rb, [x, y, z]) => {
|
1437
|
-
rb.setLinvel({
|
1438
|
-
x,
|
1439
|
-
y,
|
1440
|
-
z
|
1441
|
-
}, true);
|
1442
|
-
},
|
1443
|
-
ccd: (rb, value) => {
|
1444
|
-
rb.enableCcd(value);
|
1445
|
-
},
|
1446
|
-
softCcdPrediction: (rb, value) => {
|
1447
|
-
rb.setSoftCcdPrediction(value);
|
1448
|
-
},
|
1449
|
-
userData: (rb, value) => {
|
1450
|
-
rb.userData = value;
|
1451
|
-
},
|
1452
|
-
|
1453
|
-
type(rb, value) {
|
1454
|
-
rb.setBodyType(rigidBodyTypeFromString(value), true);
|
1455
|
-
},
|
1456
|
-
|
1457
|
-
position: () => {},
|
1458
|
-
rotation: () => {},
|
1459
|
-
quaternion: () => {},
|
1460
|
-
scale: () => {}
|
1461
|
-
};
|
1462
|
-
const mutableRigidBodyOptionKeys = Object.keys(mutableRigidBodyOptions);
|
1463
|
-
const setRigidBodyOptions = (rigidBody, options, states, updateTranslations = true) => {
|
1464
|
-
if (!rigidBody) {
|
1465
|
-
return;
|
1466
|
-
}
|
1467
|
-
|
1468
|
-
const state = states.get(rigidBody.handle);
|
1469
|
-
|
1470
|
-
if (state) {
|
1471
|
-
if (updateTranslations) {
|
1472
|
-
state.object.updateWorldMatrix(true, false);
|
1473
|
-
|
1474
|
-
_matrix4.copy(state.object.matrixWorld).decompose(_position, _rotation, _scale);
|
1475
|
-
|
1476
|
-
rigidBody.setTranslation(_position, false);
|
1477
|
-
rigidBody.setRotation(_rotation, false);
|
1478
|
-
}
|
1479
|
-
|
1480
|
-
mutableRigidBodyOptionKeys.forEach(key => {
|
1481
|
-
if (key in options) {
|
1482
|
-
mutableRigidBodyOptions[key](rigidBody, options[key]);
|
1483
|
-
}
|
1484
|
-
});
|
1485
|
-
}
|
1486
|
-
};
|
1487
|
-
const useUpdateRigidBodyOptions = (getRigidBody, props, states, updateTranslations = true) => {
|
1488
|
-
// TODO: Improve this, split each prop into its own effect
|
1489
|
-
const mutablePropsAsFlatArray = React.useMemo(() => mutableRigidBodyOptionKeys.flatMap(key => {
|
1490
|
-
return vectorToTuple(props[key]);
|
1491
|
-
}), [props]);
|
1492
|
-
React.useEffect(() => {
|
1493
|
-
const rigidBody = getRigidBody();
|
1494
|
-
setRigidBodyOptions(rigidBody, props, states, updateTranslations);
|
1495
|
-
}, mutablePropsAsFlatArray);
|
1496
|
-
};
|
1497
|
-
const useRigidBodyEvents = (getRigidBody, props, events) => {
|
1498
|
-
const {
|
1499
|
-
onWake,
|
1500
|
-
onSleep,
|
1501
|
-
onCollisionEnter,
|
1502
|
-
onCollisionExit,
|
1503
|
-
onIntersectionEnter,
|
1504
|
-
onIntersectionExit,
|
1505
|
-
onContactForce
|
1506
|
-
} = props;
|
1507
|
-
const eventHandlers = {
|
1508
|
-
onWake,
|
1509
|
-
onSleep,
|
1510
|
-
onCollisionEnter,
|
1511
|
-
onCollisionExit,
|
1512
|
-
onIntersectionEnter,
|
1513
|
-
onIntersectionExit,
|
1514
|
-
onContactForce
|
1515
|
-
};
|
1516
|
-
React.useEffect(() => {
|
1517
|
-
const rigidBody = getRigidBody();
|
1518
|
-
events.set(rigidBody.handle, eventHandlers);
|
1519
|
-
return () => {
|
1520
|
-
events.delete(rigidBody.handle);
|
1521
|
-
};
|
1522
|
-
}, [onWake, onSleep, onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit, onContactForce]);
|
1523
|
-
};
|
1524
|
-
|
1525
|
-
const _excluded$1 = ["children", "type", "position", "rotation", "scale", "quaternion", "transformState"];
|
1419
|
+
const _excluded$1 = ["ref", "children", "type", "position", "rotation", "scale", "quaternion", "transformState"];
|
1526
1420
|
const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
|
1527
1421
|
const useRigidBodyContext = () => React.useContext(RigidBodyContext);
|
1528
|
-
|
1529
1422
|
/**
|
1530
1423
|
* A rigid body is a physical object that can be simulated by the physics engine.
|
1531
1424
|
* @category Components
|
1532
1425
|
*/
|
1533
|
-
const RigidBody = /*#__PURE__*/React.memo(
|
1426
|
+
const RigidBody = /*#__PURE__*/React.memo(props => {
|
1534
1427
|
const {
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1428
|
+
ref,
|
1429
|
+
children,
|
1430
|
+
type,
|
1431
|
+
position,
|
1432
|
+
rotation,
|
1433
|
+
scale,
|
1434
|
+
quaternion,
|
1435
|
+
transformState
|
1436
|
+
} = props,
|
1437
|
+
objectProps = _objectWithoutProperties(props, _excluded$1);
|
1545
1438
|
const objectRef = React.useRef(null);
|
1546
|
-
const rigidBodyRef = useForwardedRef(
|
1439
|
+
const rigidBodyRef = useForwardedRef(ref);
|
1547
1440
|
const {
|
1548
1441
|
world,
|
1549
1442
|
rigidBodyStates,
|
@@ -1558,24 +1451,24 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
|
|
1558
1451
|
const immutablePropArray = immutableRigidBodyOptions.flatMap(key => {
|
1559
1452
|
return Array.isArray(mergedOptions[key]) ? [...mergedOptions[key]] : mergedOptions[key];
|
1560
1453
|
});
|
1561
|
-
const childColliderProps = useChildColliderProps(objectRef, mergedOptions);
|
1454
|
+
const childColliderProps = useChildColliderProps(objectRef, mergedOptions);
|
1562
1455
|
|
1456
|
+
// Provide a way to eagerly create rigidbody
|
1563
1457
|
const getRigidBody = useImperativeInstance(() => {
|
1564
1458
|
const desc = rigidBodyDescFromOptions(mergedOptions);
|
1565
1459
|
const rigidBody = world.createRigidBody(desc);
|
1566
|
-
|
1567
|
-
|
1568
|
-
forwardedRef(rigidBody);
|
1460
|
+
if (typeof ref === "function") {
|
1461
|
+
ref(rigidBody);
|
1569
1462
|
}
|
1570
|
-
|
1571
1463
|
rigidBodyRef.current = rigidBody;
|
1572
1464
|
return rigidBody;
|
1573
1465
|
}, rigidBody => {
|
1574
1466
|
if (world.getRigidBody(rigidBody.handle)) {
|
1575
1467
|
world.removeRigidBody(rigidBody);
|
1576
1468
|
}
|
1577
|
-
}, immutablePropArray);
|
1469
|
+
}, immutablePropArray);
|
1578
1470
|
|
1471
|
+
// Only provide a object state after the ref has been set
|
1579
1472
|
React.useEffect(() => {
|
1580
1473
|
const rigidBody = getRigidBody();
|
1581
1474
|
const state = createRigidBodyState({
|
@@ -1608,7 +1501,7 @@ const RigidBody = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props,
|
|
1608
1501
|
}), children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({
|
1609
1502
|
key: index
|
1610
1503
|
}, colliderProps)))));
|
1611
|
-
})
|
1504
|
+
});
|
1612
1505
|
RigidBody.displayName = "RigidBody";
|
1613
1506
|
|
1614
1507
|
/**
|
@@ -1645,52 +1538,52 @@ const MeshCollider = /*#__PURE__*/React.memo(props => {
|
|
1645
1538
|
});
|
1646
1539
|
MeshCollider.displayName = "MeshCollider";
|
1647
1540
|
|
1648
|
-
const _excluded = ["
|
1649
|
-
|
1650
|
-
|
1541
|
+
const _excluded = ["ref"],
|
1542
|
+
_excluded2 = ["children", "instances", "colliderNodes", "position", "rotation", "quaternion", "scale"];
|
1543
|
+
const InstancedRigidBodies = /*#__PURE__*/React.memo(_ref => {
|
1544
|
+
let {
|
1545
|
+
ref
|
1546
|
+
} = _ref,
|
1547
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
1548
|
+
const rigidBodiesRef = useForwardedRef(ref, []);
|
1651
1549
|
const objectRef = React.useRef(null);
|
1652
1550
|
const instanceWrapperRef = React.useRef(null);
|
1653
|
-
|
1654
1551
|
const {
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1552
|
+
// instanced props
|
1553
|
+
children,
|
1554
|
+
instances,
|
1555
|
+
colliderNodes = [],
|
1556
|
+
// wrapper object props
|
1557
|
+
position,
|
1558
|
+
rotation,
|
1559
|
+
quaternion,
|
1560
|
+
scale
|
1561
|
+
|
1562
|
+
// rigid body specific props, and r3f-object props
|
1563
|
+
} = props,
|
1564
|
+
rigidBodyProps = _objectWithoutProperties(props, _excluded2);
|
1667
1565
|
const childColliderProps = useChildColliderProps(objectRef, _objectSpread2(_objectSpread2({}, props), {}, {
|
1668
1566
|
children: undefined
|
1669
1567
|
}));
|
1670
|
-
|
1671
1568
|
const getInstancedMesh = () => {
|
1672
1569
|
const firstChild = instanceWrapperRef.current.children[0];
|
1673
|
-
|
1674
1570
|
if (firstChild && "isInstancedMesh" in firstChild) {
|
1675
1571
|
return firstChild;
|
1676
1572
|
}
|
1677
|
-
|
1678
1573
|
return undefined;
|
1679
1574
|
};
|
1680
|
-
|
1681
1575
|
React.useEffect(() => {
|
1682
1576
|
const instancedMesh = getInstancedMesh();
|
1683
|
-
|
1684
1577
|
if (instancedMesh) {
|
1685
1578
|
instancedMesh.instanceMatrix.setUsage(three.DynamicDrawUsage);
|
1686
1579
|
} else {
|
1687
1580
|
console.warn("InstancedRigidBodies expects exactly one child, which must be an InstancedMesh");
|
1688
1581
|
}
|
1689
|
-
}, []);
|
1582
|
+
}, []);
|
1690
1583
|
|
1584
|
+
// Update the RigidBodyStates whenever the instances change
|
1691
1585
|
const applyInstancedState = (state, index) => {
|
1692
1586
|
const instancedMesh = getInstancedMesh();
|
1693
|
-
|
1694
1587
|
if (instancedMesh) {
|
1695
1588
|
return _objectSpread2(_objectSpread2({}, state), {}, {
|
1696
1589
|
getMatrix: matrix => {
|
@@ -1704,10 +1597,8 @@ const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forward
|
|
1704
1597
|
meshType: "instancedMesh"
|
1705
1598
|
});
|
1706
1599
|
}
|
1707
|
-
|
1708
1600
|
return state;
|
1709
1601
|
};
|
1710
|
-
|
1711
1602
|
return /*#__PURE__*/React__default["default"].createElement("object3D", _extends({
|
1712
1603
|
ref: objectRef
|
1713
1604
|
}, rigidBodyProps, {
|
@@ -1718,25 +1609,26 @@ const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forward
|
|
1718
1609
|
}), /*#__PURE__*/React__default["default"].createElement("object3D", {
|
1719
1610
|
ref: instanceWrapperRef
|
1720
1611
|
}, children), instances === null || instances === void 0 ? void 0 : instances.map((instance, index) => /*#__PURE__*/React__default["default"].createElement(RigidBody, _extends({}, rigidBodyProps, instance, {
|
1721
|
-
ref: body =>
|
1612
|
+
ref: body => {
|
1613
|
+
rigidBodiesRef.current[index] = body;
|
1614
|
+
},
|
1722
1615
|
transformState: state => applyInstancedState(state, index)
|
1723
1616
|
}), /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, colliderNodes.map((node, index) => /*#__PURE__*/React__default["default"].createElement(React.Fragment, {
|
1724
1617
|
key: index
|
1725
1618
|
}, node)), childColliderProps.map((colliderProps, colliderIndex) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({
|
1726
1619
|
key: colliderIndex
|
1727
1620
|
}, colliderProps)))))));
|
1728
|
-
})
|
1621
|
+
});
|
1729
1622
|
InstancedRigidBodies.displayName = "InstancedRigidBodies";
|
1730
1623
|
|
1731
1624
|
/**
|
1732
1625
|
* @internal
|
1733
1626
|
*/
|
1734
|
-
|
1735
1627
|
const useImpulseJoint = (body1, body2, params) => {
|
1736
1628
|
const {
|
1737
1629
|
world
|
1738
1630
|
} = useRapier();
|
1739
|
-
const jointRef = React.useRef();
|
1631
|
+
const jointRef = React.useRef(undefined);
|
1740
1632
|
useImperativeInstance(() => {
|
1741
1633
|
if (body1.current && body2.current) {
|
1742
1634
|
const newJoint = world.createImpulseJoint(params, body1.current, body2.current, true);
|
@@ -1746,7 +1638,6 @@ const useImpulseJoint = (body1, body2, params) => {
|
|
1746
1638
|
}, joint => {
|
1747
1639
|
if (joint) {
|
1748
1640
|
jointRef.current = undefined;
|
1749
|
-
|
1750
1641
|
if (world.getImpulseJoint(joint.handle)) {
|
1751
1642
|
world.removeImpulseJoint(joint, true);
|
1752
1643
|
}
|
@@ -1754,6 +1645,7 @@ const useImpulseJoint = (body1, body2, params) => {
|
|
1754
1645
|
}, []);
|
1755
1646
|
return jointRef;
|
1756
1647
|
};
|
1648
|
+
|
1757
1649
|
/**
|
1758
1650
|
* A fixed joint ensures that two rigid-bodies don't move relative to each other.
|
1759
1651
|
* Fixed joints are characterized by one local frame (represented by an isometry) on each rigid-body.
|
@@ -1761,13 +1653,13 @@ const useImpulseJoint = (body1, body2, params) => {
|
|
1761
1653
|
*
|
1762
1654
|
* @category Hooks - Joints
|
1763
1655
|
*/
|
1764
|
-
|
1765
1656
|
const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor, body2LocalFrame]) => {
|
1766
1657
|
const {
|
1767
1658
|
rapier
|
1768
1659
|
} = useRapier();
|
1769
1660
|
return useImpulseJoint(body1, body2, rapier.JointData.fixed(vector3ToRapierVector(body1Anchor), quaternionToRapierQuaternion(body1LocalFrame), vector3ToRapierVector(body2Anchor), quaternionToRapierQuaternion(body2LocalFrame)));
|
1770
1661
|
};
|
1662
|
+
|
1771
1663
|
/**
|
1772
1664
|
* The spherical joint ensures that two points on the local-spaces of two rigid-bodies always coincide (it prevents any relative
|
1773
1665
|
* translational motion at this points). This is typically used to simulate ragdolls arms, pendulums, etc.
|
@@ -1776,13 +1668,13 @@ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor,
|
|
1776
1668
|
*
|
1777
1669
|
* @category Hooks - Joints
|
1778
1670
|
*/
|
1779
|
-
|
1780
1671
|
const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
1781
1672
|
const {
|
1782
1673
|
rapier
|
1783
1674
|
} = useRapier();
|
1784
1675
|
return useImpulseJoint(body1, body2, rapier.JointData.spherical(vector3ToRapierVector(body1Anchor), vector3ToRapierVector(body2Anchor)));
|
1785
1676
|
};
|
1677
|
+
|
1786
1678
|
/**
|
1787
1679
|
* The revolute joint prevents any relative movement between two rigid-bodies, except for relative
|
1788
1680
|
* rotations along one axis. This is typically used to simulate wheels, fans, etc.
|
@@ -1790,20 +1682,18 @@ const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
|
1790
1682
|
*
|
1791
1683
|
* @category Hooks - Joints
|
1792
1684
|
*/
|
1793
|
-
|
1794
1685
|
const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis, limits]) => {
|
1795
1686
|
const {
|
1796
1687
|
rapier
|
1797
1688
|
} = useRapier();
|
1798
1689
|
const params = rapier.JointData.revolute(vector3ToRapierVector(body1Anchor), vector3ToRapierVector(body2Anchor), vector3ToRapierVector(axis));
|
1799
|
-
|
1800
1690
|
if (limits) {
|
1801
1691
|
params.limitsEnabled = true;
|
1802
1692
|
params.limits = limits;
|
1803
1693
|
}
|
1804
|
-
|
1805
1694
|
return useImpulseJoint(body1, body2, params);
|
1806
1695
|
};
|
1696
|
+
|
1807
1697
|
/**
|
1808
1698
|
* The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
|
1809
1699
|
* It is characterized by one local anchor as well as one local axis on each rigid-body. In 3D, an optional
|
@@ -1811,25 +1701,22 @@ const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis, limits]
|
|
1811
1701
|
*
|
1812
1702
|
* @category Hooks - Joints
|
1813
1703
|
*/
|
1814
|
-
|
1815
1704
|
const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis, limits]) => {
|
1816
1705
|
const {
|
1817
1706
|
rapier
|
1818
1707
|
} = useRapier();
|
1819
1708
|
const params = rapier.JointData.prismatic(vector3ToRapierVector(body1Anchor), vector3ToRapierVector(body2Anchor), vector3ToRapierVector(axis));
|
1820
|
-
|
1821
1709
|
if (limits) {
|
1822
1710
|
params.limitsEnabled = true;
|
1823
1711
|
params.limits = limits;
|
1824
1712
|
}
|
1825
|
-
|
1826
1713
|
return useImpulseJoint(body1, body2, params);
|
1827
1714
|
};
|
1715
|
+
|
1828
1716
|
/**
|
1829
1717
|
* The rope joint limits the max distance between two bodies.
|
1830
1718
|
* @category Hooks - Joints
|
1831
1719
|
*/
|
1832
|
-
|
1833
1720
|
const useRopeJoint = (body1, body2, [body1Anchor, body2Anchor, length]) => {
|
1834
1721
|
const {
|
1835
1722
|
rapier
|
@@ -1839,11 +1726,11 @@ const useRopeJoint = (body1, body2, [body1Anchor, body2Anchor, length]) => {
|
|
1839
1726
|
const params = rapier.JointData.rope(length, vBody1Anchor, vBody2Anchor);
|
1840
1727
|
return useImpulseJoint(body1, body2, params);
|
1841
1728
|
};
|
1729
|
+
|
1842
1730
|
/**
|
1843
1731
|
* The spring joint applies a force proportional to the distance between two objects.
|
1844
1732
|
* @category Hooks - Joints
|
1845
1733
|
*/
|
1846
|
-
|
1847
1734
|
const useSpringJoint = (body1, body2, [body1Anchor, body2Anchor, restLength, stiffness, damping]) => {
|
1848
1735
|
const {
|
1849
1736
|
rapier
|
@@ -1887,7 +1774,6 @@ const useSpringJoint = (body1, body2, [body1Anchor, body2Anchor, restLength, sti
|
|
1887
1774
|
* @returns An InteractionGroup bitmask.
|
1888
1775
|
*/
|
1889
1776
|
const interactionGroups = (memberships, filters) => (bitmask(memberships) << 16) + (filters !== undefined ? bitmask(filters) : 0b1111111111111111);
|
1890
|
-
|
1891
1777
|
const bitmask = groups => [groups].flat().reduce((acc, layer) => acc | 1 << layer, 0);
|
1892
1778
|
|
1893
1779
|
Object.defineProperty(exports, 'CoefficientCombineRule', {
|