@react-three/rapier 0.6.9 → 0.7.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/dist/declarations/src/AnyCollider.d.ts +6 -2
- package/dist/declarations/src/InstancedRigidBodies.d.ts +1 -1
- package/dist/declarations/src/MeshCollider.d.ts +1 -1
- package/dist/declarations/src/Physics.d.ts +32 -19
- package/dist/declarations/src/RigidBody.d.ts +0 -2
- package/dist/declarations/src/hooks.d.ts +3 -1
- package/dist/declarations/src/shared-objects.d.ts +3 -0
- package/dist/declarations/src/types.d.ts +48 -17
- package/dist/declarations/src/utils-collider.d.ts +36 -0
- package/dist/declarations/src/utils-rigidbody.d.ts +20 -0
- package/dist/declarations/src/utils.d.ts +5 -46
- package/dist/react-three-rapier.cjs.dev.js +775 -672
- package/dist/react-three-rapier.cjs.prod.js +775 -672
- package/dist/react-three-rapier.esm.js +776 -675
- package/package.json +1 -1
- package/readme.md +19 -3
@@ -7,7 +7,6 @@ var React = require('react');
|
|
7
7
|
var useAsset = require('use-asset');
|
8
8
|
var fiber = require('@react-three/fiber');
|
9
9
|
var three = require('three');
|
10
|
-
var BufferGeometryUtils = require('three/examples/jsm/utils/BufferGeometryUtils');
|
11
10
|
var MathUtils = require('three/src/math/MathUtils');
|
12
11
|
var threeStdlib = require('three-stdlib');
|
13
12
|
|
@@ -34,18 +33,18 @@ function _interopNamespace(e) {
|
|
34
33
|
var React__default = /*#__PURE__*/_interopDefault(React);
|
35
34
|
|
36
35
|
const _quaternion = new three.Quaternion();
|
37
|
-
|
36
|
+
new three.Euler();
|
38
37
|
const _vector3 = new three.Vector3();
|
39
|
-
new three.Object3D();
|
38
|
+
const _object3d = new three.Object3D();
|
40
39
|
const _matrix4 = new three.Matrix4();
|
40
|
+
const _position = new three.Vector3();
|
41
|
+
const _rotation = new three.Quaternion();
|
42
|
+
const _scale = new three.Vector3();
|
41
43
|
|
42
44
|
const vectorArrayToVector3 = arr => {
|
43
45
|
const [x, y, z] = arr;
|
44
46
|
return new three.Vector3(x, y, z);
|
45
47
|
};
|
46
|
-
const vector3ToQuaternion = v => {
|
47
|
-
return _quaternion.setFromEuler(_euler.setFromVector3(v));
|
48
|
-
};
|
49
48
|
const rapierVector3ToVector3 = ({
|
50
49
|
x,
|
51
50
|
y,
|
@@ -64,216 +63,6 @@ const rigidBodyTypeMap = {
|
|
64
63
|
kinematicVelocity: 3
|
65
64
|
};
|
66
65
|
const rigidBodyTypeFromString = type => rigidBodyTypeMap[type];
|
67
|
-
const decomposeMatrix4 = m => {
|
68
|
-
const position = new three.Vector3();
|
69
|
-
const rotation = new three.Quaternion();
|
70
|
-
const scale = new three.Vector3();
|
71
|
-
m.decompose(position, rotation, scale);
|
72
|
-
return {
|
73
|
-
position,
|
74
|
-
rotation,
|
75
|
-
scale
|
76
|
-
};
|
77
|
-
};
|
78
|
-
const scaleColliderArgs = (shape, args, scale) => {
|
79
|
-
const newArgs = args.slice(); // Heightfield uses a vector
|
80
|
-
|
81
|
-
if (shape === "heightfield") {
|
82
|
-
const s = newArgs[3];
|
83
|
-
s.x *= scale.x;
|
84
|
-
s.x *= scale.y;
|
85
|
-
s.x *= scale.z;
|
86
|
-
return newArgs;
|
87
|
-
} // Trimesh and convex scale the vertices
|
88
|
-
|
89
|
-
|
90
|
-
if (shape === "trimesh" || shape === "convexHull") {
|
91
|
-
newArgs[0] = scaleVertices(newArgs[0], scale);
|
92
|
-
return newArgs;
|
93
|
-
} // Prepfill with some extra
|
94
|
-
|
95
|
-
|
96
|
-
const scaleArray = [scale.x, scale.y, scale.z, scale.x, scale.x];
|
97
|
-
return newArgs.map((arg, index) => scaleArray[index] * arg);
|
98
|
-
};
|
99
|
-
|
100
|
-
const applyColliderOptions = (collider, options) => {
|
101
|
-
if (options.collisionGroups !== undefined) collider.setCollisionGroups(options.collisionGroups);
|
102
|
-
if (options.solverGroups !== undefined) collider.setSolverGroups(options.solverGroups);
|
103
|
-
};
|
104
|
-
|
105
|
-
const createColliderFromOptions = ({
|
106
|
-
options,
|
107
|
-
world,
|
108
|
-
rigidBody,
|
109
|
-
scale,
|
110
|
-
hasCollisionEvents
|
111
|
-
}) => {
|
112
|
-
var _options$shape, _options$args, _options$restitution, _options$restitutionC, _options$friction, _options$frictionComb;
|
113
|
-
|
114
|
-
const mass = (options === null || options === void 0 ? void 0 : options.mass) || 1;
|
115
|
-
const colliderShape = (_options$shape = options === null || options === void 0 ? void 0 : options.shape) !== null && _options$shape !== void 0 ? _options$shape : "cuboid";
|
116
|
-
const colliderArgs = (_options$args = options === null || options === void 0 ? void 0 : options.args) !== null && _options$args !== void 0 ? _options$args : [];
|
117
|
-
const [cmx, cmy, cmz] = (options === null || options === void 0 ? void 0 : options.centerOfMass) || [0, 0, 0];
|
118
|
-
const [pix, piy, piz] = (options === null || options === void 0 ? void 0 : options.principalAngularInertia) || [mass * 0.2, mass * 0.2, mass * 0.2];
|
119
|
-
const [x, y, z] = (options === null || options === void 0 ? void 0 : options.position) || [0, 0, 0];
|
120
|
-
const [rx, ry, rz] = (options === null || options === void 0 ? void 0 : options.rotation) || [0, 0, 0];
|
121
|
-
const qRotation = vector3ToQuaternion(new three.Vector3(rx, ry, rz)); // @ts-ignore
|
122
|
-
|
123
|
-
const scaledArgs = scaleColliderArgs(options.shape, colliderArgs, scale);
|
124
|
-
let colliderDesc = rapier3dCompat.ColliderDesc[colliderShape]( // @ts-ignore
|
125
|
-
...scaledArgs).setTranslation(x * scale.x, y * scale.y, z * scale.z).setRotation({
|
126
|
-
x: qRotation.x,
|
127
|
-
y: qRotation.y,
|
128
|
-
z: qRotation.z,
|
129
|
-
w: qRotation.w
|
130
|
-
}).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);
|
131
|
-
|
132
|
-
if (hasCollisionEvents) {
|
133
|
-
colliderDesc = colliderDesc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
|
134
|
-
} // If any of the mass properties are specified, add mass properties
|
135
|
-
|
136
|
-
|
137
|
-
const qMassRot = vector3ToQuaternion(new three.Vector3(0, 0, 0));
|
138
|
-
|
139
|
-
if (options !== null && options !== void 0 && options.mass || options !== null && options !== void 0 && options.centerOfMass || options !== null && options !== void 0 && options.principalAngularInertia) {
|
140
|
-
colliderDesc.setDensity(0);
|
141
|
-
colliderDesc.setMassProperties(mass, {
|
142
|
-
x: cmx,
|
143
|
-
y: cmy,
|
144
|
-
z: cmz
|
145
|
-
}, {
|
146
|
-
x: pix,
|
147
|
-
y: piy,
|
148
|
-
z: piz
|
149
|
-
}, {
|
150
|
-
x: qMassRot.x,
|
151
|
-
y: qMassRot.y,
|
152
|
-
z: qMassRot.z,
|
153
|
-
w: qMassRot.w
|
154
|
-
});
|
155
|
-
}
|
156
|
-
|
157
|
-
const collider = world.createCollider(colliderDesc, rigidBody);
|
158
|
-
applyColliderOptions(collider, options);
|
159
|
-
return collider;
|
160
|
-
};
|
161
|
-
|
162
|
-
const isChildOfMeshCollider = child => {
|
163
|
-
let flag = false;
|
164
|
-
child.traverseAncestors(a => {
|
165
|
-
if (a.userData.r3RapierType === "MeshCollider") flag = true;
|
166
|
-
});
|
167
|
-
return flag;
|
168
|
-
};
|
169
|
-
|
170
|
-
const createCollidersFromChildren = ({
|
171
|
-
object,
|
172
|
-
rigidBody,
|
173
|
-
options,
|
174
|
-
world,
|
175
|
-
ignoreMeshColliders: _ignoreMeshColliders = true
|
176
|
-
}) => {
|
177
|
-
const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
|
178
|
-
const colliders = [];
|
179
|
-
object.traverseVisible(child => {
|
180
|
-
if ("isMesh" in child) {
|
181
|
-
if (_ignoreMeshColliders && isChildOfMeshCollider(child)) return;
|
182
|
-
const {
|
183
|
-
geometry
|
184
|
-
} = child;
|
185
|
-
const {
|
186
|
-
x,
|
187
|
-
y,
|
188
|
-
z
|
189
|
-
} = child.position;
|
190
|
-
const {
|
191
|
-
x: rx,
|
192
|
-
y: ry,
|
193
|
-
z: rz,
|
194
|
-
w: rw
|
195
|
-
} = new three.Quaternion().setFromEuler(child.rotation);
|
196
|
-
const scale = child.getWorldScale(new three.Vector3()); // We translate the colliders based on the parent's world scale
|
197
|
-
|
198
|
-
const parentWorldScale = child.parent.getWorldScale(new three.Vector3());
|
199
|
-
const desc = colliderDescFromGeometry(geometry, options.colliders, scale, hasCollisionEvents);
|
200
|
-
const offset = new three.Vector3(0, 0, 0);
|
201
|
-
|
202
|
-
if (options.colliders === "cuboid") {
|
203
|
-
var _geometry$boundingBox;
|
204
|
-
|
205
|
-
geometry.computeBoundingBox();
|
206
|
-
(_geometry$boundingBox = geometry.boundingBox) === null || _geometry$boundingBox === void 0 ? void 0 : _geometry$boundingBox.getCenter(offset);
|
207
|
-
}
|
208
|
-
|
209
|
-
if (options.colliders === "ball") {
|
210
|
-
geometry.computeBoundingSphere();
|
211
|
-
offset.copy(geometry.boundingSphere.center);
|
212
|
-
}
|
213
|
-
|
214
|
-
if (Number.isFinite(options.friction)) desc.setFriction(options.friction);
|
215
|
-
if (Number.isFinite(options.restitution)) desc.setRestitution(options.restitution);
|
216
|
-
desc.setTranslation((x + offset.x) * parentWorldScale.x, (y + offset.y) * parentWorldScale.y, (z + offset.z) * parentWorldScale.z).setRotation({
|
217
|
-
x: rx,
|
218
|
-
y: ry,
|
219
|
-
z: rz,
|
220
|
-
w: rw
|
221
|
-
});
|
222
|
-
const actualRigidBody = rigidBody ? world.getRigidBody(rigidBody.handle) : undefined;
|
223
|
-
const collider = world.createCollider(desc, actualRigidBody);
|
224
|
-
applyColliderOptions(collider, options);
|
225
|
-
colliders.push(collider);
|
226
|
-
}
|
227
|
-
});
|
228
|
-
return colliders;
|
229
|
-
};
|
230
|
-
const colliderDescFromGeometry = (geometry, colliders, scale, hasCollisionEvents) => {
|
231
|
-
let desc;
|
232
|
-
|
233
|
-
switch (colliders) {
|
234
|
-
case "cuboid":
|
235
|
-
{
|
236
|
-
geometry.computeBoundingBox();
|
237
|
-
const {
|
238
|
-
boundingBox
|
239
|
-
} = geometry;
|
240
|
-
const size = boundingBox.getSize(new three.Vector3());
|
241
|
-
desc = rapier3dCompat.ColliderDesc.cuboid(size.x / 2 * scale.x, size.y / 2 * scale.y, size.z / 2 * scale.z);
|
242
|
-
}
|
243
|
-
break;
|
244
|
-
|
245
|
-
case "ball":
|
246
|
-
{
|
247
|
-
geometry.computeBoundingSphere();
|
248
|
-
const {
|
249
|
-
boundingSphere
|
250
|
-
} = geometry;
|
251
|
-
const radius = boundingSphere.radius * scale.x;
|
252
|
-
desc = rapier3dCompat.ColliderDesc.ball(radius);
|
253
|
-
}
|
254
|
-
break;
|
255
|
-
|
256
|
-
case "trimesh":
|
257
|
-
{
|
258
|
-
var _g$index;
|
259
|
-
|
260
|
-
const clonedGeometry = geometry.index ? geometry.clone() : BufferGeometryUtils.mergeVertices(geometry);
|
261
|
-
const g = clonedGeometry.scale(scale.x, scale.y, scale.z);
|
262
|
-
desc = rapier3dCompat.ColliderDesc.trimesh(g.attributes.position.array, (_g$index = g.index) === null || _g$index === void 0 ? void 0 : _g$index.array);
|
263
|
-
}
|
264
|
-
break;
|
265
|
-
|
266
|
-
case "hull":
|
267
|
-
{
|
268
|
-
const g = geometry.clone().scale(scale.x, scale.y, scale.z);
|
269
|
-
desc = rapier3dCompat.ColliderDesc.convexHull(g.attributes.position.array);
|
270
|
-
}
|
271
|
-
break;
|
272
|
-
}
|
273
|
-
|
274
|
-
if (hasCollisionEvents) desc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
|
275
|
-
return desc;
|
276
|
-
};
|
277
66
|
const scaleVertices = (vertices, scale) => {
|
278
67
|
const scaledVerts = Array.from(vertices);
|
279
68
|
|
@@ -285,28 +74,6 @@ const scaleVertices = (vertices, scale) => {
|
|
285
74
|
|
286
75
|
return scaledVerts;
|
287
76
|
};
|
288
|
-
const rigidBodyDescFromOptions = options => {
|
289
|
-
var _options$linearVeloci, _options$angularVeloc, _options$angularDampi, _options$linearDampin, _options$gravityScale, _options$canSleep, _options$ccd, _options$enabledRotat, _options$enabledTrans;
|
290
|
-
|
291
|
-
const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
|
292
|
-
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];
|
293
|
-
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];
|
294
|
-
const angularDamping = (_options$angularDampi = options === null || options === void 0 ? void 0 : options.angularDamping) !== null && _options$angularDampi !== void 0 ? _options$angularDampi : 0;
|
295
|
-
const linearDamping = (_options$linearDampin = options === null || options === void 0 ? void 0 : options.linearDamping) !== null && _options$linearDampin !== void 0 ? _options$linearDampin : 0;
|
296
|
-
const gravityScale = (_options$gravityScale = options === null || options === void 0 ? void 0 : options.gravityScale) !== null && _options$gravityScale !== void 0 ? _options$gravityScale : 1;
|
297
|
-
const canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
|
298
|
-
const ccdEnabled = (_options$ccd = options === null || options === void 0 ? void 0 : options.ccd) !== null && _options$ccd !== void 0 ? _options$ccd : false;
|
299
|
-
const [erx, ery, erz] = (_options$enabledRotat = options === null || options === void 0 ? void 0 : options.enabledRotations) !== null && _options$enabledRotat !== void 0 ? _options$enabledRotat : [true, true, true];
|
300
|
-
const [etx, ety, etz] = (_options$enabledTrans = options === null || options === void 0 ? void 0 : options.enabledTranslations) !== null && _options$enabledTrans !== void 0 ? _options$enabledTrans : [true, true, true];
|
301
|
-
const desc = new rapier3dCompat.RigidBodyDesc(type).setLinvel(lvx, lvy, lvz).setAngvel({
|
302
|
-
x: avx,
|
303
|
-
y: avy,
|
304
|
-
z: avz
|
305
|
-
}).setLinearDamping(linearDamping).setAngularDamping(angularDamping).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled).enabledRotations(erx, ery, erz).enabledTranslations(etx, ety, etz);
|
306
|
-
if (options.lockRotations) desc.lockRotations();
|
307
|
-
if (options.lockTranslations) desc.lockTranslations();
|
308
|
-
return desc;
|
309
|
-
};
|
310
77
|
|
311
78
|
const createRigidBodyApi = ref => {
|
312
79
|
return {
|
@@ -458,7 +225,6 @@ const Physics = ({
|
|
458
225
|
gravity: _gravity = [0, -9.81, 0],
|
459
226
|
children,
|
460
227
|
timeStep: _timeStep = 1 / 60,
|
461
|
-
maxSubSteps: _maxSubSteps = 10,
|
462
228
|
paused: _paused = false,
|
463
229
|
updatePriority
|
464
230
|
}) => {
|
@@ -477,6 +243,7 @@ const Physics = ({
|
|
477
243
|
return worldRef.current;
|
478
244
|
});
|
479
245
|
const [rigidBodyStates] = React.useState(() => new Map());
|
246
|
+
const [colliderStates] = React.useState(() => new Map());
|
480
247
|
const [rigidBodyEvents] = React.useState(() => new Map());
|
481
248
|
const [colliderEvents] = React.useState(() => new Map());
|
482
249
|
const [eventQueue] = React.useState(() => new rapier3dCompat.EventQueue(false)); // Init world
|
@@ -498,11 +265,9 @@ const Physics = ({
|
|
498
265
|
}
|
499
266
|
}, [_gravity]);
|
500
267
|
const [steppingState] = React.useState({
|
501
|
-
time: 0,
|
502
|
-
lastTime: 0,
|
503
268
|
accumulator: 0
|
504
269
|
});
|
505
|
-
fiber.useFrame((_,
|
270
|
+
fiber.useFrame((_, dt) => {
|
506
271
|
const world = worldRef.current;
|
507
272
|
if (!world) return;
|
508
273
|
world.timestep = _timeStep;
|
@@ -510,33 +275,19 @@ const Physics = ({
|
|
510
275
|
* Fixed timeStep simulation progression
|
511
276
|
* @see https://gafferongames.com/post/fix_your_timestep/
|
512
277
|
*/
|
278
|
+
// don't step time forwards if paused
|
279
|
+
// Increase accumulator
|
513
280
|
|
514
|
-
|
515
|
-
|
516
|
-
const nowTime = steppingState.time += _paused ? 0 : MathUtils.clamp(delta, 0, 1) * 1000;
|
517
|
-
const timeStepMs = _timeStep * 1000;
|
518
|
-
const timeSinceLast = nowTime - steppingState.lastTime;
|
519
|
-
steppingState.lastTime = nowTime;
|
520
|
-
steppingState.accumulator += timeSinceLast;
|
281
|
+
steppingState.accumulator += _paused ? 0 : MathUtils.clamp(dt, 0, 0.2);
|
521
282
|
|
522
283
|
if (!_paused) {
|
523
|
-
|
524
|
-
|
525
|
-
while (steppingState.accumulator >= timeStepMs && subSteps < _maxSubSteps) {
|
526
|
-
// Collect previous state
|
527
|
-
world.bodies.forEach(b => {
|
528
|
-
previousTranslations[b.handle] = {
|
529
|
-
rotation: rapierQuaternionToQuaternion(b.rotation()).normalize(),
|
530
|
-
translation: rapierVector3ToVector3(b.translation())
|
531
|
-
};
|
532
|
-
});
|
284
|
+
while (steppingState.accumulator >= _timeStep) {
|
533
285
|
world.step(eventQueue);
|
534
|
-
|
535
|
-
steppingState.accumulator -= timeStepMs;
|
286
|
+
steppingState.accumulator -= _timeStep;
|
536
287
|
}
|
537
288
|
}
|
538
289
|
|
539
|
-
const interpolationAlpha = steppingState.accumulator %
|
290
|
+
const interpolationAlpha = steppingState.accumulator % _timeStep / _timeStep; // Update meshes
|
540
291
|
|
541
292
|
rigidBodyStates.forEach((state, handle) => {
|
542
293
|
const rigidBody = world.getRigidBody(handle);
|
@@ -562,86 +313,151 @@ const Physics = ({
|
|
562
313
|
return;
|
563
314
|
}
|
564
315
|
|
565
|
-
let
|
566
|
-
let
|
567
|
-
let newRotation = rapierQuaternionToQuaternion(rigidBody.rotation());
|
568
|
-
let interpolatedTranslation = oldState ? oldState.translation.lerp(newTranslation, 1) : newTranslation;
|
569
|
-
let interpolatedRotation = oldState ? oldState.rotation.slerp(newRotation, interpolationAlpha) : newRotation;
|
570
|
-
state.setMatrix(_matrix4.compose(interpolatedTranslation, interpolatedRotation, state.worldScale).premultiply(state.invertedMatrixWorld));
|
316
|
+
let t = rigidBody.translation();
|
317
|
+
let r = rigidBody.rotation(); // Get new position
|
571
318
|
|
572
|
-
|
573
|
-
state.mesh.instanceMatrix.needsUpdate = true;
|
574
|
-
}
|
575
|
-
}); // Collision events
|
319
|
+
_matrix4.compose(t, rapierQuaternionToQuaternion(r), state.scale).premultiply(state.invertedWorldMatrix).decompose(_position, _rotation, _scale);
|
576
320
|
|
321
|
+
if (state.object instanceof three.InstancedMesh) {
|
322
|
+
state.setMatrix(_matrix4);
|
323
|
+
state.object.instanceMatrix.needsUpdate = true;
|
324
|
+
} else {
|
325
|
+
// Interpolate from last position
|
326
|
+
state.object.position.lerp(_position, interpolationAlpha);
|
327
|
+
state.object.quaternion.slerp(_rotation, interpolationAlpha);
|
328
|
+
}
|
329
|
+
});
|
577
330
|
eventQueue.drainCollisionEvents((handle1, handle2, started) => {
|
578
331
|
var _collider1$parent, _collider2$parent;
|
579
332
|
|
580
333
|
const collider1 = world.getCollider(handle1);
|
581
334
|
const collider2 = world.getCollider(handle2);
|
582
335
|
const rigidBodyHandle1 = (_collider1$parent = collider1.parent()) === null || _collider1$parent === void 0 ? void 0 : _collider1$parent.handle;
|
583
|
-
const rigidBodyHandle2 = (_collider2$parent = collider2.parent()) === null || _collider2$parent === void 0 ? void 0 : _collider2$parent.handle;
|
336
|
+
const rigidBodyHandle2 = (_collider2$parent = collider2.parent()) === null || _collider2$parent === void 0 ? void 0 : _collider2$parent.handle; // Collision Events
|
584
337
|
|
585
|
-
if (!collider1 || !collider2
|
338
|
+
if (!collider1 || !collider2) {
|
586
339
|
return;
|
587
340
|
}
|
588
341
|
|
589
|
-
const rigidBody1 = world.getRigidBody(rigidBodyHandle1);
|
590
|
-
const rigidBody2 = world.getRigidBody(rigidBodyHandle2);
|
591
|
-
const rigidBody1Events = rigidBodyEvents.get(rigidBodyHandle1);
|
592
|
-
const rigidBoyd2Events = rigidBodyEvents.get(rigidBodyHandle2);
|
593
342
|
const collider1Events = colliderEvents.get(collider1.handle);
|
594
343
|
const collider2Events = colliderEvents.get(collider2.handle);
|
344
|
+
const rigidBody1 = rigidBodyHandle1 ? world.getRigidBody(rigidBodyHandle1) : undefined;
|
345
|
+
const rigidBody2 = rigidBodyHandle2 ? world.getRigidBody(rigidBodyHandle2) : undefined;
|
346
|
+
const rigidBody1Events = rigidBodyHandle1 ? rigidBodyEvents.get(rigidBodyHandle1) : undefined;
|
347
|
+
const rigidBody2Events = rigidBodyHandle2 ? rigidBodyEvents.get(rigidBodyHandle2) : undefined;
|
348
|
+
const collider1State = colliderStates.get(collider1.handle);
|
349
|
+
const collider2State = colliderStates.get(collider2.handle);
|
350
|
+
const rigidBody1State = rigidBodyHandle1 ? rigidBodyStates.get(rigidBodyHandle1) : undefined;
|
351
|
+
const rigidBody2State = rigidBodyHandle2 ? rigidBodyStates.get(rigidBodyHandle2) : undefined;
|
595
352
|
|
596
353
|
if (started) {
|
597
354
|
world.contactPair(collider1, collider2, (manifold, flipped) => {
|
598
|
-
var _rigidBody1Events$onC,
|
355
|
+
var _rigidBody1Events$onC, _rigidBody2Events$onC, _collider1Events$onCo, _collider2Events$onCo;
|
599
356
|
|
600
357
|
/* RigidBody events */
|
601
358
|
rigidBody1Events === null || rigidBody1Events === void 0 ? void 0 : (_rigidBody1Events$onC = rigidBody1Events.onCollisionEnter) === null || _rigidBody1Events$onC === void 0 ? void 0 : _rigidBody1Events$onC.call(rigidBody1Events, {
|
602
|
-
|
359
|
+
rigidBody: rigidBody2,
|
603
360
|
collider: collider2,
|
361
|
+
colliderObject: collider2State === null || collider2State === void 0 ? void 0 : collider2State.object,
|
362
|
+
rigidBodyObject: rigidBody2State === null || rigidBody2State === void 0 ? void 0 : rigidBody2State.object,
|
604
363
|
manifold,
|
605
364
|
flipped
|
606
365
|
});
|
607
|
-
|
608
|
-
|
366
|
+
rigidBody2Events === null || rigidBody2Events === void 0 ? void 0 : (_rigidBody2Events$onC = rigidBody2Events.onCollisionEnter) === null || _rigidBody2Events$onC === void 0 ? void 0 : _rigidBody2Events$onC.call(rigidBody2Events, {
|
367
|
+
rigidBody: rigidBody1,
|
609
368
|
collider: collider1,
|
369
|
+
colliderObject: collider1State === null || collider1State === void 0 ? void 0 : collider1State.object,
|
370
|
+
rigidBodyObject: rigidBody1State === null || rigidBody1State === void 0 ? void 0 : rigidBody1State.object,
|
610
371
|
manifold,
|
611
372
|
flipped
|
612
373
|
});
|
613
374
|
/* Collider events */
|
614
375
|
|
615
376
|
collider1Events === null || collider1Events === void 0 ? void 0 : (_collider1Events$onCo = collider1Events.onCollisionEnter) === null || _collider1Events$onCo === void 0 ? void 0 : _collider1Events$onCo.call(collider1Events, {
|
616
|
-
|
377
|
+
rigidBody: rigidBody2,
|
617
378
|
collider: collider2,
|
379
|
+
colliderObject: collider2State === null || collider2State === void 0 ? void 0 : collider2State.object,
|
380
|
+
rigidBodyObject: rigidBody2State === null || rigidBody2State === void 0 ? void 0 : rigidBody2State.object,
|
618
381
|
manifold,
|
619
382
|
flipped
|
620
383
|
});
|
621
384
|
collider2Events === null || collider2Events === void 0 ? void 0 : (_collider2Events$onCo = collider2Events.onCollisionEnter) === null || _collider2Events$onCo === void 0 ? void 0 : _collider2Events$onCo.call(collider2Events, {
|
622
|
-
|
385
|
+
rigidBody: rigidBody1,
|
623
386
|
collider: collider1,
|
387
|
+
colliderObject: collider1State === null || collider1State === void 0 ? void 0 : collider1State.object,
|
388
|
+
rigidBodyObject: rigidBody1State === null || rigidBody1State === void 0 ? void 0 : rigidBody1State.object,
|
624
389
|
manifold,
|
625
390
|
flipped
|
626
391
|
});
|
627
392
|
});
|
628
393
|
} else {
|
629
|
-
var _rigidBody1Events$onC2,
|
394
|
+
var _rigidBody1Events$onC2, _rigidBody2Events$onC2, _collider1Events$onCo2, _collider2Events$onCo2;
|
630
395
|
|
631
396
|
rigidBody1Events === null || rigidBody1Events === void 0 ? void 0 : (_rigidBody1Events$onC2 = rigidBody1Events.onCollisionExit) === null || _rigidBody1Events$onC2 === void 0 ? void 0 : _rigidBody1Events$onC2.call(rigidBody1Events, {
|
632
|
-
|
397
|
+
rigidBody: rigidBody2,
|
633
398
|
collider: collider2
|
634
399
|
});
|
635
|
-
|
636
|
-
|
400
|
+
rigidBody2Events === null || rigidBody2Events === void 0 ? void 0 : (_rigidBody2Events$onC2 = rigidBody2Events.onCollisionExit) === null || _rigidBody2Events$onC2 === void 0 ? void 0 : _rigidBody2Events$onC2.call(rigidBody2Events, {
|
401
|
+
rigidBody: rigidBody1,
|
637
402
|
collider: collider1
|
638
403
|
});
|
639
404
|
collider1Events === null || collider1Events === void 0 ? void 0 : (_collider1Events$onCo2 = collider1Events.onCollisionExit) === null || _collider1Events$onCo2 === void 0 ? void 0 : _collider1Events$onCo2.call(collider1Events, {
|
640
|
-
|
405
|
+
rigidBody: rigidBody2,
|
641
406
|
collider: collider2
|
642
407
|
});
|
643
408
|
collider2Events === null || collider2Events === void 0 ? void 0 : (_collider2Events$onCo2 = collider2Events.onCollisionExit) === null || _collider2Events$onCo2 === void 0 ? void 0 : _collider2Events$onCo2.call(collider2Events, {
|
644
|
-
|
409
|
+
rigidBody: rigidBody1,
|
410
|
+
collider: collider1
|
411
|
+
});
|
412
|
+
} // Sensor Intersections
|
413
|
+
|
414
|
+
|
415
|
+
if (started) {
|
416
|
+
if (world.intersectionPair(collider1, collider2)) {
|
417
|
+
var _rigidBody1Events$onI, _rigidBody2Events$onI, _collider1Events$onIn, _collider2Events$onIn;
|
418
|
+
|
419
|
+
rigidBody1Events === null || rigidBody1Events === void 0 ? void 0 : (_rigidBody1Events$onI = rigidBody1Events.onIntersectionEnter) === null || _rigidBody1Events$onI === void 0 ? void 0 : _rigidBody1Events$onI.call(rigidBody1Events, {
|
420
|
+
rigidBody: rigidBody2,
|
421
|
+
collider: collider2,
|
422
|
+
colliderObject: collider2State === null || collider2State === void 0 ? void 0 : collider2State.object,
|
423
|
+
rigidBodyObject: rigidBody2State === null || rigidBody2State === void 0 ? void 0 : rigidBody2State.object
|
424
|
+
});
|
425
|
+
rigidBody2Events === null || rigidBody2Events === void 0 ? void 0 : (_rigidBody2Events$onI = rigidBody2Events.onIntersectionEnter) === null || _rigidBody2Events$onI === void 0 ? void 0 : _rigidBody2Events$onI.call(rigidBody2Events, {
|
426
|
+
rigidBody: rigidBody1,
|
427
|
+
collider: collider1,
|
428
|
+
colliderObject: collider1State === null || collider1State === void 0 ? void 0 : collider1State.object,
|
429
|
+
rigidBodyObject: rigidBody1State === null || rigidBody1State === void 0 ? void 0 : rigidBody1State.object
|
430
|
+
});
|
431
|
+
collider1Events === null || collider1Events === void 0 ? void 0 : (_collider1Events$onIn = collider1Events.onIntersectionEnter) === null || _collider1Events$onIn === void 0 ? void 0 : _collider1Events$onIn.call(collider1Events, {
|
432
|
+
rigidBody: rigidBody2,
|
433
|
+
collider: collider2,
|
434
|
+
colliderObject: collider2State === null || collider2State === void 0 ? void 0 : collider2State.object,
|
435
|
+
rigidBodyObject: rigidBody2State === null || rigidBody2State === void 0 ? void 0 : rigidBody2State.object
|
436
|
+
});
|
437
|
+
collider2Events === null || collider2Events === void 0 ? void 0 : (_collider2Events$onIn = collider2Events.onIntersectionEnter) === null || _collider2Events$onIn === void 0 ? void 0 : _collider2Events$onIn.call(collider2Events, {
|
438
|
+
rigidBody: rigidBody1,
|
439
|
+
collider: collider1,
|
440
|
+
colliderObject: collider1State === null || collider1State === void 0 ? void 0 : collider1State.object,
|
441
|
+
rigidBodyObject: rigidBody1State === null || rigidBody1State === void 0 ? void 0 : rigidBody1State.object
|
442
|
+
});
|
443
|
+
}
|
444
|
+
} else {
|
445
|
+
var _rigidBody1Events$onI2, _rigidBody2Events$onI2, _collider1Events$onIn2, _collider2Events$onIn2;
|
446
|
+
|
447
|
+
rigidBody1Events === null || rigidBody1Events === void 0 ? void 0 : (_rigidBody1Events$onI2 = rigidBody1Events.onIntersectionExit) === null || _rigidBody1Events$onI2 === void 0 ? void 0 : _rigidBody1Events$onI2.call(rigidBody1Events, {
|
448
|
+
rigidBody: rigidBody2,
|
449
|
+
collider: collider2
|
450
|
+
});
|
451
|
+
rigidBody2Events === null || rigidBody2Events === void 0 ? void 0 : (_rigidBody2Events$onI2 = rigidBody2Events.onIntersectionExit) === null || _rigidBody2Events$onI2 === void 0 ? void 0 : _rigidBody2Events$onI2.call(rigidBody2Events, {
|
452
|
+
rigidBody: rigidBody1,
|
453
|
+
collider: collider1
|
454
|
+
});
|
455
|
+
collider1Events === null || collider1Events === void 0 ? void 0 : (_collider1Events$onIn2 = collider1Events.onIntersectionExit) === null || _collider1Events$onIn2 === void 0 ? void 0 : _collider1Events$onIn2.call(collider1Events, {
|
456
|
+
rigidBody: rigidBody2,
|
457
|
+
collider: collider2
|
458
|
+
});
|
459
|
+
collider2Events === null || collider2Events === void 0 ? void 0 : (_collider2Events$onIn2 = collider2Events.onIntersectionExit) === null || _collider2Events$onIn2 === void 0 ? void 0 : _collider2Events$onIn2.call(collider2Events, {
|
460
|
+
rigidBody: rigidBody1,
|
645
461
|
collider: collider1
|
646
462
|
});
|
647
463
|
}
|
@@ -656,6 +472,7 @@ const Physics = ({
|
|
656
472
|
gravity: _gravity
|
657
473
|
},
|
658
474
|
rigidBodyStates,
|
475
|
+
colliderStates,
|
659
476
|
rigidBodyEvents,
|
660
477
|
colliderEvents,
|
661
478
|
isPaused
|
@@ -758,144 +575,466 @@ function _objectSpread2(target) {
|
|
758
575
|
return target;
|
759
576
|
}
|
760
577
|
|
761
|
-
const
|
762
|
-
|
578
|
+
const rigidBodyDescFromOptions = options => {
|
579
|
+
const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
|
580
|
+
const desc = new rapier3dCompat.RigidBodyDesc(type);
|
581
|
+
return desc;
|
763
582
|
};
|
764
|
-
const
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
}
|
780
|
-
|
781
|
-
|
782
|
-
|
583
|
+
const createRigidBodyState = ({
|
584
|
+
rigidBody,
|
585
|
+
object,
|
586
|
+
setMatrix,
|
587
|
+
getMatrix,
|
588
|
+
worldScale
|
589
|
+
}) => {
|
590
|
+
object.updateWorldMatrix(true, false);
|
591
|
+
const invertedWorldMatrix = object.parent.matrixWorld.clone().invert();
|
592
|
+
return {
|
593
|
+
object,
|
594
|
+
rigidBody,
|
595
|
+
invertedWorldMatrix,
|
596
|
+
setMatrix: setMatrix ? setMatrix : matrix => {
|
597
|
+
object.matrix.copy(matrix);
|
598
|
+
},
|
599
|
+
getMatrix: getMatrix ? getMatrix : matrix => matrix.copy(object.matrix),
|
600
|
+
scale: worldScale || object.getWorldScale(_scale).clone(),
|
601
|
+
isSleeping: false
|
602
|
+
};
|
603
|
+
};
|
604
|
+
const mutableRigidBodyOptions = {
|
605
|
+
gravityScale: (rb, value) => {
|
606
|
+
rb.setGravityScale(value, true);
|
607
|
+
},
|
608
|
+
linearDamping: (rb, value) => {
|
609
|
+
rb.setLinearDamping(value);
|
610
|
+
},
|
611
|
+
angularDamping: (rb, value) => {
|
612
|
+
rb.setAngularDamping(value);
|
613
|
+
},
|
614
|
+
enabledRotations: (rb, [x, y, z]) => {
|
615
|
+
rb.setEnabledRotations(x, y, z, true);
|
616
|
+
},
|
617
|
+
enabledTranslations: (rb, [x, y, z]) => {
|
618
|
+
rb.setEnabledTranslations(x, y, z, true);
|
619
|
+
},
|
620
|
+
angularVelocity: (rb, [x, y, z]) => {
|
621
|
+
rb.setAngvel({
|
622
|
+
x,
|
623
|
+
y,
|
624
|
+
z
|
625
|
+
}, true);
|
626
|
+
},
|
627
|
+
linearVelocity: (rb, [x, y, z]) => {
|
628
|
+
rb.setLinvel({
|
629
|
+
x,
|
630
|
+
y,
|
631
|
+
z
|
632
|
+
}, true);
|
633
|
+
},
|
634
|
+
ccd: (rb, value) => {
|
635
|
+
rb.enableCcd(value);
|
636
|
+
}
|
637
|
+
};
|
638
|
+
const mutableRigidBodyOptionKeys = Object.keys(mutableRigidBodyOptions);
|
639
|
+
const setRigidBodyOptions = (rigidBody, options, states, updateTranslations = true) => {
|
640
|
+
if (!rigidBody) {
|
641
|
+
return;
|
642
|
+
}
|
783
643
|
|
784
|
-
|
785
|
-
var _ref$current$parent, _ref, _options$colliders;
|
644
|
+
const state = states.get(rigidBody.handle);
|
786
645
|
|
787
|
-
|
788
|
-
|
646
|
+
if (state) {
|
647
|
+
if (updateTranslations) {
|
648
|
+
state.object.updateWorldMatrix(true, false);
|
789
649
|
|
790
|
-
|
791
|
-
ref.current = new three.Object3D();
|
792
|
-
} // isSleeping used for onSleep and onWake events
|
650
|
+
_matrix4.copy(state.object.matrixWorld).decompose(_position, _rotation, _scale);
|
793
651
|
|
652
|
+
rigidBody.setTranslation(_position, false);
|
653
|
+
rigidBody.setRotation(_rotation, false);
|
654
|
+
}
|
794
655
|
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
const scale = ((_ref$current$parent = ref.current.parent) === null || _ref$current$parent === void 0 ? void 0 : _ref$current$parent.getWorldScale(new three.Vector3())) || {
|
800
|
-
x: 1,
|
801
|
-
y: 1,
|
802
|
-
z: 1
|
803
|
-
}; // Transforms from options
|
804
|
-
|
805
|
-
const [x, y, z] = (options === null || options === void 0 ? void 0 : options.position) || [0, 0, 0];
|
806
|
-
const [rx, ry, rz] = (options === null || options === void 0 ? void 0 : options.rotation) || [0, 0, 0]; // Set initial transforms based on world transforms
|
807
|
-
|
808
|
-
rigidBody.setTranslation({
|
809
|
-
x: worldPosition.x + x * scale.x,
|
810
|
-
y: worldPosition.y + y * scale.y,
|
811
|
-
z: worldPosition.z + z * scale.z
|
812
|
-
}, false);
|
813
|
-
const rotation = vector3ToQuaternion(new three.Vector3(rx, ry, rz)).multiply(worldRotation);
|
814
|
-
rigidBody.setRotation({
|
815
|
-
x: rotation.x,
|
816
|
-
y: rotation.y,
|
817
|
-
z: rotation.z,
|
818
|
-
w: rotation.w
|
819
|
-
}, false);
|
820
|
-
rigidBody.resetForces(false);
|
821
|
-
rigidBody.resetTorques(false);
|
822
|
-
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;
|
823
|
-
const autoColliders = colliderSetting !== false ? createCollidersFromChildren({
|
824
|
-
object: ref.current,
|
825
|
-
rigidBody,
|
826
|
-
options: _objectSpread2(_objectSpread2({}, options), {}, {
|
827
|
-
colliders: colliderSetting
|
828
|
-
}),
|
829
|
-
world,
|
830
|
-
ignoreMeshColliders: true
|
831
|
-
}) : [];
|
832
|
-
rigidBodyStates.set(rigidBody.handle, {
|
833
|
-
mesh: ref.current,
|
834
|
-
invertedMatrixWorld: ref.current.parent.matrixWorld.clone().invert(),
|
835
|
-
isSleeping: false,
|
836
|
-
worldScale: ref.current.getWorldScale(_vector3).clone(),
|
837
|
-
setMatrix: mat => ref.current.matrix.copy(mat),
|
838
|
-
getMatrix: () => ref.current.matrix
|
656
|
+
mutableRigidBodyOptionKeys.forEach(key => {
|
657
|
+
if (key in options) {
|
658
|
+
mutableRigidBodyOptions[key](rigidBody, options[key]);
|
659
|
+
}
|
839
660
|
});
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
autoColliders.forEach(collider => world.removeCollider(collider));
|
844
|
-
rigidBodyRef.current = undefined;
|
845
|
-
rigidBodyStates.delete(rigidBody.handle);
|
846
|
-
};
|
847
|
-
}, []); // Events
|
848
|
-
|
661
|
+
}
|
662
|
+
};
|
663
|
+
const useUpdateRigidBodyOptions = (rigidBodyRef, props, states, updateTranslations = true) => {
|
849
664
|
React.useEffect(() => {
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
}
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
}, [options.onCollisionEnter, options.onCollisionExit]);
|
861
|
-
const api = React.useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
|
862
|
-
return [ref, api];
|
863
|
-
}; // Joints
|
864
|
-
|
865
|
-
const useImpulseJoint = (body1, body2, params) => {
|
665
|
+
if ("length" in rigidBodyRef.current) {
|
666
|
+
rigidBodyRef.current.forEach(rigidBody => {
|
667
|
+
setRigidBodyOptions(rigidBody, props, states, updateTranslations);
|
668
|
+
});
|
669
|
+
} else {
|
670
|
+
setRigidBodyOptions(rigidBodyRef.current, props, states, updateTranslations);
|
671
|
+
}
|
672
|
+
}, [props]);
|
673
|
+
};
|
674
|
+
const useRigidBodyEvents = (rigidBodyRef, props, events) => {
|
866
675
|
const {
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
676
|
+
onWake,
|
677
|
+
onSleep,
|
678
|
+
onCollisionEnter,
|
679
|
+
onCollisionExit,
|
680
|
+
onIntersectionEnter,
|
681
|
+
onIntersectionExit
|
682
|
+
} = props;
|
683
|
+
const eventHandlers = {
|
684
|
+
onWake,
|
685
|
+
onSleep,
|
686
|
+
onCollisionEnter,
|
687
|
+
onCollisionExit,
|
688
|
+
onIntersectionEnter,
|
689
|
+
onIntersectionExit
|
690
|
+
};
|
691
|
+
React.useEffect(() => {
|
692
|
+
if ("length" in rigidBodyRef.current) {
|
693
|
+
rigidBodyRef.current.forEach(rigidBody => {
|
694
|
+
events.set(rigidBody.handle, eventHandlers);
|
695
|
+
});
|
696
|
+
} else {
|
697
|
+
events.set(rigidBodyRef.current.handle, eventHandlers);
|
881
698
|
}
|
882
699
|
|
883
|
-
return jointRef.current;
|
884
|
-
});
|
885
|
-
React.useEffect(() => {
|
886
|
-
const joint = getJointRef.current();
|
887
700
|
return () => {
|
888
|
-
if (
|
889
|
-
|
890
|
-
|
701
|
+
if ("length" in rigidBodyRef.current) {
|
702
|
+
rigidBodyRef.current.forEach(rigidBody => {
|
703
|
+
events.delete(rigidBody.handle);
|
704
|
+
});
|
705
|
+
} else {
|
706
|
+
events.delete(rigidBodyRef.current.handle);
|
891
707
|
}
|
892
708
|
};
|
893
|
-
}, []);
|
894
|
-
const api = React.useMemo(() => createJointApi(getJointRef), []);
|
895
|
-
return api;
|
709
|
+
}, [onWake, onSleep, onCollisionEnter, onCollisionExit]);
|
896
710
|
};
|
897
|
-
|
898
|
-
|
711
|
+
|
712
|
+
const scaleColliderArgs = (shape, args, scale) => {
|
713
|
+
const newArgs = args.slice(); // Heightfield uses a vector
|
714
|
+
|
715
|
+
if (shape === "heightfield") {
|
716
|
+
const s = newArgs[3];
|
717
|
+
s.x *= scale.x;
|
718
|
+
s.x *= scale.y;
|
719
|
+
s.x *= scale.z;
|
720
|
+
return newArgs;
|
721
|
+
} // Trimesh and convex scale the vertices
|
722
|
+
|
723
|
+
|
724
|
+
if (shape === "trimesh" || shape === "convexHull") {
|
725
|
+
newArgs[0] = scaleVertices(newArgs[0], scale);
|
726
|
+
return newArgs;
|
727
|
+
} // Prepfill with some extra
|
728
|
+
|
729
|
+
|
730
|
+
const scaleArray = [scale.x, scale.y, scale.z, scale.x, scale.x];
|
731
|
+
return newArgs.map((arg, index) => scaleArray[index] * arg);
|
732
|
+
};
|
733
|
+
const createColliderFromOptions = (options, world, scale, rigidBody) => {
|
734
|
+
const scaledArgs = scaleColliderArgs(options.shape, options.args, scale); // @ts-ignore
|
735
|
+
|
736
|
+
const desc = rapier3dCompat.ColliderDesc[options.shape](...scaledArgs);
|
737
|
+
return world.createCollider(desc, rigidBody);
|
738
|
+
};
|
739
|
+
const mutableColliderOptions = {
|
740
|
+
sensor: (collider, value) => {
|
741
|
+
collider.setSensor(value);
|
742
|
+
},
|
743
|
+
collisionGroups: (collider, value) => {
|
744
|
+
collider.setCollisionGroups(value);
|
745
|
+
},
|
746
|
+
solverGroups: (collider, value) => {
|
747
|
+
collider.setSolverGroups(value);
|
748
|
+
},
|
749
|
+
friction: (collider, value) => {
|
750
|
+
collider.setFriction(value);
|
751
|
+
},
|
752
|
+
restitution: (collider, value) => {
|
753
|
+
collider.setRestitution(value);
|
754
|
+
},
|
755
|
+
density: (collider, value) => {
|
756
|
+
collider.setDensity(value);
|
757
|
+
},
|
758
|
+
mass: (collider, value) => {
|
759
|
+
collider.setMass(value);
|
760
|
+
}
|
761
|
+
};
|
762
|
+
const mutableColliderOptionKeys = Object.keys(mutableColliderOptions);
|
763
|
+
const setColliderOptions = (collider, options, states) => {
|
764
|
+
const state = states.get(collider.handle);
|
765
|
+
|
766
|
+
if (state) {
|
767
|
+
// Update collider position based on the object's position
|
768
|
+
const parentWorldScale = state.object.parent.getWorldScale(_vector3);
|
769
|
+
state.object.updateWorldMatrix(true, false);
|
770
|
+
|
771
|
+
_matrix4.copy(state.object.matrixWorld).premultiply(state.worldParent.matrixWorld.clone().invert()).decompose(_position, _rotation, _scale);
|
772
|
+
|
773
|
+
collider.setTranslationWrtParent({
|
774
|
+
x: _position.x * parentWorldScale.x,
|
775
|
+
y: _position.y * parentWorldScale.y,
|
776
|
+
z: _position.z * parentWorldScale.z
|
777
|
+
});
|
778
|
+
collider.setRotationWrtParent(_rotation);
|
779
|
+
mutableColliderOptionKeys.forEach(key => {
|
780
|
+
if (key in options) {
|
781
|
+
mutableColliderOptions[key](collider, options[key]);
|
782
|
+
}
|
783
|
+
});
|
784
|
+
}
|
785
|
+
};
|
786
|
+
const useUpdateColliderOptions = (collidersRef, props, states) => {
|
787
|
+
React.useEffect(() => {
|
788
|
+
collidersRef.current.forEach(collider => {
|
789
|
+
setColliderOptions(collider, props, states);
|
790
|
+
});
|
791
|
+
}, [props]);
|
792
|
+
};
|
793
|
+
|
794
|
+
const isChildOfMeshCollider = child => {
|
795
|
+
let flag = false;
|
796
|
+
child.traverseAncestors(a => {
|
797
|
+
if (a.userData.r3RapierType === "MeshCollider") flag = true;
|
798
|
+
});
|
799
|
+
return flag;
|
800
|
+
};
|
801
|
+
|
802
|
+
const createColliderState = (collider, object, rigidBodyObject) => {
|
803
|
+
return {
|
804
|
+
collider,
|
805
|
+
worldParent: rigidBodyObject || object.parent,
|
806
|
+
object
|
807
|
+
};
|
808
|
+
};
|
809
|
+
const autoColliderMap = {
|
810
|
+
cuboid: "cuboid",
|
811
|
+
ball: "ball",
|
812
|
+
hull: "convexHull",
|
813
|
+
trimesh: "trimesh"
|
814
|
+
};
|
815
|
+
const createColliderPropsFromChildren = ({
|
816
|
+
object,
|
817
|
+
ignoreMeshColliders: _ignoreMeshColliders = true,
|
818
|
+
options
|
819
|
+
}) => {
|
820
|
+
const colliderProps = [];
|
821
|
+
object.updateWorldMatrix(true, false);
|
822
|
+
const invertedParentMatrixWorld = object.matrixWorld.clone().invert();
|
823
|
+
object.traverseVisible(child => {
|
824
|
+
if ("isMesh" in child) {
|
825
|
+
if (_ignoreMeshColliders && isChildOfMeshCollider(child)) return;
|
826
|
+
const worldScale = child.getWorldScale(_scale);
|
827
|
+
const shape = autoColliderMap[options.colliders || "cuboid"];
|
828
|
+
child.updateWorldMatrix(true, false);
|
829
|
+
|
830
|
+
_matrix4.copy(child.matrixWorld).premultiply(invertedParentMatrixWorld).decompose(_position, _rotation, _scale);
|
831
|
+
|
832
|
+
const rotationEuler = new three.Euler().setFromQuaternion(_rotation, "XYZ");
|
833
|
+
const {
|
834
|
+
geometry
|
835
|
+
} = child;
|
836
|
+
const {
|
837
|
+
args,
|
838
|
+
offset
|
839
|
+
} = getColliderArgsFromGeometry(geometry, options.colliders || "cuboid");
|
840
|
+
colliderProps.push(_objectSpread2(_objectSpread2({}, options), {}, {
|
841
|
+
args: args,
|
842
|
+
shape: shape,
|
843
|
+
rotation: [rotationEuler.x, rotationEuler.y, rotationEuler.z],
|
844
|
+
position: [_position.x + offset.x * worldScale.x, _position.y + offset.y * worldScale.y, _position.z + offset.z * worldScale.z],
|
845
|
+
scale: [worldScale.x, worldScale.y, worldScale.z]
|
846
|
+
}));
|
847
|
+
}
|
848
|
+
});
|
849
|
+
return colliderProps;
|
850
|
+
};
|
851
|
+
const getColliderArgsFromGeometry = (geometry, colliders) => {
|
852
|
+
switch (colliders) {
|
853
|
+
case "cuboid":
|
854
|
+
{
|
855
|
+
geometry.computeBoundingBox();
|
856
|
+
const {
|
857
|
+
boundingBox
|
858
|
+
} = geometry;
|
859
|
+
const size = boundingBox.getSize(new three.Vector3());
|
860
|
+
return {
|
861
|
+
args: [size.x / 2, size.y / 2, size.z / 2],
|
862
|
+
offset: boundingBox.getCenter(new three.Vector3())
|
863
|
+
};
|
864
|
+
}
|
865
|
+
|
866
|
+
case "ball":
|
867
|
+
{
|
868
|
+
geometry.computeBoundingSphere();
|
869
|
+
const {
|
870
|
+
boundingSphere
|
871
|
+
} = geometry;
|
872
|
+
const radius = boundingSphere.radius;
|
873
|
+
return {
|
874
|
+
args: [radius],
|
875
|
+
offset: boundingSphere.center
|
876
|
+
};
|
877
|
+
}
|
878
|
+
|
879
|
+
case "trimesh":
|
880
|
+
{
|
881
|
+
var _clonedGeometry$index;
|
882
|
+
|
883
|
+
const clonedGeometry = geometry.index ? geometry.clone() : threeStdlib.mergeVertices(geometry);
|
884
|
+
return {
|
885
|
+
args: [clonedGeometry.attributes.position.array, (_clonedGeometry$index = clonedGeometry.index) === null || _clonedGeometry$index === void 0 ? void 0 : _clonedGeometry$index.array],
|
886
|
+
offset: new three.Vector3()
|
887
|
+
};
|
888
|
+
}
|
889
|
+
|
890
|
+
case "hull":
|
891
|
+
{
|
892
|
+
const g = geometry.clone();
|
893
|
+
return {
|
894
|
+
args: [g.attributes.position.array],
|
895
|
+
offset: new three.Vector3()
|
896
|
+
};
|
897
|
+
}
|
898
|
+
}
|
899
|
+
|
900
|
+
return {
|
901
|
+
args: [],
|
902
|
+
offset: new three.Vector3()
|
903
|
+
};
|
904
|
+
};
|
905
|
+
const useColliderEvents = (collidersRef, props, events) => {
|
906
|
+
const {
|
907
|
+
onCollisionEnter,
|
908
|
+
onCollisionExit,
|
909
|
+
onIntersectionEnter,
|
910
|
+
onIntersectionExit
|
911
|
+
} = props;
|
912
|
+
React.useEffect(() => {
|
913
|
+
var _collidersRef$current;
|
914
|
+
|
915
|
+
(_collidersRef$current = collidersRef.current) === null || _collidersRef$current === void 0 ? void 0 : _collidersRef$current.forEach(collider => {
|
916
|
+
if (onCollisionEnter || onCollisionExit || onIntersectionEnter || onIntersectionExit) {
|
917
|
+
collider.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
|
918
|
+
}
|
919
|
+
|
920
|
+
events.set(collider.handle, {
|
921
|
+
onCollisionEnter,
|
922
|
+
onCollisionExit,
|
923
|
+
onIntersectionEnter,
|
924
|
+
onIntersectionExit
|
925
|
+
});
|
926
|
+
});
|
927
|
+
return () => {
|
928
|
+
var _collidersRef$current2;
|
929
|
+
|
930
|
+
(_collidersRef$current2 = collidersRef.current) === null || _collidersRef$current2 === void 0 ? void 0 : _collidersRef$current2.forEach(collider => events.delete(collider.handle));
|
931
|
+
};
|
932
|
+
}, [onCollisionEnter, onCollisionExit]);
|
933
|
+
};
|
934
|
+
|
935
|
+
const useRapier = () => {
|
936
|
+
return React.useContext(RapierContext);
|
937
|
+
};
|
938
|
+
const useChildColliderProps = (ref, options, ignoreMeshColliders = true) => {
|
939
|
+
const [colliderProps, setColliderProps] = React.useState([]);
|
940
|
+
React.useEffect(() => {
|
941
|
+
const object = ref.current;
|
942
|
+
|
943
|
+
if (object && options.colliders !== false) {
|
944
|
+
setColliderProps(createColliderPropsFromChildren({
|
945
|
+
object: ref.current,
|
946
|
+
options,
|
947
|
+
ignoreMeshColliders
|
948
|
+
}));
|
949
|
+
}
|
950
|
+
}, [options]);
|
951
|
+
return colliderProps;
|
952
|
+
};
|
953
|
+
const useRigidBody = (options = {}) => {
|
954
|
+
const {
|
955
|
+
world,
|
956
|
+
rigidBodyStates,
|
957
|
+
physicsOptions,
|
958
|
+
rigidBodyEvents
|
959
|
+
} = useRapier();
|
960
|
+
const ref = React.useRef();
|
961
|
+
const mergedOptions = React.useMemo(() => {
|
962
|
+
return _objectSpread2(_objectSpread2(_objectSpread2({}, physicsOptions), options), {}, {
|
963
|
+
children: undefined
|
964
|
+
});
|
965
|
+
}, [physicsOptions, options]);
|
966
|
+
const childColliderProps = useChildColliderProps(ref, mergedOptions); // Create rigidbody
|
967
|
+
|
968
|
+
const rigidBodyRef = React.useRef();
|
969
|
+
const getRigidBodyRef = React.useRef(() => {
|
970
|
+
if (!rigidBodyRef.current) {
|
971
|
+
const desc = rigidBodyDescFromOptions(options);
|
972
|
+
const rigidBody = world.createRigidBody(desc);
|
973
|
+
rigidBodyRef.current = world.getRigidBody(rigidBody.handle);
|
974
|
+
}
|
975
|
+
|
976
|
+
return rigidBodyRef.current;
|
977
|
+
}); // Setup
|
978
|
+
|
979
|
+
React.useEffect(() => {
|
980
|
+
const rigidBody = getRigidBodyRef.current();
|
981
|
+
rigidBodyRef.current = rigidBody;
|
982
|
+
|
983
|
+
if (!ref.current) {
|
984
|
+
ref.current = new three.Object3D();
|
985
|
+
} // isSleeping used for onSleep and onWake events
|
986
|
+
|
987
|
+
|
988
|
+
ref.current.userData.isSleeping = false;
|
989
|
+
rigidBodyStates.set(rigidBody.handle, createRigidBodyState({
|
990
|
+
rigidBody,
|
991
|
+
object: ref.current
|
992
|
+
}));
|
993
|
+
return () => {
|
994
|
+
world.removeRigidBody(rigidBody);
|
995
|
+
rigidBodyStates.delete(rigidBody.handle);
|
996
|
+
};
|
997
|
+
}, []);
|
998
|
+
useUpdateRigidBodyOptions(rigidBodyRef, mergedOptions, rigidBodyStates);
|
999
|
+
useRigidBodyEvents(rigidBodyRef, mergedOptions, rigidBodyEvents);
|
1000
|
+
const api = React.useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
|
1001
|
+
return [ref, api, childColliderProps];
|
1002
|
+
}; // Joints
|
1003
|
+
|
1004
|
+
const useImpulseJoint = (body1, body2, params) => {
|
1005
|
+
const {
|
1006
|
+
world
|
1007
|
+
} = useRapier();
|
1008
|
+
const jointRef = React.useRef();
|
1009
|
+
const getJointRef = React.useRef(() => {
|
1010
|
+
if (!jointRef.current) {
|
1011
|
+
let rb1;
|
1012
|
+
let rb2;
|
1013
|
+
|
1014
|
+
if ("current" in body1 && body1.current && "current" in body2 && body2.current) {
|
1015
|
+
rb1 = world.getRigidBody(body1.current.handle);
|
1016
|
+
rb2 = world.getRigidBody(body2.current.handle);
|
1017
|
+
const newJoint = world.createImpulseJoint(params, rb1, rb2);
|
1018
|
+
jointRef.current = newJoint;
|
1019
|
+
}
|
1020
|
+
}
|
1021
|
+
|
1022
|
+
return jointRef.current;
|
1023
|
+
});
|
1024
|
+
React.useEffect(() => {
|
1025
|
+
const joint = getJointRef.current();
|
1026
|
+
return () => {
|
1027
|
+
if (joint) {
|
1028
|
+
world.removeImpulseJoint(joint);
|
1029
|
+
jointRef.current = undefined;
|
1030
|
+
}
|
1031
|
+
};
|
1032
|
+
}, []);
|
1033
|
+
const api = React.useMemo(() => createJointApi(getJointRef), []);
|
1034
|
+
return api;
|
1035
|
+
};
|
1036
|
+
/**
|
1037
|
+
*
|
899
1038
|
* A fixed joint ensures that two rigid-bodies don't move relative to each other.
|
900
1039
|
* Fixed joints are characterized by one local frame (represented by an isometry) on each rigid-body.
|
901
1040
|
* The fixed-joint makes these frames coincide in world-space.
|
@@ -949,80 +1088,173 @@ const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
|
949
1088
|
return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
|
950
1089
|
};
|
951
1090
|
|
952
|
-
|
953
|
-
|
954
|
-
const
|
955
|
-
|
1091
|
+
// Colliders
|
1092
|
+
const AnyCollider = /*#__PURE__*/React.memo(props => {
|
1093
|
+
const {
|
1094
|
+
children,
|
1095
|
+
position,
|
1096
|
+
rotation,
|
1097
|
+
quaternion,
|
1098
|
+
scale
|
1099
|
+
} = props;
|
1100
|
+
const {
|
1101
|
+
world,
|
1102
|
+
colliderEvents,
|
1103
|
+
colliderStates
|
1104
|
+
} = useRapier();
|
1105
|
+
const rigidBodyContext = useRigidBodyContext();
|
1106
|
+
const ref = React.useRef(null);
|
1107
|
+
const collidersRef = React.useRef([]);
|
1108
|
+
React.useEffect(() => {
|
1109
|
+
const object = ref.current;
|
1110
|
+
const worldScale = object.getWorldScale(new three.Vector3());
|
1111
|
+
const colliders = []; // If this is an InstancedRigidBody api
|
956
1112
|
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
1113
|
+
if (rigidBodyContext && "at" in rigidBodyContext.api) {
|
1114
|
+
rigidBodyContext.api.forEach((body, index) => {
|
1115
|
+
var _rigidBodyContext$opt, _rigidBodyContext$opt2;
|
1116
|
+
|
1117
|
+
let instanceScale = worldScale;
|
962
1118
|
|
963
|
-
|
1119
|
+
if ("scales" in rigidBodyContext.options && rigidBodyContext !== null && rigidBodyContext !== void 0 && (_rigidBodyContext$opt = rigidBodyContext.options) !== null && _rigidBodyContext$opt !== void 0 && (_rigidBodyContext$opt2 = _rigidBodyContext$opt.scales) !== null && _rigidBodyContext$opt2 !== void 0 && _rigidBodyContext$opt2[index]) {
|
1120
|
+
instanceScale = instanceScale.clone().multiply(vectorArrayToVector3(rigidBodyContext.options.scales[index]));
|
1121
|
+
}
|
964
1122
|
|
965
|
-
|
1123
|
+
const collider = createColliderFromOptions(props, world, instanceScale, body.raw());
|
1124
|
+
colliderStates.set(collider.handle, createColliderState(collider, object, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
|
1125
|
+
colliders.push(collider);
|
1126
|
+
});
|
1127
|
+
} else {
|
1128
|
+
const collider = createColliderFromOptions(props, world, worldScale, rigidBodyContext && (rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.api).raw());
|
1129
|
+
colliderStates.set(collider.handle, createColliderState(collider, object, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.ref.current));
|
1130
|
+
colliders.push(collider);
|
1131
|
+
}
|
966
1132
|
|
1133
|
+
collidersRef.current = colliders;
|
1134
|
+
return () => {
|
1135
|
+
colliders.forEach(collider => {
|
1136
|
+
world.removeCollider(collider);
|
1137
|
+
});
|
1138
|
+
};
|
1139
|
+
}, []);
|
1140
|
+
useUpdateColliderOptions(collidersRef, props, colliderStates);
|
1141
|
+
useColliderEvents(collidersRef, props, colliderEvents);
|
1142
|
+
return /*#__PURE__*/React__default["default"].createElement("object3D", {
|
1143
|
+
position: position,
|
1144
|
+
rotation: rotation,
|
1145
|
+
quaternion: quaternion,
|
1146
|
+
scale: scale,
|
1147
|
+
ref: ref
|
1148
|
+
}, children);
|
1149
|
+
});
|
1150
|
+
const CuboidCollider = props => {
|
1151
|
+
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1152
|
+
shape: "cuboid"
|
1153
|
+
}));
|
1154
|
+
};
|
1155
|
+
const RoundCuboidCollider = props => {
|
1156
|
+
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1157
|
+
shape: "roundCuboid"
|
1158
|
+
}));
|
1159
|
+
};
|
1160
|
+
const BallCollider = props => {
|
1161
|
+
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1162
|
+
shape: "ball"
|
1163
|
+
}));
|
1164
|
+
};
|
1165
|
+
const CapsuleCollider = props => {
|
1166
|
+
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1167
|
+
shape: "capsule"
|
1168
|
+
}));
|
1169
|
+
};
|
1170
|
+
const HeightfieldCollider = props => {
|
1171
|
+
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1172
|
+
shape: "heightfield"
|
1173
|
+
}));
|
1174
|
+
};
|
1175
|
+
const TrimeshCollider = props => {
|
1176
|
+
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1177
|
+
shape: "trimesh"
|
1178
|
+
}));
|
1179
|
+
};
|
1180
|
+
const ConeCollider = props => {
|
1181
|
+
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1182
|
+
shape: "cone"
|
1183
|
+
}));
|
1184
|
+
};
|
1185
|
+
const CylinderCollider = props => {
|
1186
|
+
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1187
|
+
shape: "cylinder"
|
1188
|
+
}));
|
1189
|
+
};
|
1190
|
+
const ConvexHullCollider = props => {
|
1191
|
+
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1192
|
+
shape: "convexHull"
|
1193
|
+
}));
|
1194
|
+
};
|
1195
|
+
|
1196
|
+
const _excluded$1 = ["children", "type", "position", "rotation", "scale", "quaternion"];
|
1197
|
+
const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
|
1198
|
+
const useRigidBodyContext = () => React.useContext(RigidBodyContext);
|
1199
|
+
const RigidBody = /*#__PURE__*/React.forwardRef((props, ref) => {
|
1200
|
+
const {
|
1201
|
+
children,
|
1202
|
+
type,
|
1203
|
+
position,
|
1204
|
+
rotation,
|
1205
|
+
scale,
|
1206
|
+
quaternion
|
1207
|
+
} = props,
|
1208
|
+
objectProps = _objectWithoutProperties(props, _excluded$1);
|
1209
|
+
|
1210
|
+
const [object, api, childColliderProps] = useRigidBody(props);
|
967
1211
|
React.useImperativeHandle(ref, () => api);
|
968
1212
|
return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
|
969
1213
|
value: {
|
970
1214
|
ref: object,
|
971
1215
|
api,
|
972
|
-
hasCollisionEvents: !!(props.onCollisionEnter || props.onCollisionExit),
|
973
1216
|
options: props
|
974
1217
|
}
|
975
1218
|
}, /*#__PURE__*/React__default["default"].createElement("object3D", _extends({
|
976
1219
|
ref: object
|
977
|
-
}, objectProps
|
1220
|
+
}, objectProps, {
|
1221
|
+
position: position,
|
1222
|
+
rotation: rotation,
|
1223
|
+
quaternion: quaternion,
|
1224
|
+
scale: scale
|
1225
|
+
}), children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({
|
1226
|
+
key: index
|
1227
|
+
}, colliderProps)))));
|
978
1228
|
});
|
979
1229
|
|
980
|
-
const MeshCollider =
|
981
|
-
|
982
|
-
|
983
|
-
|
1230
|
+
const MeshCollider = props => {
|
1231
|
+
const {
|
1232
|
+
children,
|
1233
|
+
type
|
1234
|
+
} = props;
|
984
1235
|
const {
|
985
1236
|
physicsOptions,
|
986
1237
|
world
|
987
1238
|
} = useRapier();
|
988
1239
|
const object = React.useRef(null);
|
989
1240
|
const {
|
990
|
-
api,
|
991
1241
|
options
|
992
1242
|
} = useRigidBodyContext();
|
993
|
-
React.
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
if ("raw" in api) {
|
1002
|
-
autoColliders = createCollidersFromChildren({
|
1003
|
-
object: object.current,
|
1004
|
-
rigidBody: api,
|
1005
|
-
options: _objectSpread2(_objectSpread2({}, options), {}, {
|
1006
|
-
colliders: colliderSetting
|
1007
|
-
}),
|
1008
|
-
world,
|
1009
|
-
ignoreMeshColliders: false
|
1010
|
-
});
|
1011
|
-
}
|
1012
|
-
}
|
1013
|
-
|
1014
|
-
return () => {
|
1015
|
-
autoColliders.forEach(collider => {
|
1016
|
-
world.removeCollider(collider);
|
1017
|
-
});
|
1018
|
-
};
|
1019
|
-
}, []);
|
1243
|
+
const mergedOptions = React.useMemo(() => {
|
1244
|
+
return _objectSpread2(_objectSpread2(_objectSpread2({}, physicsOptions), options), {}, {
|
1245
|
+
children: undefined,
|
1246
|
+
colliders: type
|
1247
|
+
});
|
1248
|
+
}, [physicsOptions, options]);
|
1249
|
+
const childColliderProps = useChildColliderProps(object, mergedOptions, false);
|
1020
1250
|
return /*#__PURE__*/React__default["default"].createElement("object3D", {
|
1021
1251
|
ref: object,
|
1022
1252
|
userData: {
|
1023
1253
|
r3RapierType: "MeshCollider"
|
1024
1254
|
}
|
1025
|
-
}, children)
|
1255
|
+
}, children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({
|
1256
|
+
key: index
|
1257
|
+
}, colliderProps))));
|
1026
1258
|
};
|
1027
1259
|
|
1028
1260
|
const geometryFromCollider = collider => {
|
@@ -1199,14 +1431,24 @@ const Debug = ({
|
|
1199
1431
|
})));
|
1200
1432
|
};
|
1201
1433
|
|
1434
|
+
const _excluded = ["positions", "rotations", "children"];
|
1202
1435
|
const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
1203
1436
|
const {
|
1204
1437
|
world,
|
1205
1438
|
rigidBodyStates,
|
1206
|
-
physicsOptions
|
1439
|
+
physicsOptions,
|
1440
|
+
rigidBodyEvents
|
1207
1441
|
} = useRapier();
|
1208
1442
|
const object = React.useRef(null);
|
1209
|
-
|
1443
|
+
|
1444
|
+
const {
|
1445
|
+
positions,
|
1446
|
+
rotations,
|
1447
|
+
children
|
1448
|
+
} = props,
|
1449
|
+
options = _objectWithoutProperties(props, _excluded);
|
1450
|
+
|
1451
|
+
const instancesRef = React.useRef([]);
|
1210
1452
|
const instancesRefGetter = React.useRef(() => {
|
1211
1453
|
if (!instancesRef.current) {
|
1212
1454
|
instancesRef.current = [];
|
@@ -1214,235 +1456,94 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1214
1456
|
|
1215
1457
|
return instancesRef.current;
|
1216
1458
|
});
|
1459
|
+
const mergedOptions = React.useMemo(() => {
|
1460
|
+
return _objectSpread2(_objectSpread2({}, physicsOptions), options);
|
1461
|
+
}, [physicsOptions, options]);
|
1462
|
+
const childColliderProps = useChildColliderProps(object, mergedOptions);
|
1217
1463
|
React.useLayoutEffect(() => {
|
1218
|
-
|
1464
|
+
object.current.updateWorldMatrix(true, false);
|
1219
1465
|
const rigidBodies = instancesRefGetter.current();
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
1466
|
+
const invertedWorld = object.current.matrixWorld.clone().invert();
|
1467
|
+
object.current.traverseVisible(mesh => {
|
1468
|
+
if (mesh instanceof three.InstancedMesh) {
|
1469
|
+
mesh.instanceMatrix.setUsage(three.DynamicDrawUsage);
|
1470
|
+
const worldScale = mesh.getWorldScale(_scale);
|
1471
|
+
|
1472
|
+
for (let index = 0; index < mesh.count; index++) {
|
1473
|
+
var _options$scales;
|
1474
|
+
|
1475
|
+
const desc = rigidBodyDescFromOptions(props);
|
1476
|
+
const rigidBody = world.createRigidBody(desc);
|
1477
|
+
const scale = ((_options$scales = options.scales) === null || _options$scales === void 0 ? void 0 : _options$scales[index]) || [1, 1, 1];
|
1478
|
+
const instanceScale = worldScale.clone().multiply(vectorArrayToVector3(scale));
|
1479
|
+
rigidBodyStates.set(rigidBody.handle, createRigidBodyState({
|
1480
|
+
rigidBody,
|
1481
|
+
object: mesh,
|
1482
|
+
setMatrix: matrix => mesh.setMatrixAt(index, matrix),
|
1483
|
+
getMatrix: matrix => {
|
1484
|
+
mesh.getMatrixAt(index, matrix);
|
1485
|
+
return matrix;
|
1486
|
+
},
|
1487
|
+
worldScale: instanceScale
|
1488
|
+
}));
|
1489
|
+
const [x, y, z] = (positions === null || positions === void 0 ? void 0 : positions[index]) || [0, 0, 0];
|
1490
|
+
const [rx, ry, rz] = (rotations === null || rotations === void 0 ? void 0 : rotations[index]) || [0, 0, 0];
|
1491
|
+
|
1492
|
+
_object3d.position.set(x, y, z);
|
1493
|
+
|
1494
|
+
_object3d.rotation.set(rx, ry, rz);
|
1495
|
+
|
1496
|
+
_object3d.applyMatrix4(invertedWorld);
|
1497
|
+
|
1498
|
+
mesh.setMatrixAt(index, _object3d.matrix);
|
1499
|
+
rigidBody.setTranslation(_object3d.position, false);
|
1500
|
+
rigidBody.setRotation(_object3d.quaternion, false);
|
1501
|
+
const api = createRigidBodyApi({
|
1502
|
+
current() {
|
1503
|
+
return rigidBody;
|
1241
1504
|
}
|
1242
1505
|
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1248
|
-
rotation
|
1249
|
-
} = decomposeMatrix4(matrix);
|
1250
|
-
|
1251
|
-
if (props.colliders !== false) {
|
1252
|
-
const colliderDesc = colliderDescFromGeometry(mesh.geometry, props.colliders !== undefined ? props.colliders : physicsOptions.colliders, scale, false // Collisions currently not enabled for instances
|
1253
|
-
);
|
1254
|
-
const collider = world.createCollider(colliderDesc, rigidBody);
|
1255
|
-
colliders.push(collider);
|
1256
|
-
} // Set positions
|
1257
|
-
|
1258
|
-
|
1259
|
-
if (props.positions && props.positions[index]) {
|
1260
|
-
rigidBody.setTranslation(vectorArrayToVector3(props.positions[index]), true);
|
1261
|
-
} else {
|
1262
|
-
rigidBody.setTranslation(position, true);
|
1263
|
-
} // Set rotations
|
1264
|
-
|
1265
|
-
|
1266
|
-
if (props.rotations && props.rotations[index]) {
|
1267
|
-
const [x, y, z] = props.rotations[index];
|
1268
|
-
rigidBody.setRotation(vector3ToQuaternion(new three.Vector3(x, y, z)), true);
|
1269
|
-
} else {
|
1270
|
-
rigidBody.setRotation(rotation, true);
|
1271
|
-
}
|
1272
|
-
|
1273
|
-
rigidBodyStates.set(rigidBody.handle, {
|
1274
|
-
mesh: mesh,
|
1275
|
-
isSleeping: false,
|
1276
|
-
invertedMatrixWorld: object.current.matrixWorld.clone().invert(),
|
1277
|
-
setMatrix: matrix => mesh.setMatrixAt(index, matrix),
|
1278
|
-
getMatrix: () => {
|
1279
|
-
const m = new three.Matrix4();
|
1280
|
-
mesh.getMatrixAt(index, m);
|
1281
|
-
return m;
|
1282
|
-
},
|
1283
|
-
// Setting the world scale to the scale here, because
|
1284
|
-
// we want the scales to be reflected by instance
|
1285
|
-
worldScale: scale
|
1286
|
-
});
|
1287
|
-
const api = createRigidBodyApi({
|
1288
|
-
current() {
|
1289
|
-
return rigidBody;
|
1290
|
-
}
|
1291
|
-
|
1292
|
-
});
|
1293
|
-
rigidBodies.push({
|
1294
|
-
rigidBody,
|
1295
|
-
api
|
1296
|
-
});
|
1297
|
-
}
|
1298
|
-
}
|
1299
|
-
|
1300
|
-
if (mesh.type === "Mesh" && !("isInstancedMesh" in mesh)) {
|
1301
|
-
console.warn("Can only use InstancedMesh inside <InstancedRigidBodies />, Mesh will be ignored.");
|
1506
|
+
});
|
1507
|
+
rigidBodies.push({
|
1508
|
+
rigidBody,
|
1509
|
+
api
|
1510
|
+
});
|
1302
1511
|
}
|
1512
|
+
}
|
1513
|
+
});
|
1514
|
+
return () => {
|
1515
|
+
rigidBodies.forEach(rb => {
|
1516
|
+
world.removeRigidBody(rb.rigidBody);
|
1517
|
+
rigidBodyStates.delete(rb.rigidBody.handle);
|
1303
1518
|
});
|
1304
|
-
|
1305
|
-
|
1306
|
-
colliders.forEach(coll => world.removeCollider(coll));
|
1307
|
-
instancesRef.current = undefined;
|
1308
|
-
};
|
1309
|
-
}
|
1519
|
+
instancesRef.current = [];
|
1520
|
+
};
|
1310
1521
|
}, []);
|
1311
1522
|
const api = React.useMemo(() => createInstancedRigidBodiesApi(instancesRefGetter), []);
|
1312
|
-
React.useImperativeHandle(ref, () => api);
|
1313
|
-
|
1523
|
+
React.useImperativeHandle(ref, () => api);
|
1524
|
+
useUpdateRigidBodyOptions({
|
1525
|
+
current: instancesRef.current.map(({
|
1526
|
+
rigidBody
|
1527
|
+
}) => rigidBody)
|
1528
|
+
}, mergedOptions, rigidBodyStates, false);
|
1529
|
+
useRigidBodyEvents({
|
1530
|
+
current: instancesRef.current.map(({
|
1531
|
+
rigidBody
|
1532
|
+
}) => rigidBody)
|
1533
|
+
}, mergedOptions, rigidBodyEvents);
|
1314
1534
|
return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
|
1315
1535
|
value: {
|
1316
1536
|
ref: object,
|
1317
1537
|
api,
|
1318
|
-
hasCollisionEvents: false,
|
1319
1538
|
options: props
|
1320
1539
|
}
|
1321
1540
|
}, /*#__PURE__*/React__default["default"].createElement("object3D", {
|
1322
1541
|
ref: object
|
1323
|
-
}, props.children)
|
1542
|
+
}, props.children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({
|
1543
|
+
key: index
|
1544
|
+
}, colliderProps)))));
|
1324
1545
|
});
|
1325
1546
|
|
1326
|
-
const _excluded = ["children", "onCollisionEnter", "onCollisionExit"];
|
1327
|
-
|
1328
|
-
const AnyCollider = _ref => {
|
1329
|
-
let {
|
1330
|
-
children,
|
1331
|
-
onCollisionEnter,
|
1332
|
-
onCollisionExit
|
1333
|
-
} = _ref,
|
1334
|
-
props = _objectWithoutProperties(_ref, _excluded);
|
1335
|
-
|
1336
|
-
const {
|
1337
|
-
world,
|
1338
|
-
colliderEvents
|
1339
|
-
} = useRapier();
|
1340
|
-
const rigidBodyContext = useRigidBodyContext();
|
1341
|
-
const ref = React.useRef(null);
|
1342
|
-
React.useEffect(() => {
|
1343
|
-
const scale = ref.current.getWorldScale(new three.Vector3());
|
1344
|
-
const colliders = [];
|
1345
|
-
const hasCollisionEvents = (rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.hasCollisionEvents) || !!onCollisionEnter || !!onCollisionExit; // If this is an InstancedRigidBody api
|
1346
|
-
|
1347
|
-
if (rigidBodyContext && "at" in rigidBodyContext.api) {
|
1348
|
-
rigidBodyContext.api.forEach((body, index) => {
|
1349
|
-
var _rigidBodyContext$opt, _rigidBodyContext$opt2;
|
1350
|
-
|
1351
|
-
let instanceScale = scale.clone();
|
1352
|
-
|
1353
|
-
if ("scales" in rigidBodyContext.options && rigidBodyContext !== null && rigidBodyContext !== void 0 && (_rigidBodyContext$opt = rigidBodyContext.options) !== null && _rigidBodyContext$opt !== void 0 && (_rigidBodyContext$opt2 = _rigidBodyContext$opt.scales) !== null && _rigidBodyContext$opt2 !== void 0 && _rigidBodyContext$opt2[index]) {
|
1354
|
-
instanceScale.multiply(vectorArrayToVector3(rigidBodyContext.options.scales[index]));
|
1355
|
-
}
|
1356
|
-
|
1357
|
-
colliders.push(createColliderFromOptions({
|
1358
|
-
options: _objectSpread2({
|
1359
|
-
solverGroups: rigidBodyContext.options.solverGroups,
|
1360
|
-
collisionGroups: rigidBodyContext.options.collisionGroups
|
1361
|
-
}, props),
|
1362
|
-
world,
|
1363
|
-
rigidBody: body.raw(),
|
1364
|
-
scale: instanceScale,
|
1365
|
-
hasCollisionEvents
|
1366
|
-
}));
|
1367
|
-
});
|
1368
|
-
} else {
|
1369
|
-
colliders.push(createColliderFromOptions({
|
1370
|
-
options: _objectSpread2({
|
1371
|
-
solverGroups: (rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options.solverGroups) || props.solverGroups,
|
1372
|
-
collisionGroups: (rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options.collisionGroups) || props.collisionGroups
|
1373
|
-
}, props),
|
1374
|
-
world,
|
1375
|
-
// Initiate with a rigidbody, or undefined, because colliders can exist without a rigid body
|
1376
|
-
rigidBody: rigidBodyContext && "raw" in rigidBodyContext.api ? rigidBodyContext.api.raw() : undefined,
|
1377
|
-
scale,
|
1378
|
-
hasCollisionEvents
|
1379
|
-
}));
|
1380
|
-
}
|
1381
|
-
/* Register collision events. */
|
1382
|
-
|
1383
|
-
|
1384
|
-
colliders.forEach(collider => colliderEvents.set(collider.handle, {
|
1385
|
-
onCollisionEnter,
|
1386
|
-
onCollisionExit
|
1387
|
-
}));
|
1388
|
-
return () => {
|
1389
|
-
colliders.forEach(collider => {
|
1390
|
-
colliderEvents.delete(collider.handle);
|
1391
|
-
world.removeCollider(collider);
|
1392
|
-
});
|
1393
|
-
};
|
1394
|
-
}, []);
|
1395
|
-
return /*#__PURE__*/React__default["default"].createElement("object3D", {
|
1396
|
-
ref: ref
|
1397
|
-
}, children);
|
1398
|
-
};
|
1399
|
-
|
1400
|
-
const CuboidCollider = props => {
|
1401
|
-
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1402
|
-
shape: "cuboid"
|
1403
|
-
}));
|
1404
|
-
};
|
1405
|
-
const RoundCuboidCollider = props => {
|
1406
|
-
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1407
|
-
shape: "roundCuboid"
|
1408
|
-
}));
|
1409
|
-
};
|
1410
|
-
const BallCollider = props => {
|
1411
|
-
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1412
|
-
shape: "ball"
|
1413
|
-
}));
|
1414
|
-
};
|
1415
|
-
const CapsuleCollider = props => {
|
1416
|
-
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1417
|
-
shape: "capsule"
|
1418
|
-
}));
|
1419
|
-
};
|
1420
|
-
const HeightfieldCollider = props => {
|
1421
|
-
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1422
|
-
shape: "heightfield"
|
1423
|
-
}));
|
1424
|
-
};
|
1425
|
-
const TrimeshCollider = props => {
|
1426
|
-
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1427
|
-
shape: "trimesh"
|
1428
|
-
}));
|
1429
|
-
};
|
1430
|
-
const ConeCollider = props => {
|
1431
|
-
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1432
|
-
shape: "cone"
|
1433
|
-
}));
|
1434
|
-
};
|
1435
|
-
const CylinderCollider = props => {
|
1436
|
-
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1437
|
-
shape: "cylinder"
|
1438
|
-
}));
|
1439
|
-
};
|
1440
|
-
const ConvexHullCollider = props => {
|
1441
|
-
return /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({}, props, {
|
1442
|
-
shape: "convexHull"
|
1443
|
-
}));
|
1444
|
-
};
|
1445
|
-
|
1446
1547
|
/**
|
1447
1548
|
* Calculates an InteractionGroup bitmask for use in the `collisionGroups` or `solverGroups`
|
1448
1549
|
* properties of RigidBody or Collider components. The first argument represents a list of
|
@@ -1491,6 +1592,7 @@ Object.defineProperty(exports, 'RapierRigidBody', {
|
|
1491
1592
|
enumerable: true,
|
1492
1593
|
get: function () { return rapier3dCompat.RigidBody; }
|
1493
1594
|
});
|
1595
|
+
exports.AnyCollider = AnyCollider;
|
1494
1596
|
exports.BallCollider = BallCollider;
|
1495
1597
|
exports.CapsuleCollider = CapsuleCollider;
|
1496
1598
|
exports.ConeCollider = ConeCollider;
|
@@ -1506,6 +1608,7 @@ exports.RigidBody = RigidBody;
|
|
1506
1608
|
exports.RoundCuboidCollider = RoundCuboidCollider;
|
1507
1609
|
exports.TrimeshCollider = TrimeshCollider;
|
1508
1610
|
exports.interactionGroups = interactionGroups;
|
1611
|
+
exports.useChildColliderProps = useChildColliderProps;
|
1509
1612
|
exports.useFixedJoint = useFixedJoint;
|
1510
1613
|
exports.useImpulseJoint = useImpulseJoint;
|
1511
1614
|
exports.usePrismaticJoint = usePrismaticJoint;
|