@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
@@ -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
|
+
}
|
338
|
+
|
339
|
+
if (!rigidBody.isSleeping() && mesh.userData.isSleeping) {
|
340
|
+
var _events$onWake;
|
202
341
|
|
203
|
-
|
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,71 +476,53 @@ 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
|
-
|
482
|
+
rapier,
|
292
483
|
world,
|
293
|
-
|
484
|
+
rigidBodyMeshes,
|
485
|
+
physicsOptions,
|
486
|
+
rigidBodyEvents
|
294
487
|
} = useRapier();
|
295
488
|
const ref = useRef(); // Create rigidbody
|
296
489
|
|
297
|
-
const
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
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
|
316
512
|
|
317
513
|
useEffect(() => {
|
318
514
|
var _ref$current$parent, _ref, _options$colliders;
|
319
515
|
|
516
|
+
const rigidBody = getRigidBodyRef.current();
|
517
|
+
rigidBodyRef.current = rigidBody;
|
518
|
+
|
320
519
|
if (!ref.current) {
|
321
520
|
ref.current = new Object3D();
|
322
|
-
} //
|
521
|
+
} // isSleeping used for onSleep and onWake events
|
323
522
|
|
324
523
|
|
524
|
+
ref.current.userData.isSleeping = false; // Get intitial world transforms
|
525
|
+
|
325
526
|
const worldPosition = ref.current.getWorldPosition(new Vector3());
|
326
527
|
const worldRotation = ref.current.getWorldQuaternion(new Quaternion());
|
327
528
|
const scale = ((_ref$current$parent = ref.current.parent) === null || _ref$current$parent === void 0 ? void 0 : _ref$current$parent.getWorldScale(new Vector3())) || {
|
@@ -348,43 +549,56 @@ const useRigidBody = options => {
|
|
348
549
|
}, false);
|
349
550
|
rigidBody.resetForces(false);
|
350
551
|
rigidBody.resetTorques(false);
|
351
|
-
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;
|
352
|
-
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);
|
353
557
|
return () => {
|
558
|
+
autoColliders.forEach(collider => world.removeCollider(collider));
|
354
559
|
world.removeRigidBody(rigidBody);
|
355
|
-
|
560
|
+
rigidBodyRef.current = undefined;
|
561
|
+
rigidBodyMeshes.delete(rigidBody.handle);
|
356
562
|
};
|
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
|
-
|
383
|
-
ref.current.rotation.setFromRotationMatrix(o.matrix);
|
384
|
-
}
|
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);
|
385
589
|
}
|
590
|
+
|
591
|
+
return colliderRef.current;
|
386
592
|
});
|
387
|
-
|
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];
|
388
602
|
};
|
389
603
|
const useRigidBodyWithCollider = (rigidBodyOptions, colliderOptions) => {
|
390
604
|
const {
|
@@ -397,9 +611,9 @@ const useRigidBodyWithCollider = (rigidBodyOptions, colliderOptions) => {
|
|
397
611
|
}
|
398
612
|
|
399
613
|
const scale = ref.current.getWorldScale(new Vector3());
|
400
|
-
const collider = createColliderFromOptions(colliderOptions, world, rigidBody, scale);
|
614
|
+
const collider = createColliderFromOptions(colliderOptions, world, rigidBody.handle, scale);
|
401
615
|
return () => {
|
402
|
-
world.removeCollider(collider
|
616
|
+
world.removeCollider(collider);
|
403
617
|
};
|
404
618
|
}, []);
|
405
619
|
return [ref, rigidBody];
|
@@ -525,20 +739,42 @@ const useRoundConvexMesh = (rigidBodyOptions = {}, colliderOptions = {}) => {
|
|
525
739
|
|
526
740
|
const useImpulseJoint = (body1, body2, params) => {
|
527
741
|
const {
|
528
|
-
world
|
529
|
-
RAPIER
|
742
|
+
world
|
530
743
|
} = useRapier();
|
531
|
-
|
532
|
-
|
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
|
+
}
|
533
755
|
|
534
|
-
|
535
|
-
|
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
|
+
}
|
536
762
|
}
|
537
763
|
|
764
|
+
return jointRef.current;
|
765
|
+
});
|
766
|
+
useEffect(() => {
|
767
|
+
const joint = getJointRef.current();
|
538
768
|
return () => {
|
539
|
-
if (joint)
|
769
|
+
if (joint) {
|
770
|
+
console.log('remove joint', joint);
|
771
|
+
world.removeImpulseJoint(joint);
|
772
|
+
jointRef.current = undefined;
|
773
|
+
}
|
540
774
|
};
|
541
|
-
}, [
|
775
|
+
}, []);
|
776
|
+
const api = useMemo(() => createJointApi(getJointRef), []);
|
777
|
+
return api;
|
542
778
|
};
|
543
779
|
/**
|
544
780
|
*
|
@@ -549,9 +785,9 @@ const useImpulseJoint = (body1, body2, params) => {
|
|
549
785
|
|
550
786
|
const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor, body2LocalFrame]) => {
|
551
787
|
const {
|
552
|
-
|
788
|
+
rapier
|
553
789
|
} = useRapier();
|
554
|
-
return useImpulseJoint(body1, body2,
|
790
|
+
return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToObject(body1Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToObject(body1LocalFrame)), {}, {
|
555
791
|
w: 1
|
556
792
|
}), vectorArrayToObject(body2Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToObject(body2LocalFrame)), {}, {
|
557
793
|
w: 1
|
@@ -566,9 +802,9 @@ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor,
|
|
566
802
|
|
567
803
|
const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
568
804
|
const {
|
569
|
-
|
805
|
+
rapier
|
570
806
|
} = useRapier();
|
571
|
-
return useImpulseJoint(body1, body2,
|
807
|
+
return useImpulseJoint(body1, body2, rapier.JointData.spherical(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor)));
|
572
808
|
};
|
573
809
|
/**
|
574
810
|
* The revolute joint prevents any relative movement between two rigid-bodies, except for relative
|
@@ -578,9 +814,9 @@ const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
|
578
814
|
|
579
815
|
const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
580
816
|
const {
|
581
|
-
|
817
|
+
rapier
|
582
818
|
} = useRapier();
|
583
|
-
return useImpulseJoint(body1, body2,
|
819
|
+
return useImpulseJoint(body1, body2, rapier.JointData.revolute(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor), vectorArrayToObject(axis)));
|
584
820
|
};
|
585
821
|
/**
|
586
822
|
* The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
|
@@ -590,9 +826,9 @@ const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
|
590
826
|
|
591
827
|
const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
592
828
|
const {
|
593
|
-
|
829
|
+
rapier
|
594
830
|
} = useRapier();
|
595
|
-
return useImpulseJoint(body1, body2,
|
831
|
+
return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToObject(body1Anchor), vectorArrayToObject(body2Anchor), vectorArrayToObject(axis)));
|
596
832
|
};
|
597
833
|
|
598
834
|
function _extends() {
|
@@ -647,10 +883,11 @@ function _objectWithoutProperties(source, excluded) {
|
|
647
883
|
return target;
|
648
884
|
}
|
649
885
|
|
650
|
-
const _excluded = ["children"]
|
886
|
+
const _excluded = ["children"],
|
887
|
+
_excluded2 = ["children"];
|
651
888
|
const RigidBodyContext = /*#__PURE__*/createContext(undefined);
|
652
889
|
|
653
|
-
const
|
890
|
+
const useRigidBodyContext = () => useContext(RigidBodyContext); // RigidBody
|
654
891
|
|
655
892
|
|
656
893
|
const RigidBody = /*#__PURE__*/forwardRef((_ref, ref) => {
|
@@ -659,28 +896,36 @@ const RigidBody = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
659
896
|
} = _ref,
|
660
897
|
props = _objectWithoutProperties(_ref, _excluded);
|
661
898
|
|
662
|
-
const [
|
899
|
+
const [object, rigidBody] = useRigidBody(props);
|
663
900
|
useImperativeHandle(ref, () => rigidBody);
|
664
901
|
return /*#__PURE__*/React.createElement(RigidBodyContext.Provider, {
|
665
|
-
value: [
|
666
|
-
}, /*#__PURE__*/React.createElement("
|
667
|
-
ref:
|
902
|
+
value: [object, rigidBody, !!(props.onCollisionEnter || props.onCollisionExit)]
|
903
|
+
}, /*#__PURE__*/React.createElement("object3D", {
|
904
|
+
ref: object
|
668
905
|
}, children));
|
669
906
|
}); // Colliders
|
670
907
|
|
671
|
-
const AnyCollider =
|
908
|
+
const AnyCollider = _ref2 => {
|
909
|
+
let {
|
910
|
+
children
|
911
|
+
} = _ref2,
|
912
|
+
props = _objectWithoutProperties(_ref2, _excluded2);
|
913
|
+
|
672
914
|
const {
|
673
915
|
world
|
674
916
|
} = useRapier();
|
675
|
-
const [
|
917
|
+
const [, rigidBody, hasCollisionEvents] = useRigidBodyContext();
|
918
|
+
const ref = useRef(null);
|
676
919
|
useEffect(() => {
|
677
|
-
const scale =
|
678
|
-
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);
|
679
922
|
return () => {
|
680
|
-
world.removeCollider(collider
|
923
|
+
world.removeCollider(collider);
|
681
924
|
};
|
682
925
|
}, []);
|
683
|
-
return
|
926
|
+
return /*#__PURE__*/React.createElement("object3D", {
|
927
|
+
ref: ref
|
928
|
+
}, children);
|
684
929
|
};
|
685
930
|
|
686
931
|
const CuboidCollider = props => {
|
@@ -829,7 +1074,7 @@ const Debug = () => {
|
|
829
1074
|
|
830
1075
|
useFrame(() => {
|
831
1076
|
const newColliders = [];
|
832
|
-
world.
|
1077
|
+
world.forEachCollider(collider => {
|
833
1078
|
newColliders.push(collider.handle);
|
834
1079
|
});
|
835
1080
|
setColliders(newColliders);
|