@react-three/rapier 0.1.1 → 0.3.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/CHANGELOG.md +24 -0
- package/dist/declarations/src/Physics.d.ts +23 -4
- package/dist/declarations/src/api.d.ts +33 -0
- package/dist/declarations/src/components.d.ts +11 -3
- package/dist/declarations/src/hooks.d.ts +172 -24
- package/dist/declarations/src/index.d.ts +1 -1
- package/dist/declarations/src/types.d.ts +24 -2
- package/dist/declarations/src/utils.d.ts +5 -5
- package/dist/react-three-rapier.cjs.dev.js +381 -135
- package/dist/react-three-rapier.cjs.prod.js +381 -135
- package/dist/react-three-rapier.esm.js +384 -138
- package/package.json +1 -1
@@ -63,11 +63,11 @@ const scaleColliderArgs = (shape, args, scale) => {
|
|
63
63
|
const scaleArray = [scale.x, scale.y, scale.z];
|
64
64
|
return newArgs.map((arg, index) => scaleArray[index] * arg);
|
65
65
|
};
|
66
|
-
const createColliderFromOptions = (options, world,
|
66
|
+
const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
|
67
67
|
x: 1,
|
68
68
|
y: 1,
|
69
69
|
z: 1
|
70
|
-
}) => {
|
70
|
+
}, hasCollisionEvents = false) => {
|
71
71
|
var _options$shape, _options$args, _options$restitution, _options$restitutionC, _options$friction, _options$frictionComb;
|
72
72
|
|
73
73
|
const mass = (options === null || options === void 0 ? void 0 : options.mass) || 1;
|
@@ -85,7 +85,12 @@ const createColliderFromOptions = (options, world, body, scale = {
|
|
85
85
|
y: ry,
|
86
86
|
z: rz,
|
87
87
|
w: 1
|
88
|
-
}).setRestitution((_options$restitution = options === null || options === void 0 ? void 0 : options.restitution) !== null && _options$restitution !== void 0 ? _options$restitution : 0).setRestitutionCombineRule((_options$restitutionC = options === null || options === void 0 ? void 0 : options.restitutionCombineRule) !== null && _options$restitutionC !== void 0 ? _options$restitutionC : rapier3dCompat.CoefficientCombineRule.Average).setFriction((_options$friction = options === null || options === void 0 ? void 0 : options.friction) !== null && _options$friction !== void 0 ? _options$friction : 0.7).setFrictionCombineRule((_options$frictionComb = options === null || options === void 0 ? void 0 : options.frictionCombineRule) !== null && _options$frictionComb !== void 0 ? _options$frictionComb : rapier3dCompat.CoefficientCombineRule.Average);
|
88
|
+
}).setRestitution((_options$restitution = options === null || options === void 0 ? void 0 : options.restitution) !== null && _options$restitution !== void 0 ? _options$restitution : 0).setRestitutionCombineRule((_options$restitutionC = options === null || options === void 0 ? void 0 : options.restitutionCombineRule) !== null && _options$restitutionC !== void 0 ? _options$restitutionC : rapier3dCompat.CoefficientCombineRule.Average).setFriction((_options$friction = options === null || options === void 0 ? void 0 : options.friction) !== null && _options$friction !== void 0 ? _options$friction : 0.7).setFrictionCombineRule((_options$frictionComb = options === null || options === void 0 ? void 0 : options.frictionCombineRule) !== null && _options$frictionComb !== void 0 ? _options$frictionComb : rapier3dCompat.CoefficientCombineRule.Average);
|
89
|
+
|
90
|
+
if (hasCollisionEvents) {
|
91
|
+
colliderDesc = colliderDesc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
|
92
|
+
} // If any of the mass properties are specified, add mass properties
|
93
|
+
|
89
94
|
|
90
95
|
if (options !== null && options !== void 0 && options.mass || options !== null && options !== void 0 && options.centerOfMass || options !== null && options !== void 0 && options.principalAngularInertia) {
|
91
96
|
colliderDesc.setDensity(0);
|
@@ -105,12 +110,13 @@ const createColliderFromOptions = (options, world, body, scale = {
|
|
105
110
|
});
|
106
111
|
}
|
107
112
|
|
108
|
-
const collider = world.createCollider(colliderDesc,
|
113
|
+
const collider = world.createCollider(colliderDesc, rigidBodyHandle);
|
109
114
|
return collider;
|
110
115
|
};
|
111
|
-
const createCollidersFromChildren = (object, rigidBody, type, world) => {
|
116
|
+
const createCollidersFromChildren = (object, rigidBody, type, world, hasCollisionEvents = false) => {
|
112
117
|
const colliders = [];
|
113
118
|
let desc;
|
119
|
+
let offset = new three.Vector3();
|
114
120
|
object.traverse(child => {
|
115
121
|
if ("isMesh" in child) {
|
116
122
|
const {
|
@@ -137,6 +143,7 @@ const createCollidersFromChildren = (object, rigidBody, type, world) => {
|
|
137
143
|
boundingBox
|
138
144
|
} = geometry;
|
139
145
|
const size = boundingBox.getSize(new three.Vector3());
|
146
|
+
boundingBox.getCenter(offset);
|
140
147
|
desc = rapier3dCompat.ColliderDesc.cuboid(size.x / 2 * scale.x, size.y / 2 * scale.y, size.z / 2 * scale.z);
|
141
148
|
}
|
142
149
|
break;
|
@@ -148,6 +155,7 @@ const createCollidersFromChildren = (object, rigidBody, type, world) => {
|
|
148
155
|
boundingSphere
|
149
156
|
} = geometry;
|
150
157
|
const radius = boundingSphere.radius * scale.x;
|
158
|
+
offset.copy(boundingSphere.center);
|
151
159
|
desc = rapier3dCompat.ColliderDesc.ball(radius);
|
152
160
|
}
|
153
161
|
break;
|
@@ -172,12 +180,17 @@ const createCollidersFromChildren = (object, rigidBody, type, world) => {
|
|
172
180
|
|
173
181
|
|
174
182
|
const parentWorldScale = child.parent.getWorldScale(new three.Vector3());
|
175
|
-
desc.setTranslation(x * parentWorldScale.x, y * parentWorldScale.y, z * parentWorldScale.z).setRotation({
|
183
|
+
desc.setTranslation((x + offset.x) * parentWorldScale.x, (y + offset.y) * parentWorldScale.y, (z + offset.z) * parentWorldScale.z).setRotation({
|
176
184
|
x: rx,
|
177
185
|
y: ry,
|
178
186
|
z: rz,
|
179
187
|
w: rw
|
180
188
|
});
|
189
|
+
|
190
|
+
if (hasCollisionEvents) {
|
191
|
+
desc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
|
192
|
+
}
|
193
|
+
|
181
194
|
const collider = world.createCollider(desc, rigidBody.handle);
|
182
195
|
colliders.push(collider);
|
183
196
|
}
|
@@ -196,6 +209,99 @@ const scaleVertices = (vertices, scale) => {
|
|
196
209
|
return scaledVerts;
|
197
210
|
};
|
198
211
|
|
212
|
+
// TODO: Flesh this out
|
213
|
+
const createRigidBodyApi = ref => {
|
214
|
+
return {
|
215
|
+
raw: () => ref.current(),
|
216
|
+
|
217
|
+
get handle() {
|
218
|
+
return ref.current().handle;
|
219
|
+
},
|
220
|
+
|
221
|
+
applyImpulse({
|
222
|
+
x,
|
223
|
+
y,
|
224
|
+
z
|
225
|
+
}) {
|
226
|
+
ref.current().applyImpulse({
|
227
|
+
x,
|
228
|
+
y,
|
229
|
+
z
|
230
|
+
}, true);
|
231
|
+
},
|
232
|
+
|
233
|
+
applyTorqueImpulse({
|
234
|
+
x,
|
235
|
+
y,
|
236
|
+
z
|
237
|
+
}) {
|
238
|
+
ref.current().applyTorqueImpulse({
|
239
|
+
x,
|
240
|
+
y,
|
241
|
+
z
|
242
|
+
}, true);
|
243
|
+
},
|
244
|
+
|
245
|
+
translation() {
|
246
|
+
const {
|
247
|
+
x,
|
248
|
+
y,
|
249
|
+
z
|
250
|
+
} = ref.current().translation();
|
251
|
+
return new three.Vector3(x, y, z);
|
252
|
+
},
|
253
|
+
|
254
|
+
rotation() {
|
255
|
+
const {
|
256
|
+
x,
|
257
|
+
y,
|
258
|
+
z,
|
259
|
+
w
|
260
|
+
} = ref.current().rotation();
|
261
|
+
return new three.Quaternion(x, y, z, w);
|
262
|
+
}
|
263
|
+
|
264
|
+
};
|
265
|
+
}; // TODO: Flesh this out
|
266
|
+
|
267
|
+
const createColliderApi = ref => {
|
268
|
+
return {
|
269
|
+
raw: () => ref.current(),
|
270
|
+
|
271
|
+
get handle() {
|
272
|
+
return ref.current().handle;
|
273
|
+
}
|
274
|
+
|
275
|
+
};
|
276
|
+
};
|
277
|
+
const createWorldApi = ref => {
|
278
|
+
return {
|
279
|
+
raw: () => ref.current(),
|
280
|
+
getCollider: handle => ref.current().getCollider(handle),
|
281
|
+
getRigidBody: handle => ref.current().getRigidBody(handle),
|
282
|
+
createRigidBody: desc => ref.current().createRigidBody(desc),
|
283
|
+
createCollider: (desc, rigidBodyHandle) => ref.current().createCollider(desc, rigidBodyHandle),
|
284
|
+
removeRigidBody: rigidBody => ref.current().removeRigidBody(rigidBody),
|
285
|
+
removeCollider: collider => ref.current().removeCollider(collider, true),
|
286
|
+
createImpulseJoint: (params, rigidBodyA, rigidBodyB) => ref.current().createImpulseJoint(params, rigidBodyA, rigidBodyB),
|
287
|
+
removeImpulseJoint: joint => ref.current().removeImpulseJoint(joint, true),
|
288
|
+
forEachCollider: callback => ref.current().forEachCollider(callback)
|
289
|
+
};
|
290
|
+
}; // TODO: Broken currently, waiting for Rapier3D to fix
|
291
|
+
|
292
|
+
const createJointApi = ref => {
|
293
|
+
return {
|
294
|
+
raw: () => ref.current(),
|
295
|
+
|
296
|
+
get handle() {
|
297
|
+
return ref.current().handle;
|
298
|
+
},
|
299
|
+
|
300
|
+
configureMotorPosition: (targetPos, stiffness, damping) => ref.current().configureMotorPosition(targetPos, stiffness, damping),
|
301
|
+
configureMotorVelocity: (targetVel, damping) => ref.current().configureMotorVelocity(targetVel, damping)
|
302
|
+
};
|
303
|
+
};
|
304
|
+
|
199
305
|
const RapierContext = /*#__PURE__*/React.createContext(undefined);
|
200
306
|
|
201
307
|
const importRapier = async () => {
|
@@ -210,30 +316,143 @@ const Physics = ({
|
|
210
316
|
children
|
211
317
|
}) => {
|
212
318
|
const rapier = useAsset.useAsset(importRapier);
|
213
|
-
const
|
214
|
-
const
|
215
|
-
if (!
|
216
|
-
|
217
|
-
|
218
|
-
|
319
|
+
const worldRef = React.useRef();
|
320
|
+
const getWorldRef = React.useRef(() => {
|
321
|
+
if (!worldRef.current) {
|
322
|
+
const world = new rapier.World(vectorArrayToObject(_gravity));
|
323
|
+
worldRef.current = world;
|
324
|
+
}
|
325
|
+
|
326
|
+
return worldRef.current;
|
327
|
+
});
|
328
|
+
const [colliderMeshes] = React.useState(() => new Map());
|
329
|
+
const [rigidBodyMeshes] = React.useState(() => new Map());
|
330
|
+
const [rigidBodyEvents] = React.useState(() => new Map());
|
331
|
+
const [eventQueue] = React.useState(() => new rapier3dCompat.EventQueue(false)); // Init world
|
332
|
+
|
333
|
+
React.useLayoutEffect(() => {
|
334
|
+
const world = getWorldRef.current();
|
335
|
+
return () => {
|
336
|
+
if (world) {
|
337
|
+
world.free();
|
338
|
+
worldRef.current = undefined;
|
339
|
+
}
|
340
|
+
};
|
341
|
+
}, []);
|
219
342
|
const time = React.useRef(performance.now());
|
220
343
|
fiber.useFrame(context => {
|
221
|
-
|
344
|
+
const world = worldRef.current;
|
345
|
+
if (!world) return; // Set timestep to current delta, to allow for variable frame rates
|
222
346
|
// We cap the delta at 100, so that the physics simulation doesn't get wild
|
347
|
+
|
223
348
|
const now = performance.now();
|
224
349
|
const delta = Math.min(100, now - time.current);
|
225
350
|
world.timestep = delta / 1000;
|
226
|
-
world.step(); //
|
351
|
+
world.step(eventQueue); // Update meshes
|
352
|
+
|
353
|
+
rigidBodyMeshes.forEach((mesh, handle) => {
|
354
|
+
const rigidBody = world.getRigidBody(handle);
|
355
|
+
const events = rigidBodyEvents.get(handle);
|
356
|
+
|
357
|
+
if (events !== null && events !== void 0 && events.onSleep || events !== null && events !== void 0 && events.onWake) {
|
358
|
+
if (rigidBody.isSleeping() && !mesh.userData.isSleeping) {
|
359
|
+
var _events$onSleep;
|
360
|
+
|
361
|
+
events === null || events === void 0 ? void 0 : (_events$onSleep = events.onSleep) === null || _events$onSleep === void 0 ? void 0 : _events$onSleep.call(events);
|
362
|
+
}
|
363
|
+
|
364
|
+
if (!rigidBody.isSleeping() && mesh.userData.isSleeping) {
|
365
|
+
var _events$onWake;
|
366
|
+
|
367
|
+
events === null || events === void 0 ? void 0 : (_events$onWake = events.onWake) === null || _events$onWake === void 0 ? void 0 : _events$onWake.call(events);
|
368
|
+
}
|
369
|
+
|
370
|
+
mesh.userData.isSleeping = rigidBody.isSleeping();
|
371
|
+
}
|
372
|
+
|
373
|
+
if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !mesh.parent) {
|
374
|
+
return;
|
375
|
+
}
|
376
|
+
|
377
|
+
const {
|
378
|
+
x,
|
379
|
+
y,
|
380
|
+
z
|
381
|
+
} = rigidBody.translation();
|
382
|
+
const {
|
383
|
+
x: rx,
|
384
|
+
y: ry,
|
385
|
+
z: rz,
|
386
|
+
w: rw
|
387
|
+
} = rigidBody.rotation();
|
388
|
+
const scale = mesh.getWorldScale(new three.Vector3()); // haha matrixes I have no idea what I'm doing :)
|
389
|
+
|
390
|
+
const o = new three.Object3D();
|
391
|
+
o.position.set(x, y, z);
|
392
|
+
o.rotation.setFromQuaternion(new three.Quaternion(rx, ry, rz, rw));
|
393
|
+
o.scale.set(scale.x, scale.y, scale.z);
|
394
|
+
o.updateMatrix();
|
395
|
+
o.applyMatrix4(mesh.parent.matrixWorld.clone().invert());
|
396
|
+
o.updateMatrix();
|
397
|
+
mesh.position.setFromMatrixPosition(o.matrix);
|
398
|
+
mesh.rotation.setFromRotationMatrix(o.matrix);
|
399
|
+
}); // Collision events
|
400
|
+
|
401
|
+
eventQueue.drainCollisionEvents((handle1, handle2, started) => {
|
402
|
+
const collider1 = world.getCollider(handle1);
|
403
|
+
const collider2 = world.getCollider(handle2);
|
404
|
+
const rigidBodyHandle1 = collider1.parent();
|
405
|
+
const rigidBodyHandle2 = collider2.parent();
|
406
|
+
|
407
|
+
if (!collider1 || !collider2 || !rigidBodyHandle1 || !rigidBodyHandle2) {
|
408
|
+
return;
|
409
|
+
}
|
227
410
|
|
228
|
-
|
411
|
+
const rigidBody1 = world.getRigidBody(rigidBodyHandle1);
|
412
|
+
const rigidBody2 = world.getRigidBody(rigidBodyHandle2);
|
413
|
+
const events1 = rigidBodyEvents.get(rigidBodyHandle1);
|
414
|
+
const events2 = rigidBodyEvents.get(rigidBodyHandle2);
|
415
|
+
|
416
|
+
if (started) {
|
417
|
+
world.contactPair(handle1, handle2, (manifold, flipped) => {
|
418
|
+
var _events1$onCollisionE, _events2$onCollisionE;
|
419
|
+
|
420
|
+
events1 === null || events1 === void 0 ? void 0 : (_events1$onCollisionE = events1.onCollisionEnter) === null || _events1$onCollisionE === void 0 ? void 0 : _events1$onCollisionE.call(events1, {
|
421
|
+
target: rigidBody2,
|
422
|
+
manifold,
|
423
|
+
flipped
|
424
|
+
});
|
425
|
+
events2 === null || events2 === void 0 ? void 0 : (_events2$onCollisionE = events2.onCollisionEnter) === null || _events2$onCollisionE === void 0 ? void 0 : _events2$onCollisionE.call(events2, {
|
426
|
+
target: rigidBody1,
|
427
|
+
manifold,
|
428
|
+
flipped
|
429
|
+
});
|
430
|
+
});
|
431
|
+
} else {
|
432
|
+
var _events1$onCollisionE2, _events2$onCollisionE2;
|
433
|
+
|
434
|
+
events1 === null || events1 === void 0 ? void 0 : (_events1$onCollisionE2 = events1.onCollisionExit) === null || _events1$onCollisionE2 === void 0 ? void 0 : _events1$onCollisionE2.call(events1, {
|
435
|
+
target: rigidBody2
|
436
|
+
});
|
437
|
+
events2 === null || events2 === void 0 ? void 0 : (_events2$onCollisionE2 = events2.onCollisionExit) === null || _events2$onCollisionE2 === void 0 ? void 0 : _events2$onCollisionE2.call(events2, {
|
438
|
+
target: rigidBody1
|
439
|
+
});
|
440
|
+
}
|
441
|
+
});
|
229
442
|
time.current = now;
|
230
443
|
});
|
444
|
+
const api = React.useMemo(() => createWorldApi(getWorldRef), []);
|
231
445
|
const context = React.useMemo(() => ({
|
232
|
-
|
233
|
-
world,
|
234
|
-
|
235
|
-
|
236
|
-
|
446
|
+
rapier,
|
447
|
+
world: api,
|
448
|
+
physicsOptions: {
|
449
|
+
colliders: _colliders,
|
450
|
+
gravity: _gravity
|
451
|
+
},
|
452
|
+
colliderMeshes,
|
453
|
+
rigidBodyMeshes,
|
454
|
+
rigidBodyEvents
|
455
|
+
}), []);
|
237
456
|
return /*#__PURE__*/React__default["default"].createElement(RapierContext.Provider, {
|
238
457
|
value: context
|
239
458
|
}, children);
|
@@ -282,70 +501,53 @@ function _objectSpread2(target) {
|
|
282
501
|
|
283
502
|
const useRapier = () => {
|
284
503
|
return React.useContext(RapierContext);
|
285
|
-
}; // Private hook for updating the simulations on objects
|
286
|
-
|
287
|
-
const useRapierStep = callback => {
|
288
|
-
const {
|
289
|
-
stepFuncs
|
290
|
-
} = useRapier();
|
291
|
-
React.useEffect(() => {
|
292
|
-
stepFuncs.push(callback);
|
293
|
-
return () => {
|
294
|
-
const index = stepFuncs.indexOf(callback);
|
295
|
-
stepFuncs.splice(index, 1);
|
296
|
-
};
|
297
|
-
}, [callback]);
|
298
504
|
};
|
299
|
-
const
|
505
|
+
const useRigidBody = (options = {}) => {
|
300
506
|
const {
|
301
|
-
|
302
|
-
world
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
}, []);
|
307
|
-
React.useEffect(() => {
|
308
|
-
return () => {
|
309
|
-
world.removeCollider(collider, false);
|
310
|
-
};
|
311
|
-
}, []);
|
312
|
-
return [collider];
|
313
|
-
};
|
314
|
-
const useRigidBody = options => {
|
315
|
-
const {
|
316
|
-
RAPIER,
|
317
|
-
world
|
507
|
+
rapier,
|
508
|
+
world,
|
509
|
+
rigidBodyMeshes,
|
510
|
+
physicsOptions,
|
511
|
+
rigidBodyEvents
|
318
512
|
} = useRapier();
|
319
513
|
const ref = React.useRef(); // Create rigidbody
|
320
514
|
|
321
|
-
const
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
515
|
+
const rigidBodyRef = React.useRef();
|
516
|
+
const getRigidBodyRef = React.useRef(() => {
|
517
|
+
if (!rigidBodyRef.current) {
|
518
|
+
var _options$linearVeloci, _options$angularVeloc, _options$gravityScale, _options$canSleep, _options$ccd;
|
519
|
+
|
520
|
+
const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
|
521
|
+
const [lvx, lvy, lvz] = (_options$linearVeloci = options === null || options === void 0 ? void 0 : options.linearVelocity) !== null && _options$linearVeloci !== void 0 ? _options$linearVeloci : [0, 0, 0];
|
522
|
+
const [avx, avy, avz] = (_options$angularVeloc = options === null || options === void 0 ? void 0 : options.angularVelocity) !== null && _options$angularVeloc !== void 0 ? _options$angularVeloc : [0, 0, 0];
|
523
|
+
const gravityScale = (_options$gravityScale = options === null || options === void 0 ? void 0 : options.gravityScale) !== null && _options$gravityScale !== void 0 ? _options$gravityScale : 1;
|
524
|
+
const canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
|
525
|
+
const ccdEnabled = (_options$ccd = options === null || options === void 0 ? void 0 : options.ccd) !== null && _options$ccd !== void 0 ? _options$ccd : false;
|
526
|
+
const desc = new rapier.RigidBodyDesc(type).setLinvel(lvx, lvy, lvz).setAngvel({
|
527
|
+
x: avx,
|
528
|
+
y: avy,
|
529
|
+
z: avz
|
530
|
+
}).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled);
|
531
|
+
const rigidBody = world.createRigidBody(desc);
|
532
|
+
rigidBodyRef.current = rigidBody;
|
533
|
+
}
|
534
|
+
|
535
|
+
return rigidBodyRef.current;
|
536
|
+
}); // Setup
|
340
537
|
|
341
538
|
React.useEffect(() => {
|
342
|
-
var _ref$current$parent, _options$colliders;
|
539
|
+
var _ref$current$parent, _ref, _options$colliders;
|
540
|
+
|
541
|
+
const rigidBody = getRigidBodyRef.current();
|
542
|
+
rigidBodyRef.current = rigidBody;
|
343
543
|
|
344
544
|
if (!ref.current) {
|
345
545
|
ref.current = new three.Object3D();
|
346
|
-
} //
|
546
|
+
} // isSleeping used for onSleep and onWake events
|
347
547
|
|
348
548
|
|
549
|
+
ref.current.userData.isSleeping = false; // Get intitial world transforms
|
550
|
+
|
349
551
|
const worldPosition = ref.current.getWorldPosition(new three.Vector3());
|
350
552
|
const worldRotation = ref.current.getWorldQuaternion(new three.Quaternion());
|
351
553
|
const scale = ((_ref$current$parent = ref.current.parent) === null || _ref$current$parent === void 0 ? void 0 : _ref$current$parent.getWorldScale(new three.Vector3())) || {
|
@@ -372,43 +574,56 @@ const useRigidBody = options => {
|
|
372
574
|
}, false);
|
373
575
|
rigidBody.resetForces(false);
|
374
576
|
rigidBody.resetTorques(false);
|
375
|
-
const colliderSetting = (_options$colliders = options === null || options === void 0 ? void 0 : options.colliders) !== null && _options$colliders !== void 0 ? _options$colliders : false;
|
376
|
-
const
|
577
|
+
const colliderSetting = (_ref = (_options$colliders = options === null || options === void 0 ? void 0 : options.colliders) !== null && _options$colliders !== void 0 ? _options$colliders : physicsOptions.colliders) !== null && _ref !== void 0 ? _ref : false;
|
578
|
+
const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
|
579
|
+
const autoColliders = colliderSetting !== false ? createCollidersFromChildren(ref.current, rigidBody, colliderSetting, world, hasCollisionEvents) : [];
|
580
|
+
rigidBody.wakeUp();
|
581
|
+
rigidBodyMeshes.set(rigidBody.handle, ref.current);
|
377
582
|
return () => {
|
583
|
+
autoColliders.forEach(collider => world.removeCollider(collider));
|
378
584
|
world.removeRigidBody(rigidBody);
|
379
|
-
|
585
|
+
rigidBodyRef.current = undefined;
|
586
|
+
rigidBodyMeshes.delete(rigidBody.handle);
|
380
587
|
};
|
381
|
-
}, []);
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
ref.current.rotation.setFromRotationMatrix(o.matrix);
|
408
|
-
}
|
588
|
+
}, []); // Events
|
589
|
+
|
590
|
+
React.useEffect(() => {
|
591
|
+
const rigidBody = getRigidBodyRef.current();
|
592
|
+
rigidBodyEvents.set(rigidBody.handle, {
|
593
|
+
onCollisionEnter: options === null || options === void 0 ? void 0 : options.onCollisionEnter,
|
594
|
+
onCollisionExit: options === null || options === void 0 ? void 0 : options.onCollisionExit,
|
595
|
+
onSleep: options === null || options === void 0 ? void 0 : options.onSleep,
|
596
|
+
onWake: options === null || options === void 0 ? void 0 : options.onWake
|
597
|
+
});
|
598
|
+
return () => {
|
599
|
+
rigidBodyEvents.delete(rigidBody.handle);
|
600
|
+
};
|
601
|
+
}, [options.onCollisionEnter, options.onCollisionExit]);
|
602
|
+
const api = React.useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
|
603
|
+
return [ref, api];
|
604
|
+
};
|
605
|
+
const useCollider = (body, options = {}) => {
|
606
|
+
const {
|
607
|
+
world
|
608
|
+
} = useRapier();
|
609
|
+
const colliderRef = React.useRef();
|
610
|
+
const objectRef = React.useRef();
|
611
|
+
const getColliderRef = React.useRef(() => {
|
612
|
+
if (!colliderRef.current) {
|
613
|
+
colliderRef.current = createColliderFromOptions(options, world, body.handle);
|
409
614
|
}
|
615
|
+
|
616
|
+
return colliderRef.current;
|
410
617
|
});
|
411
|
-
|
618
|
+
React.useEffect(() => {
|
619
|
+
const collider = getColliderRef.current();
|
620
|
+
return () => {
|
621
|
+
if (collider) world.removeCollider(collider);
|
622
|
+
colliderRef.current = undefined;
|
623
|
+
};
|
624
|
+
}, []);
|
625
|
+
const api = React.useMemo(() => createColliderApi(getColliderRef), []);
|
626
|
+
return [objectRef, api];
|
412
627
|
};
|
413
628
|
const useRigidBodyWithCollider = (rigidBodyOptions, colliderOptions) => {
|
414
629
|
const {
|
@@ -421,9 +636,9 @@ const useRigidBodyWithCollider = (rigidBodyOptions, colliderOptions) => {
|
|
421
636
|
}
|
422
637
|
|
423
638
|
const scale = ref.current.getWorldScale(new three.Vector3());
|
424
|
-
const collider = createColliderFromOptions(colliderOptions, world, rigidBody, scale);
|
639
|
+
const collider = createColliderFromOptions(colliderOptions, world, rigidBody.handle, scale);
|
425
640
|
return () => {
|
426
|
-
world.removeCollider(collider
|
641
|
+
world.removeCollider(collider);
|
427
642
|
};
|
428
643
|
}, []);
|
429
644
|
return [ref, rigidBody];
|
@@ -549,20 +764,42 @@ const useRoundConvexMesh = (rigidBodyOptions = {}, colliderOptions = {}) => {
|
|
549
764
|
|
550
765
|
const useImpulseJoint = (body1, body2, params) => {
|
551
766
|
const {
|
552
|
-
world
|
553
|
-
RAPIER
|
767
|
+
world
|
554
768
|
} = useRapier();
|
555
|
-
React.
|
556
|
-
|
769
|
+
const jointRef = React.useRef();
|
770
|
+
const getJointRef = React.useRef(() => {
|
771
|
+
if (!jointRef.current) {
|
772
|
+
let rb1;
|
773
|
+
let rb2;
|
774
|
+
|
775
|
+
if ('handle' in body1 && 'handle' in body2) {
|
776
|
+
rb1 = world.getRigidBody(body1.handle);
|
777
|
+
rb2 = world.getRigidBody(body2.handle);
|
778
|
+
jointRef.current = world.createImpulseJoint(params, rb1, rb2);
|
779
|
+
}
|
557
780
|
|
558
|
-
|
559
|
-
|
781
|
+
if ('current' in body1 && body1.current && 'current' in body2 && body2.current) {
|
782
|
+
rb1 = world.getRigidBody(body1.current.handle);
|
783
|
+
rb2 = world.getRigidBody(body2.current.handle);
|
784
|
+
const newJoint = world.createImpulseJoint(params, rb1, rb2);
|
785
|
+
jointRef.current = newJoint;
|
786
|
+
}
|
560
787
|
}
|
561
788
|
|
789
|
+
return jointRef.current;
|
790
|
+
});
|
791
|
+
React.useEffect(() => {
|
792
|
+
const joint = getJointRef.current();
|
562
793
|
return () => {
|
563
|
-
if (joint)
|
794
|
+
if (joint) {
|
795
|
+
console.log('remove joint', joint);
|
796
|
+
world.removeImpulseJoint(joint);
|
797
|
+
jointRef.current = undefined;
|
798
|
+
}
|
564
799
|
};
|
565
|
-
}, [
|
800
|
+
}, []);
|
801
|
+
const api = React.useMemo(() => createJointApi(getJointRef), []);
|
802
|
+
return api;
|
566
803
|
};
|
567
804
|
/**
|
568
805
|
*
|
@@ -573,9 +810,9 @@ const useImpulseJoint = (body1, body2, params) => {
|
|
573
810
|
|
574
811
|
const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor, body2LocalFrame]) => {
|
575
812
|
const {
|
576
|
-
|
813
|
+
rapier
|
577
814
|
} = useRapier();
|
578
|
-
return useImpulseJoint(body1, body2,
|
815
|
+
return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToObject(body1Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToObject(body1LocalFrame)), {}, {
|
579
816
|
w: 1
|
580
817
|
}), vectorArrayToObject(body2Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToObject(body2LocalFrame)), {}, {
|
581
818
|
w: 1
|
@@ -590,9 +827,9 @@ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor,
|
|
590
827
|
|
591
828
|
const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
592
829
|
const {
|
593
|
-
|
830
|
+
rapier
|
594
831
|
} = useRapier();
|
595
|
-
return useImpulseJoint(body1, body2,
|
832
|
+
return useImpulseJoint(body1, body2, rapier.JointData.spherical(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor)));
|
596
833
|
};
|
597
834
|
/**
|
598
835
|
* The revolute joint prevents any relative movement between two rigid-bodies, except for relative
|
@@ -602,9 +839,9 @@ const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
|
602
839
|
|
603
840
|
const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
604
841
|
const {
|
605
|
-
|
842
|
+
rapier
|
606
843
|
} = useRapier();
|
607
|
-
return useImpulseJoint(body1, body2,
|
844
|
+
return useImpulseJoint(body1, body2, rapier.JointData.revolute(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor), vectorArrayToObject(axis)));
|
608
845
|
};
|
609
846
|
/**
|
610
847
|
* The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
|
@@ -614,9 +851,9 @@ const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
|
614
851
|
|
615
852
|
const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
616
853
|
const {
|
617
|
-
|
854
|
+
rapier
|
618
855
|
} = useRapier();
|
619
|
-
return useImpulseJoint(body1, body2,
|
856
|
+
return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor), vectorArrayToObject(axis)));
|
620
857
|
};
|
621
858
|
|
622
859
|
function _extends() {
|
@@ -671,10 +908,11 @@ function _objectWithoutProperties(source, excluded) {
|
|
671
908
|
return target;
|
672
909
|
}
|
673
910
|
|
674
|
-
const _excluded = ["children"]
|
911
|
+
const _excluded = ["children"],
|
912
|
+
_excluded2 = ["children"];
|
675
913
|
const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
|
676
914
|
|
677
|
-
const
|
915
|
+
const useRigidBodyContext = () => React.useContext(RigidBodyContext); // RigidBody
|
678
916
|
|
679
917
|
|
680
918
|
const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
@@ -683,28 +921,36 @@ const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
683
921
|
} = _ref,
|
684
922
|
props = _objectWithoutProperties(_ref, _excluded);
|
685
923
|
|
686
|
-
const [
|
924
|
+
const [object, rigidBody] = useRigidBody(props);
|
687
925
|
React.useImperativeHandle(ref, () => rigidBody);
|
688
926
|
return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
|
689
|
-
value: [
|
690
|
-
}, /*#__PURE__*/React__default["default"].createElement("
|
691
|
-
ref:
|
927
|
+
value: [object, rigidBody, !!(props.onCollisionEnter || props.onCollisionExit)]
|
928
|
+
}, /*#__PURE__*/React__default["default"].createElement("object3D", {
|
929
|
+
ref: object
|
692
930
|
}, children));
|
693
931
|
}); // Colliders
|
694
932
|
|
695
|
-
const AnyCollider =
|
933
|
+
const AnyCollider = _ref2 => {
|
934
|
+
let {
|
935
|
+
children
|
936
|
+
} = _ref2,
|
937
|
+
props = _objectWithoutProperties(_ref2, _excluded2);
|
938
|
+
|
696
939
|
const {
|
697
940
|
world
|
698
941
|
} = useRapier();
|
699
|
-
const [
|
942
|
+
const [, rigidBody, hasCollisionEvents] = useRigidBodyContext();
|
943
|
+
const ref = React.useRef(null);
|
700
944
|
React.useEffect(() => {
|
701
|
-
const scale =
|
702
|
-
const collider = createColliderFromOptions(props, world, rigidBody, scale);
|
945
|
+
const scale = ref.current.getWorldScale(new three.Vector3());
|
946
|
+
const collider = createColliderFromOptions(props, world, rigidBody.handle, scale, hasCollisionEvents);
|
703
947
|
return () => {
|
704
|
-
world.removeCollider(collider
|
948
|
+
world.removeCollider(collider);
|
705
949
|
};
|
706
950
|
}, []);
|
707
|
-
return
|
951
|
+
return /*#__PURE__*/React__default["default"].createElement("object3D", {
|
952
|
+
ref: ref
|
953
|
+
}, children);
|
708
954
|
};
|
709
955
|
|
710
956
|
const CuboidCollider = props => {
|
@@ -853,7 +1099,7 @@ const Debug = () => {
|
|
853
1099
|
|
854
1100
|
fiber.useFrame(() => {
|
855
1101
|
const newColliders = [];
|
856
|
-
world.
|
1102
|
+
world.forEachCollider(collider => {
|
857
1103
|
newColliders.push(collider.handle);
|
858
1104
|
});
|
859
1105
|
setColliders(newColliders);
|