@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
@@ -1,9 +1,9 @@
|
|
1
|
-
import React, { useRef, useMemo, createContext, useContext, useEffect,
|
1
|
+
import React, { useRef, useState, useLayoutEffect, useMemo, createContext, useContext, useEffect, forwardRef, useImperativeHandle, memo } from 'react';
|
2
2
|
import { useAsset } from 'use-asset';
|
3
3
|
import { useFrame } from '@react-three/fiber';
|
4
|
-
import { ColliderDesc, CoefficientCombineRule, ShapeType } from '@dimforge/rapier3d-compat';
|
4
|
+
import { ColliderDesc, CoefficientCombineRule, ActiveEvents, EventQueue, ShapeType } from '@dimforge/rapier3d-compat';
|
5
5
|
export { CoefficientCombineRule, Collider as RapierCollider, RigidBody as RapierRigidBody } from '@dimforge/rapier3d-compat';
|
6
|
-
import {
|
6
|
+
import { Vector3, Quaternion, Object3D, Euler, CylinderBufferGeometry, BufferGeometry, BufferAttribute, SphereBufferGeometry, BoxBufferGeometry } from 'three';
|
7
7
|
|
8
8
|
const vectorArrayToObject = arr => {
|
9
9
|
const [x, y, z] = arr;
|
@@ -38,11 +38,11 @@ const scaleColliderArgs = (shape, args, scale) => {
|
|
38
38
|
const scaleArray = [scale.x, scale.y, scale.z];
|
39
39
|
return newArgs.map((arg, index) => scaleArray[index] * arg);
|
40
40
|
};
|
41
|
-
const createColliderFromOptions = (options, world,
|
41
|
+
const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
|
42
42
|
x: 1,
|
43
43
|
y: 1,
|
44
44
|
z: 1
|
45
|
-
}) => {
|
45
|
+
}, hasCollisionEvents = false) => {
|
46
46
|
var _options$shape, _options$args, _options$restitution, _options$restitutionC, _options$friction, _options$frictionComb;
|
47
47
|
|
48
48
|
const mass = (options === null || options === void 0 ? void 0 : options.mass) || 1;
|
@@ -60,7 +60,12 @@ const createColliderFromOptions = (options, world, body, scale = {
|
|
60
60
|
y: ry,
|
61
61
|
z: rz,
|
62
62
|
w: 1
|
63
|
-
}).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 : 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 : CoefficientCombineRule.Average);
|
63
|
+
}).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 : 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 : CoefficientCombineRule.Average);
|
64
|
+
|
65
|
+
if (hasCollisionEvents) {
|
66
|
+
colliderDesc = colliderDesc.setActiveEvents(ActiveEvents.COLLISION_EVENTS);
|
67
|
+
} // If any of the mass properties are specified, add mass properties
|
68
|
+
|
64
69
|
|
65
70
|
if (options !== null && options !== void 0 && options.mass || options !== null && options !== void 0 && options.centerOfMass || options !== null && options !== void 0 && options.principalAngularInertia) {
|
66
71
|
colliderDesc.setDensity(0);
|
@@ -80,12 +85,13 @@ const createColliderFromOptions = (options, world, body, scale = {
|
|
80
85
|
});
|
81
86
|
}
|
82
87
|
|
83
|
-
const collider = world.createCollider(colliderDesc,
|
88
|
+
const collider = world.createCollider(colliderDesc, rigidBodyHandle);
|
84
89
|
return collider;
|
85
90
|
};
|
86
|
-
const createCollidersFromChildren = (object, rigidBody, type, world) => {
|
91
|
+
const createCollidersFromChildren = (object, rigidBody, type, world, hasCollisionEvents = false) => {
|
87
92
|
const colliders = [];
|
88
93
|
let desc;
|
94
|
+
let offset = new Vector3();
|
89
95
|
object.traverse(child => {
|
90
96
|
if ("isMesh" in child) {
|
91
97
|
const {
|
@@ -112,6 +118,7 @@ const createCollidersFromChildren = (object, rigidBody, type, world) => {
|
|
112
118
|
boundingBox
|
113
119
|
} = geometry;
|
114
120
|
const size = boundingBox.getSize(new Vector3());
|
121
|
+
boundingBox.getCenter(offset);
|
115
122
|
desc = ColliderDesc.cuboid(size.x / 2 * scale.x, size.y / 2 * scale.y, size.z / 2 * scale.z);
|
116
123
|
}
|
117
124
|
break;
|
@@ -123,6 +130,7 @@ const createCollidersFromChildren = (object, rigidBody, type, world) => {
|
|
123
130
|
boundingSphere
|
124
131
|
} = geometry;
|
125
132
|
const radius = boundingSphere.radius * scale.x;
|
133
|
+
offset.copy(boundingSphere.center);
|
126
134
|
desc = ColliderDesc.ball(radius);
|
127
135
|
}
|
128
136
|
break;
|
@@ -147,12 +155,17 @@ const createCollidersFromChildren = (object, rigidBody, type, world) => {
|
|
147
155
|
|
148
156
|
|
149
157
|
const parentWorldScale = child.parent.getWorldScale(new Vector3());
|
150
|
-
desc.setTranslation(x * parentWorldScale.x, y * parentWorldScale.y, z * parentWorldScale.z).setRotation({
|
158
|
+
desc.setTranslation((x + offset.x) * parentWorldScale.x, (y + offset.y) * parentWorldScale.y, (z + offset.z) * parentWorldScale.z).setRotation({
|
151
159
|
x: rx,
|
152
160
|
y: ry,
|
153
161
|
z: rz,
|
154
162
|
w: rw
|
155
163
|
});
|
164
|
+
|
165
|
+
if (hasCollisionEvents) {
|
166
|
+
desc.setActiveEvents(ActiveEvents.COLLISION_EVENTS);
|
167
|
+
}
|
168
|
+
|
156
169
|
const collider = world.createCollider(desc, rigidBody.handle);
|
157
170
|
colliders.push(collider);
|
158
171
|
}
|
@@ -171,6 +184,99 @@ const scaleVertices = (vertices, scale) => {
|
|
171
184
|
return scaledVerts;
|
172
185
|
};
|
173
186
|
|
187
|
+
// TODO: Flesh this out
|
188
|
+
const createRigidBodyApi = ref => {
|
189
|
+
return {
|
190
|
+
raw: () => ref.current(),
|
191
|
+
|
192
|
+
get handle() {
|
193
|
+
return ref.current().handle;
|
194
|
+
},
|
195
|
+
|
196
|
+
applyImpulse({
|
197
|
+
x,
|
198
|
+
y,
|
199
|
+
z
|
200
|
+
}) {
|
201
|
+
ref.current().applyImpulse({
|
202
|
+
x,
|
203
|
+
y,
|
204
|
+
z
|
205
|
+
}, true);
|
206
|
+
},
|
207
|
+
|
208
|
+
applyTorqueImpulse({
|
209
|
+
x,
|
210
|
+
y,
|
211
|
+
z
|
212
|
+
}) {
|
213
|
+
ref.current().applyTorqueImpulse({
|
214
|
+
x,
|
215
|
+
y,
|
216
|
+
z
|
217
|
+
}, true);
|
218
|
+
},
|
219
|
+
|
220
|
+
translation() {
|
221
|
+
const {
|
222
|
+
x,
|
223
|
+
y,
|
224
|
+
z
|
225
|
+
} = ref.current().translation();
|
226
|
+
return new Vector3(x, y, z);
|
227
|
+
},
|
228
|
+
|
229
|
+
rotation() {
|
230
|
+
const {
|
231
|
+
x,
|
232
|
+
y,
|
233
|
+
z,
|
234
|
+
w
|
235
|
+
} = ref.current().rotation();
|
236
|
+
return new Quaternion(x, y, z, w);
|
237
|
+
}
|
238
|
+
|
239
|
+
};
|
240
|
+
}; // TODO: Flesh this out
|
241
|
+
|
242
|
+
const createColliderApi = ref => {
|
243
|
+
return {
|
244
|
+
raw: () => ref.current(),
|
245
|
+
|
246
|
+
get handle() {
|
247
|
+
return ref.current().handle;
|
248
|
+
}
|
249
|
+
|
250
|
+
};
|
251
|
+
};
|
252
|
+
const createWorldApi = ref => {
|
253
|
+
return {
|
254
|
+
raw: () => ref.current(),
|
255
|
+
getCollider: handle => ref.current().getCollider(handle),
|
256
|
+
getRigidBody: handle => ref.current().getRigidBody(handle),
|
257
|
+
createRigidBody: desc => ref.current().createRigidBody(desc),
|
258
|
+
createCollider: (desc, rigidBodyHandle) => ref.current().createCollider(desc, rigidBodyHandle),
|
259
|
+
removeRigidBody: rigidBody => ref.current().removeRigidBody(rigidBody),
|
260
|
+
removeCollider: collider => ref.current().removeCollider(collider, true),
|
261
|
+
createImpulseJoint: (params, rigidBodyA, rigidBodyB) => ref.current().createImpulseJoint(params, rigidBodyA, rigidBodyB),
|
262
|
+
removeImpulseJoint: joint => ref.current().removeImpulseJoint(joint, true),
|
263
|
+
forEachCollider: callback => ref.current().forEachCollider(callback)
|
264
|
+
};
|
265
|
+
}; // TODO: Broken currently, waiting for Rapier3D to fix
|
266
|
+
|
267
|
+
const createJointApi = ref => {
|
268
|
+
return {
|
269
|
+
raw: () => ref.current(),
|
270
|
+
|
271
|
+
get handle() {
|
272
|
+
return ref.current().handle;
|
273
|
+
},
|
274
|
+
|
275
|
+
configureMotorPosition: (targetPos, stiffness, damping) => ref.current().configureMotorPosition(targetPos, stiffness, damping),
|
276
|
+
configureMotorVelocity: (targetVel, damping) => ref.current().configureMotorVelocity(targetVel, damping)
|
277
|
+
};
|
278
|
+
};
|
279
|
+
|
174
280
|
const RapierContext = /*#__PURE__*/createContext(undefined);
|
175
281
|
|
176
282
|
const importRapier = async () => {
|
@@ -185,30 +291,143 @@ const Physics = ({
|
|
185
291
|
children
|
186
292
|
}) => {
|
187
293
|
const rapier = useAsset(importRapier);
|
188
|
-
const
|
189
|
-
const
|
190
|
-
if (!
|
191
|
-
|
192
|
-
|
193
|
-
|
294
|
+
const worldRef = useRef();
|
295
|
+
const getWorldRef = useRef(() => {
|
296
|
+
if (!worldRef.current) {
|
297
|
+
const world = new rapier.World(vectorArrayToObject(_gravity));
|
298
|
+
worldRef.current = world;
|
299
|
+
}
|
300
|
+
|
301
|
+
return worldRef.current;
|
302
|
+
});
|
303
|
+
const [colliderMeshes] = useState(() => new Map());
|
304
|
+
const [rigidBodyMeshes] = useState(() => new Map());
|
305
|
+
const [rigidBodyEvents] = useState(() => new Map());
|
306
|
+
const [eventQueue] = useState(() => new EventQueue(false)); // Init world
|
307
|
+
|
308
|
+
useLayoutEffect(() => {
|
309
|
+
const world = getWorldRef.current();
|
310
|
+
return () => {
|
311
|
+
if (world) {
|
312
|
+
world.free();
|
313
|
+
worldRef.current = undefined;
|
314
|
+
}
|
315
|
+
};
|
316
|
+
}, []);
|
194
317
|
const time = useRef(performance.now());
|
195
318
|
useFrame(context => {
|
196
|
-
|
319
|
+
const world = worldRef.current;
|
320
|
+
if (!world) return; // Set timestep to current delta, to allow for variable frame rates
|
197
321
|
// We cap the delta at 100, so that the physics simulation doesn't get wild
|
322
|
+
|
198
323
|
const now = performance.now();
|
199
324
|
const delta = Math.min(100, now - time.current);
|
200
325
|
world.timestep = delta / 1000;
|
201
|
-
world.step(); //
|
326
|
+
world.step(eventQueue); // Update meshes
|
327
|
+
|
328
|
+
rigidBodyMeshes.forEach((mesh, handle) => {
|
329
|
+
const rigidBody = world.getRigidBody(handle);
|
330
|
+
const events = rigidBodyEvents.get(handle);
|
331
|
+
|
332
|
+
if (events !== null && events !== void 0 && events.onSleep || events !== null && events !== void 0 && events.onWake) {
|
333
|
+
if (rigidBody.isSleeping() && !mesh.userData.isSleeping) {
|
334
|
+
var _events$onSleep;
|
335
|
+
|
336
|
+
events === null || events === void 0 ? void 0 : (_events$onSleep = events.onSleep) === null || _events$onSleep === void 0 ? void 0 : _events$onSleep.call(events);
|
337
|
+
}
|
202
338
|
|
203
|
-
|
339
|
+
if (!rigidBody.isSleeping() && mesh.userData.isSleeping) {
|
340
|
+
var _events$onWake;
|
341
|
+
|
342
|
+
events === null || events === void 0 ? void 0 : (_events$onWake = events.onWake) === null || _events$onWake === void 0 ? void 0 : _events$onWake.call(events);
|
343
|
+
}
|
344
|
+
|
345
|
+
mesh.userData.isSleeping = rigidBody.isSleeping();
|
346
|
+
}
|
347
|
+
|
348
|
+
if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !mesh.parent) {
|
349
|
+
return;
|
350
|
+
}
|
351
|
+
|
352
|
+
const {
|
353
|
+
x,
|
354
|
+
y,
|
355
|
+
z
|
356
|
+
} = rigidBody.translation();
|
357
|
+
const {
|
358
|
+
x: rx,
|
359
|
+
y: ry,
|
360
|
+
z: rz,
|
361
|
+
w: rw
|
362
|
+
} = rigidBody.rotation();
|
363
|
+
const scale = mesh.getWorldScale(new Vector3()); // haha matrixes I have no idea what I'm doing :)
|
364
|
+
|
365
|
+
const o = new Object3D();
|
366
|
+
o.position.set(x, y, z);
|
367
|
+
o.rotation.setFromQuaternion(new Quaternion(rx, ry, rz, rw));
|
368
|
+
o.scale.set(scale.x, scale.y, scale.z);
|
369
|
+
o.updateMatrix();
|
370
|
+
o.applyMatrix4(mesh.parent.matrixWorld.clone().invert());
|
371
|
+
o.updateMatrix();
|
372
|
+
mesh.position.setFromMatrixPosition(o.matrix);
|
373
|
+
mesh.rotation.setFromRotationMatrix(o.matrix);
|
374
|
+
}); // Collision events
|
375
|
+
|
376
|
+
eventQueue.drainCollisionEvents((handle1, handle2, started) => {
|
377
|
+
const collider1 = world.getCollider(handle1);
|
378
|
+
const collider2 = world.getCollider(handle2);
|
379
|
+
const rigidBodyHandle1 = collider1.parent();
|
380
|
+
const rigidBodyHandle2 = collider2.parent();
|
381
|
+
|
382
|
+
if (!collider1 || !collider2 || !rigidBodyHandle1 || !rigidBodyHandle2) {
|
383
|
+
return;
|
384
|
+
}
|
385
|
+
|
386
|
+
const rigidBody1 = world.getRigidBody(rigidBodyHandle1);
|
387
|
+
const rigidBody2 = world.getRigidBody(rigidBodyHandle2);
|
388
|
+
const events1 = rigidBodyEvents.get(rigidBodyHandle1);
|
389
|
+
const events2 = rigidBodyEvents.get(rigidBodyHandle2);
|
390
|
+
|
391
|
+
if (started) {
|
392
|
+
world.contactPair(handle1, handle2, (manifold, flipped) => {
|
393
|
+
var _events1$onCollisionE, _events2$onCollisionE;
|
394
|
+
|
395
|
+
events1 === null || events1 === void 0 ? void 0 : (_events1$onCollisionE = events1.onCollisionEnter) === null || _events1$onCollisionE === void 0 ? void 0 : _events1$onCollisionE.call(events1, {
|
396
|
+
target: rigidBody2,
|
397
|
+
manifold,
|
398
|
+
flipped
|
399
|
+
});
|
400
|
+
events2 === null || events2 === void 0 ? void 0 : (_events2$onCollisionE = events2.onCollisionEnter) === null || _events2$onCollisionE === void 0 ? void 0 : _events2$onCollisionE.call(events2, {
|
401
|
+
target: rigidBody1,
|
402
|
+
manifold,
|
403
|
+
flipped
|
404
|
+
});
|
405
|
+
});
|
406
|
+
} else {
|
407
|
+
var _events1$onCollisionE2, _events2$onCollisionE2;
|
408
|
+
|
409
|
+
events1 === null || events1 === void 0 ? void 0 : (_events1$onCollisionE2 = events1.onCollisionExit) === null || _events1$onCollisionE2 === void 0 ? void 0 : _events1$onCollisionE2.call(events1, {
|
410
|
+
target: rigidBody2
|
411
|
+
});
|
412
|
+
events2 === null || events2 === void 0 ? void 0 : (_events2$onCollisionE2 = events2.onCollisionExit) === null || _events2$onCollisionE2 === void 0 ? void 0 : _events2$onCollisionE2.call(events2, {
|
413
|
+
target: rigidBody1
|
414
|
+
});
|
415
|
+
}
|
416
|
+
});
|
204
417
|
time.current = now;
|
205
418
|
});
|
419
|
+
const api = useMemo(() => createWorldApi(getWorldRef), []);
|
206
420
|
const context = useMemo(() => ({
|
207
|
-
|
208
|
-
world,
|
209
|
-
|
210
|
-
|
211
|
-
|
421
|
+
rapier,
|
422
|
+
world: api,
|
423
|
+
physicsOptions: {
|
424
|
+
colliders: _colliders,
|
425
|
+
gravity: _gravity
|
426
|
+
},
|
427
|
+
colliderMeshes,
|
428
|
+
rigidBodyMeshes,
|
429
|
+
rigidBodyEvents
|
430
|
+
}), []);
|
212
431
|
return /*#__PURE__*/React.createElement(RapierContext.Provider, {
|
213
432
|
value: context
|
214
433
|
}, children);
|
@@ -257,69 +476,52 @@ function _objectSpread2(target) {
|
|
257
476
|
|
258
477
|
const useRapier = () => {
|
259
478
|
return useContext(RapierContext);
|
260
|
-
}; // Private hook for updating the simulations on objects
|
261
|
-
|
262
|
-
const useRapierStep = callback => {
|
263
|
-
const {
|
264
|
-
stepFuncs
|
265
|
-
} = useRapier();
|
266
|
-
useEffect(() => {
|
267
|
-
stepFuncs.push(callback);
|
268
|
-
return () => {
|
269
|
-
const index = stepFuncs.indexOf(callback);
|
270
|
-
stepFuncs.splice(index, 1);
|
271
|
-
};
|
272
|
-
}, [callback]);
|
273
|
-
};
|
274
|
-
const useCollider = (body, options = {}) => {
|
275
|
-
const {
|
276
|
-
RAPIER,
|
277
|
-
world
|
278
|
-
} = useRapier();
|
279
|
-
const collider = useMemo(() => {
|
280
|
-
return createColliderFromOptions(options, world, body);
|
281
|
-
}, []);
|
282
|
-
useEffect(() => {
|
283
|
-
return () => {
|
284
|
-
world.removeCollider(collider, false);
|
285
|
-
};
|
286
|
-
}, []);
|
287
|
-
return [collider];
|
288
479
|
};
|
289
|
-
const useRigidBody = options => {
|
480
|
+
const useRigidBody = (options = {}) => {
|
290
481
|
const {
|
291
|
-
|
292
|
-
world
|
482
|
+
rapier,
|
483
|
+
world,
|
484
|
+
rigidBodyMeshes,
|
485
|
+
physicsOptions,
|
486
|
+
rigidBodyEvents
|
293
487
|
} = useRapier();
|
294
488
|
const ref = useRef(); // Create rigidbody
|
295
489
|
|
296
|
-
const
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
490
|
+
const rigidBodyRef = useRef();
|
491
|
+
const getRigidBodyRef = useRef(() => {
|
492
|
+
if (!rigidBodyRef.current) {
|
493
|
+
var _options$linearVeloci, _options$angularVeloc, _options$gravityScale, _options$canSleep, _options$ccd;
|
494
|
+
|
495
|
+
const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
|
496
|
+
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];
|
497
|
+
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];
|
498
|
+
const gravityScale = (_options$gravityScale = options === null || options === void 0 ? void 0 : options.gravityScale) !== null && _options$gravityScale !== void 0 ? _options$gravityScale : 1;
|
499
|
+
const canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
|
500
|
+
const ccdEnabled = (_options$ccd = options === null || options === void 0 ? void 0 : options.ccd) !== null && _options$ccd !== void 0 ? _options$ccd : false;
|
501
|
+
const desc = new rapier.RigidBodyDesc(type).setLinvel(lvx, lvy, lvz).setAngvel({
|
502
|
+
x: avx,
|
503
|
+
y: avy,
|
504
|
+
z: avz
|
505
|
+
}).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled);
|
506
|
+
const rigidBody = world.createRigidBody(desc);
|
507
|
+
rigidBodyRef.current = rigidBody;
|
508
|
+
}
|
509
|
+
|
510
|
+
return rigidBodyRef.current;
|
511
|
+
}); // Setup
|
315
512
|
|
316
513
|
useEffect(() => {
|
317
|
-
var _ref$current$parent, _options$colliders;
|
514
|
+
var _ref$current$parent, _ref, _options$colliders;
|
515
|
+
|
516
|
+
const rigidBody = getRigidBodyRef.current();
|
517
|
+
rigidBodyRef.current = rigidBody;
|
318
518
|
|
319
519
|
if (!ref.current) {
|
320
520
|
ref.current = new Object3D();
|
321
|
-
} //
|
521
|
+
} // isSleeping used for onSleep and onWake events
|
522
|
+
|
322
523
|
|
524
|
+
ref.current.userData.isSleeping = false; // Get intitial world transforms
|
323
525
|
|
324
526
|
const worldPosition = ref.current.getWorldPosition(new Vector3());
|
325
527
|
const worldRotation = ref.current.getWorldQuaternion(new Quaternion());
|
@@ -347,43 +549,56 @@ const useRigidBody = options => {
|
|
347
549
|
}, false);
|
348
550
|
rigidBody.resetForces(false);
|
349
551
|
rigidBody.resetTorques(false);
|
350
|
-
const colliderSetting = (_options$colliders = options === null || options === void 0 ? void 0 : options.colliders) !== null && _options$colliders !== void 0 ? _options$colliders : false;
|
351
|
-
const
|
552
|
+
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;
|
553
|
+
const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
|
554
|
+
const autoColliders = colliderSetting !== false ? createCollidersFromChildren(ref.current, rigidBody, colliderSetting, world, hasCollisionEvents) : [];
|
555
|
+
rigidBody.wakeUp();
|
556
|
+
rigidBodyMeshes.set(rigidBody.handle, ref.current);
|
352
557
|
return () => {
|
558
|
+
autoColliders.forEach(collider => world.removeCollider(collider));
|
353
559
|
world.removeRigidBody(rigidBody);
|
354
|
-
|
560
|
+
rigidBodyRef.current = undefined;
|
561
|
+
rigidBodyMeshes.delete(rigidBody.handle);
|
355
562
|
};
|
356
|
-
}, []);
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
ref.current.rotation.setFromRotationMatrix(o.matrix);
|
383
|
-
}
|
563
|
+
}, []); // Events
|
564
|
+
|
565
|
+
useEffect(() => {
|
566
|
+
const rigidBody = getRigidBodyRef.current();
|
567
|
+
rigidBodyEvents.set(rigidBody.handle, {
|
568
|
+
onCollisionEnter: options === null || options === void 0 ? void 0 : options.onCollisionEnter,
|
569
|
+
onCollisionExit: options === null || options === void 0 ? void 0 : options.onCollisionExit,
|
570
|
+
onSleep: options === null || options === void 0 ? void 0 : options.onSleep,
|
571
|
+
onWake: options === null || options === void 0 ? void 0 : options.onWake
|
572
|
+
});
|
573
|
+
return () => {
|
574
|
+
rigidBodyEvents.delete(rigidBody.handle);
|
575
|
+
};
|
576
|
+
}, [options.onCollisionEnter, options.onCollisionExit]);
|
577
|
+
const api = useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
|
578
|
+
return [ref, api];
|
579
|
+
};
|
580
|
+
const useCollider = (body, options = {}) => {
|
581
|
+
const {
|
582
|
+
world
|
583
|
+
} = useRapier();
|
584
|
+
const colliderRef = useRef();
|
585
|
+
const objectRef = useRef();
|
586
|
+
const getColliderRef = useRef(() => {
|
587
|
+
if (!colliderRef.current) {
|
588
|
+
colliderRef.current = createColliderFromOptions(options, world, body.handle);
|
384
589
|
}
|
590
|
+
|
591
|
+
return colliderRef.current;
|
385
592
|
});
|
386
|
-
|
593
|
+
useEffect(() => {
|
594
|
+
const collider = getColliderRef.current();
|
595
|
+
return () => {
|
596
|
+
if (collider) world.removeCollider(collider);
|
597
|
+
colliderRef.current = undefined;
|
598
|
+
};
|
599
|
+
}, []);
|
600
|
+
const api = useMemo(() => createColliderApi(getColliderRef), []);
|
601
|
+
return [objectRef, api];
|
387
602
|
};
|
388
603
|
const useRigidBodyWithCollider = (rigidBodyOptions, colliderOptions) => {
|
389
604
|
const {
|
@@ -396,9 +611,9 @@ const useRigidBodyWithCollider = (rigidBodyOptions, colliderOptions) => {
|
|
396
611
|
}
|
397
612
|
|
398
613
|
const scale = ref.current.getWorldScale(new Vector3());
|
399
|
-
const collider = createColliderFromOptions(colliderOptions, world, rigidBody, scale);
|
614
|
+
const collider = createColliderFromOptions(colliderOptions, world, rigidBody.handle, scale);
|
400
615
|
return () => {
|
401
|
-
world.removeCollider(collider
|
616
|
+
world.removeCollider(collider);
|
402
617
|
};
|
403
618
|
}, []);
|
404
619
|
return [ref, rigidBody];
|
@@ -524,20 +739,42 @@ const useRoundConvexMesh = (rigidBodyOptions = {}, colliderOptions = {}) => {
|
|
524
739
|
|
525
740
|
const useImpulseJoint = (body1, body2, params) => {
|
526
741
|
const {
|
527
|
-
world
|
528
|
-
RAPIER
|
742
|
+
world
|
529
743
|
} = useRapier();
|
530
|
-
|
531
|
-
|
744
|
+
const jointRef = useRef();
|
745
|
+
const getJointRef = useRef(() => {
|
746
|
+
if (!jointRef.current) {
|
747
|
+
let rb1;
|
748
|
+
let rb2;
|
749
|
+
|
750
|
+
if ('handle' in body1 && 'handle' in body2) {
|
751
|
+
rb1 = world.getRigidBody(body1.handle);
|
752
|
+
rb2 = world.getRigidBody(body2.handle);
|
753
|
+
jointRef.current = world.createImpulseJoint(params, rb1, rb2);
|
754
|
+
}
|
532
755
|
|
533
|
-
|
534
|
-
|
756
|
+
if ('current' in body1 && body1.current && 'current' in body2 && body2.current) {
|
757
|
+
rb1 = world.getRigidBody(body1.current.handle);
|
758
|
+
rb2 = world.getRigidBody(body2.current.handle);
|
759
|
+
const newJoint = world.createImpulseJoint(params, rb1, rb2);
|
760
|
+
jointRef.current = newJoint;
|
761
|
+
}
|
535
762
|
}
|
536
763
|
|
764
|
+
return jointRef.current;
|
765
|
+
});
|
766
|
+
useEffect(() => {
|
767
|
+
const joint = getJointRef.current();
|
537
768
|
return () => {
|
538
|
-
if (joint)
|
769
|
+
if (joint) {
|
770
|
+
console.log('remove joint', joint);
|
771
|
+
world.removeImpulseJoint(joint);
|
772
|
+
jointRef.current = undefined;
|
773
|
+
}
|
539
774
|
};
|
540
|
-
}, [
|
775
|
+
}, []);
|
776
|
+
const api = useMemo(() => createJointApi(getJointRef), []);
|
777
|
+
return api;
|
541
778
|
};
|
542
779
|
/**
|
543
780
|
*
|
@@ -548,9 +785,9 @@ const useImpulseJoint = (body1, body2, params) => {
|
|
548
785
|
|
549
786
|
const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor, body2LocalFrame]) => {
|
550
787
|
const {
|
551
|
-
|
788
|
+
rapier
|
552
789
|
} = useRapier();
|
553
|
-
return useImpulseJoint(body1, body2,
|
790
|
+
return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToObject(body1Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToObject(body1LocalFrame)), {}, {
|
554
791
|
w: 1
|
555
792
|
}), vectorArrayToObject(body2Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToObject(body2LocalFrame)), {}, {
|
556
793
|
w: 1
|
@@ -565,9 +802,9 @@ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor,
|
|
565
802
|
|
566
803
|
const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
567
804
|
const {
|
568
|
-
|
805
|
+
rapier
|
569
806
|
} = useRapier();
|
570
|
-
return useImpulseJoint(body1, body2,
|
807
|
+
return useImpulseJoint(body1, body2, rapier.JointData.spherical(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor)));
|
571
808
|
};
|
572
809
|
/**
|
573
810
|
* The revolute joint prevents any relative movement between two rigid-bodies, except for relative
|
@@ -577,9 +814,9 @@ const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
|
577
814
|
|
578
815
|
const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
579
816
|
const {
|
580
|
-
|
817
|
+
rapier
|
581
818
|
} = useRapier();
|
582
|
-
return useImpulseJoint(body1, body2,
|
819
|
+
return useImpulseJoint(body1, body2, rapier.JointData.revolute(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor), vectorArrayToObject(axis)));
|
583
820
|
};
|
584
821
|
/**
|
585
822
|
* The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
|
@@ -589,9 +826,9 @@ const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
|
589
826
|
|
590
827
|
const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
591
828
|
const {
|
592
|
-
|
829
|
+
rapier
|
593
830
|
} = useRapier();
|
594
|
-
return useImpulseJoint(body1, body2,
|
831
|
+
return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor), vectorArrayToObject(axis)));
|
595
832
|
};
|
596
833
|
|
597
834
|
function _extends() {
|
@@ -646,10 +883,11 @@ function _objectWithoutProperties(source, excluded) {
|
|
646
883
|
return target;
|
647
884
|
}
|
648
885
|
|
649
|
-
const _excluded = ["children"]
|
886
|
+
const _excluded = ["children"],
|
887
|
+
_excluded2 = ["children"];
|
650
888
|
const RigidBodyContext = /*#__PURE__*/createContext(undefined);
|
651
889
|
|
652
|
-
const
|
890
|
+
const useRigidBodyContext = () => useContext(RigidBodyContext); // RigidBody
|
653
891
|
|
654
892
|
|
655
893
|
const RigidBody = /*#__PURE__*/forwardRef((_ref, ref) => {
|
@@ -658,28 +896,36 @@ const RigidBody = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
658
896
|
} = _ref,
|
659
897
|
props = _objectWithoutProperties(_ref, _excluded);
|
660
898
|
|
661
|
-
const [
|
899
|
+
const [object, rigidBody] = useRigidBody(props);
|
662
900
|
useImperativeHandle(ref, () => rigidBody);
|
663
901
|
return /*#__PURE__*/React.createElement(RigidBodyContext.Provider, {
|
664
|
-
value: [
|
665
|
-
}, /*#__PURE__*/React.createElement("
|
666
|
-
ref:
|
902
|
+
value: [object, rigidBody, !!(props.onCollisionEnter || props.onCollisionExit)]
|
903
|
+
}, /*#__PURE__*/React.createElement("object3D", {
|
904
|
+
ref: object
|
667
905
|
}, children));
|
668
906
|
}); // Colliders
|
669
907
|
|
670
|
-
const AnyCollider =
|
908
|
+
const AnyCollider = _ref2 => {
|
909
|
+
let {
|
910
|
+
children
|
911
|
+
} = _ref2,
|
912
|
+
props = _objectWithoutProperties(_ref2, _excluded2);
|
913
|
+
|
671
914
|
const {
|
672
915
|
world
|
673
916
|
} = useRapier();
|
674
|
-
const [
|
917
|
+
const [, rigidBody, hasCollisionEvents] = useRigidBodyContext();
|
918
|
+
const ref = useRef(null);
|
675
919
|
useEffect(() => {
|
676
|
-
const scale =
|
677
|
-
const collider = createColliderFromOptions(props, world, rigidBody, scale);
|
920
|
+
const scale = ref.current.getWorldScale(new Vector3());
|
921
|
+
const collider = createColliderFromOptions(props, world, rigidBody.handle, scale, hasCollisionEvents);
|
678
922
|
return () => {
|
679
|
-
world.removeCollider(collider
|
923
|
+
world.removeCollider(collider);
|
680
924
|
};
|
681
925
|
}, []);
|
682
|
-
return
|
926
|
+
return /*#__PURE__*/React.createElement("object3D", {
|
927
|
+
ref: ref
|
928
|
+
}, children);
|
683
929
|
};
|
684
930
|
|
685
931
|
const CuboidCollider = props => {
|
@@ -828,7 +1074,7 @@ const Debug = () => {
|
|
828
1074
|
|
829
1075
|
useFrame(() => {
|
830
1076
|
const newColliders = [];
|
831
|
-
world.
|
1077
|
+
world.forEachCollider(collider => {
|
832
1078
|
newColliders.push(collider.handle);
|
833
1079
|
});
|
834
1080
|
setColliders(newColliders);
|