@react-three/rapier 0.1.2 → 0.3.1
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 -5
- 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 +379 -134
- package/dist/react-three-rapier.cjs.prod.js +379 -134
- package/dist/react-three-rapier.esm.js +382 -137
- package/package.json +2 -2
@@ -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;
|
227
366
|
|
228
|
-
|
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
|
+
}
|
410
|
+
|
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,52 @@ 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
|
-
} = useRapier();
|
304
|
-
const collider = React.useMemo(() => {
|
305
|
-
return createColliderFromOptions(options, world, body);
|
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,
|
507
|
+
rapier,
|
317
508
|
world,
|
318
|
-
|
509
|
+
rigidBodyMeshes,
|
510
|
+
physicsOptions,
|
511
|
+
rigidBodyEvents
|
319
512
|
} = useRapier();
|
320
513
|
const ref = React.useRef(); // Create rigidbody
|
321
514
|
|
322
|
-
const
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
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
|
341
537
|
|
342
538
|
React.useEffect(() => {
|
343
539
|
var _ref$current$parent, _ref, _options$colliders;
|
344
540
|
|
541
|
+
const rigidBody = getRigidBodyRef.current();
|
542
|
+
rigidBodyRef.current = rigidBody;
|
543
|
+
|
345
544
|
if (!ref.current) {
|
346
545
|
ref.current = new three.Object3D();
|
347
|
-
} //
|
546
|
+
} // isSleeping used for onSleep and onWake events
|
547
|
+
|
348
548
|
|
549
|
+
ref.current.userData.isSleeping = false; // Get intitial world transforms
|
349
550
|
|
350
551
|
const worldPosition = ref.current.getWorldPosition(new three.Vector3());
|
351
552
|
const worldRotation = ref.current.getWorldQuaternion(new three.Quaternion());
|
@@ -373,43 +574,56 @@ const useRigidBody = options => {
|
|
373
574
|
}, false);
|
374
575
|
rigidBody.resetForces(false);
|
375
576
|
rigidBody.resetTorques(false);
|
376
|
-
const colliderSetting = (_ref = (_options$colliders = options === null || options === void 0 ? void 0 : options.colliders) !== null && _options$colliders !== void 0 ? _options$colliders : colliders) !== null && _ref !== void 0 ? _ref : false;
|
377
|
-
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);
|
378
582
|
return () => {
|
583
|
+
autoColliders.forEach(collider => world.removeCollider(collider));
|
379
584
|
world.removeRigidBody(rigidBody);
|
380
|
-
|
585
|
+
rigidBodyRef.current = undefined;
|
586
|
+
rigidBodyMeshes.delete(rigidBody.handle);
|
381
587
|
};
|
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
|
-
|
408
|
-
ref.current.rotation.setFromRotationMatrix(o.matrix);
|
409
|
-
}
|
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);
|
410
614
|
}
|
615
|
+
|
616
|
+
return colliderRef.current;
|
411
617
|
});
|
412
|
-
|
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];
|
413
627
|
};
|
414
628
|
const useRigidBodyWithCollider = (rigidBodyOptions, colliderOptions) => {
|
415
629
|
const {
|
@@ -422,9 +636,9 @@ const useRigidBodyWithCollider = (rigidBodyOptions, colliderOptions) => {
|
|
422
636
|
}
|
423
637
|
|
424
638
|
const scale = ref.current.getWorldScale(new three.Vector3());
|
425
|
-
const collider = createColliderFromOptions(colliderOptions, world, rigidBody, scale);
|
639
|
+
const collider = createColliderFromOptions(colliderOptions, world, rigidBody.handle, scale);
|
426
640
|
return () => {
|
427
|
-
world.removeCollider(collider
|
641
|
+
world.removeCollider(collider);
|
428
642
|
};
|
429
643
|
}, []);
|
430
644
|
return [ref, rigidBody];
|
@@ -550,20 +764,42 @@ const useRoundConvexMesh = (rigidBodyOptions = {}, colliderOptions = {}) => {
|
|
550
764
|
|
551
765
|
const useImpulseJoint = (body1, body2, params) => {
|
552
766
|
const {
|
553
|
-
world
|
554
|
-
RAPIER
|
767
|
+
world
|
555
768
|
} = useRapier();
|
556
|
-
React.
|
557
|
-
|
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
|
+
}
|
558
780
|
|
559
|
-
|
560
|
-
|
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
|
+
}
|
561
787
|
}
|
562
788
|
|
789
|
+
return jointRef.current;
|
790
|
+
});
|
791
|
+
React.useEffect(() => {
|
792
|
+
const joint = getJointRef.current();
|
563
793
|
return () => {
|
564
|
-
if (joint)
|
794
|
+
if (joint) {
|
795
|
+
console.log('remove joint', joint);
|
796
|
+
world.removeImpulseJoint(joint);
|
797
|
+
jointRef.current = undefined;
|
798
|
+
}
|
565
799
|
};
|
566
|
-
}, [
|
800
|
+
}, []);
|
801
|
+
const api = React.useMemo(() => createJointApi(getJointRef), []);
|
802
|
+
return api;
|
567
803
|
};
|
568
804
|
/**
|
569
805
|
*
|
@@ -574,9 +810,9 @@ const useImpulseJoint = (body1, body2, params) => {
|
|
574
810
|
|
575
811
|
const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor, body2LocalFrame]) => {
|
576
812
|
const {
|
577
|
-
|
813
|
+
rapier
|
578
814
|
} = useRapier();
|
579
|
-
return useImpulseJoint(body1, body2,
|
815
|
+
return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToObject(body1Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToObject(body1LocalFrame)), {}, {
|
580
816
|
w: 1
|
581
817
|
}), vectorArrayToObject(body2Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToObject(body2LocalFrame)), {}, {
|
582
818
|
w: 1
|
@@ -591,9 +827,9 @@ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor,
|
|
591
827
|
|
592
828
|
const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
593
829
|
const {
|
594
|
-
|
830
|
+
rapier
|
595
831
|
} = useRapier();
|
596
|
-
return useImpulseJoint(body1, body2,
|
832
|
+
return useImpulseJoint(body1, body2, rapier.JointData.spherical(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor)));
|
597
833
|
};
|
598
834
|
/**
|
599
835
|
* The revolute joint prevents any relative movement between two rigid-bodies, except for relative
|
@@ -603,9 +839,9 @@ const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
|
603
839
|
|
604
840
|
const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
605
841
|
const {
|
606
|
-
|
842
|
+
rapier
|
607
843
|
} = useRapier();
|
608
|
-
return useImpulseJoint(body1, body2,
|
844
|
+
return useImpulseJoint(body1, body2, rapier.JointData.revolute(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor), vectorArrayToObject(axis)));
|
609
845
|
};
|
610
846
|
/**
|
611
847
|
* The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
|
@@ -615,9 +851,9 @@ const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
|
615
851
|
|
616
852
|
const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
617
853
|
const {
|
618
|
-
|
854
|
+
rapier
|
619
855
|
} = useRapier();
|
620
|
-
return useImpulseJoint(body1, body2,
|
856
|
+
return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor), vectorArrayToObject(axis)));
|
621
857
|
};
|
622
858
|
|
623
859
|
function _extends() {
|
@@ -672,10 +908,11 @@ function _objectWithoutProperties(source, excluded) {
|
|
672
908
|
return target;
|
673
909
|
}
|
674
910
|
|
675
|
-
const _excluded = ["children"]
|
911
|
+
const _excluded = ["children"],
|
912
|
+
_excluded2 = ["children"];
|
676
913
|
const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
|
677
914
|
|
678
|
-
const
|
915
|
+
const useRigidBodyContext = () => React.useContext(RigidBodyContext); // RigidBody
|
679
916
|
|
680
917
|
|
681
918
|
const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
@@ -684,28 +921,36 @@ const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
684
921
|
} = _ref,
|
685
922
|
props = _objectWithoutProperties(_ref, _excluded);
|
686
923
|
|
687
|
-
const [
|
924
|
+
const [object, rigidBody] = useRigidBody(props);
|
688
925
|
React.useImperativeHandle(ref, () => rigidBody);
|
689
926
|
return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
|
690
|
-
value: [
|
691
|
-
}, /*#__PURE__*/React__default["default"].createElement("
|
692
|
-
ref:
|
927
|
+
value: [object, rigidBody, !!(props.onCollisionEnter || props.onCollisionExit)]
|
928
|
+
}, /*#__PURE__*/React__default["default"].createElement("object3D", {
|
929
|
+
ref: object
|
693
930
|
}, children));
|
694
931
|
}); // Colliders
|
695
932
|
|
696
|
-
const AnyCollider =
|
933
|
+
const AnyCollider = _ref2 => {
|
934
|
+
let {
|
935
|
+
children
|
936
|
+
} = _ref2,
|
937
|
+
props = _objectWithoutProperties(_ref2, _excluded2);
|
938
|
+
|
697
939
|
const {
|
698
940
|
world
|
699
941
|
} = useRapier();
|
700
|
-
const [
|
942
|
+
const [, rigidBody, hasCollisionEvents] = useRigidBodyContext();
|
943
|
+
const ref = React.useRef(null);
|
701
944
|
React.useEffect(() => {
|
702
|
-
const scale =
|
703
|
-
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);
|
704
947
|
return () => {
|
705
|
-
world.removeCollider(collider
|
948
|
+
world.removeCollider(collider);
|
706
949
|
};
|
707
950
|
}, []);
|
708
|
-
return
|
951
|
+
return /*#__PURE__*/React__default["default"].createElement("object3D", {
|
952
|
+
ref: ref
|
953
|
+
}, children);
|
709
954
|
};
|
710
955
|
|
711
956
|
const CuboidCollider = props => {
|
@@ -854,7 +1099,7 @@ const Debug = () => {
|
|
854
1099
|
|
855
1100
|
fiber.useFrame(() => {
|
856
1101
|
const newColliders = [];
|
857
|
-
world.
|
1102
|
+
world.forEachCollider(collider => {
|
858
1103
|
newColliders.push(collider.handle);
|
859
1104
|
});
|
860
1105
|
setColliders(newColliders);
|