@react-three/rapier 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/declarations/src/Physics.d.ts +14 -1
- package/dist/declarations/src/components.d.ts +1 -2
- package/dist/declarations/src/types.d.ts +17 -1
- package/dist/declarations/src/utils.d.ts +2 -2
- package/dist/react-three-rapier.cjs.dev.js +104 -15
- package/dist/react-three-rapier.cjs.prod.js +104 -15
- package/dist/react-three-rapier.esm.js +105 -16
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import React, { FC, ReactNode } from "react";
|
2
2
|
import type Rapier from "@dimforge/rapier3d-compat";
|
3
3
|
import { RigidBodyAutoCollider, Vector3Array, WorldApi } from "./types";
|
4
|
-
import { ColliderHandle } from "@dimforge/rapier3d-compat";
|
4
|
+
import { ColliderHandle, RigidBody, RigidBodyHandle, TempContactManifold } from "@dimforge/rapier3d-compat";
|
5
5
|
import { Object3D } from "three";
|
6
6
|
export interface RapierContext {
|
7
7
|
rapier: typeof Rapier;
|
@@ -11,8 +11,21 @@ export interface RapierContext {
|
|
11
11
|
physicsOptions: {
|
12
12
|
colliders: RigidBodyAutoCollider;
|
13
13
|
};
|
14
|
+
rigidBodyEvents: EventMap;
|
14
15
|
}
|
15
16
|
export declare const RapierContext: React.Context<RapierContext | undefined>;
|
17
|
+
declare type EventMap = Map<ColliderHandle | RigidBodyHandle, {
|
18
|
+
onSleep?(): void;
|
19
|
+
onWake?(): void;
|
20
|
+
onCollisionEnter?({ target, manifold, flipped }: {
|
21
|
+
target: RigidBody;
|
22
|
+
manifold: TempContactManifold;
|
23
|
+
flipped: boolean;
|
24
|
+
}): void;
|
25
|
+
onCollisionExit?({ target }: {
|
26
|
+
target: RigidBody;
|
27
|
+
}): void;
|
28
|
+
}>;
|
16
29
|
interface RapierWorldProps {
|
17
30
|
gravity?: Vector3Array;
|
18
31
|
colliders?: RigidBodyAutoCollider;
|
@@ -1,10 +1,9 @@
|
|
1
1
|
import React from "react";
|
2
2
|
import { ReactNode } from "react";
|
3
3
|
import { Vector3 } from "three";
|
4
|
-
import { BallArgs, CapsuleArgs, ConeArgs, ConvexHullArgs, CuboidArgs, CylinderArgs, HeightfieldArgs,
|
4
|
+
import { BallArgs, CapsuleArgs, ConeArgs, ConvexHullArgs, CuboidArgs, CylinderArgs, HeightfieldArgs, RoundCuboidArgs, TrimeshArgs, UseColliderOptions, UseRigidBodyOptions } from "./types";
|
5
5
|
interface RigidBodyProps extends UseRigidBodyOptions {
|
6
6
|
children?: ReactNode;
|
7
|
-
colliders?: RigidBodyAutoCollider | false;
|
8
7
|
}
|
9
8
|
export declare const RigidBody: React.ForwardRefExoticComponent<RigidBodyProps & React.RefAttributes<{
|
10
9
|
raw: () => import("@dimforge/rapier3d-compat/dynamics/rigid_body").RigidBody | undefined;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { MutableRefObject } from "react";
|
2
|
-
import { CoefficientCombineRule, RigidBody as RapierRigidBody, Collider as RapierCollider } from "@dimforge/rapier3d-compat";
|
2
|
+
import { CoefficientCombineRule, RigidBody as RapierRigidBody, Collider as RapierCollider, TempContactManifold } from "@dimforge/rapier3d-compat";
|
3
3
|
import { createColliderApi, createJointApi, createRigidBodyApi, createWorldApi } from "./api";
|
4
4
|
export { RapierRigidBody, RapierCollider };
|
5
5
|
export { CoefficientCombineRule as CoefficientCombineRule, } from "@dimforge/rapier3d-compat";
|
@@ -162,6 +162,22 @@ export interface UseRigidBodyOptions {
|
|
162
162
|
* Setting this to false will disable automatic colliders.
|
163
163
|
*/
|
164
164
|
colliders?: RigidBodyAutoCollider | false;
|
165
|
+
/**
|
166
|
+
* Callback when this rigidbody collides with another rigidbody
|
167
|
+
*/
|
168
|
+
onCollisionEnter?({}: {
|
169
|
+
target: RapierRigidBody;
|
170
|
+
manifold: TempContactManifold;
|
171
|
+
flipped: boolean;
|
172
|
+
}): void;
|
173
|
+
/**
|
174
|
+
* Callback when this rigidbody stops colliding with another rigidbody
|
175
|
+
*/
|
176
|
+
onCollisionExit?({}: {
|
177
|
+
target: RapierRigidBody;
|
178
|
+
}): void;
|
179
|
+
onSleep?(): void;
|
180
|
+
onWake?(): void;
|
165
181
|
}
|
166
182
|
export declare type SphericalJointParams = [
|
167
183
|
body1Anchor: Vector3Array,
|
@@ -12,6 +12,6 @@ export declare const createColliderFromOptions: <A>(options: UseColliderOptions<
|
|
12
12
|
x: number;
|
13
13
|
y: number;
|
14
14
|
z: number;
|
15
|
-
}) => Collider;
|
16
|
-
export declare const createCollidersFromChildren: (object: Object3D, rigidBody: RapierRigidBody, type: RigidBodyAutoCollider, world: WorldApi) => Collider[];
|
15
|
+
}, hasCollisionEvents?: boolean) => Collider;
|
16
|
+
export declare const createCollidersFromChildren: (object: Object3D, rigidBody: RapierRigidBody, type: RigidBodyAutoCollider, world: WorldApi, hasCollisionEvents?: boolean) => Collider[];
|
17
17
|
export declare const scaleVertices: (vertices: ArrayLike<number>, scale: Vector3) => number[];
|
@@ -5,8 +5,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
5
|
var React = require('react');
|
6
6
|
var useAsset = require('use-asset');
|
7
7
|
var fiber = require('@react-three/fiber');
|
8
|
-
var three = require('three');
|
9
8
|
var rapier3dCompat = require('@dimforge/rapier3d-compat');
|
9
|
+
var three = require('three');
|
10
10
|
|
11
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
12
12
|
|
@@ -67,7 +67,7 @@ const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
|
|
67
67
|
x: 1,
|
68
68
|
y: 1,
|
69
69
|
z: 1
|
70
|
-
}) => {
|
70
|
+
}, hasCollisionEvents = false) => {
|
71
71
|
var _options$shape, _options$args, _options$restitution, _options$restitutionC, _options$friction, _options$frictionComb;
|
72
72
|
|
73
73
|
const mass = (options === null || options === void 0 ? void 0 : options.mass) || 1;
|
@@ -85,7 +85,12 @@ const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
|
|
85
85
|
y: ry,
|
86
86
|
z: rz,
|
87
87
|
w: 1
|
88
|
-
}).setRestitution((_options$restitution = options === null || options === void 0 ? void 0 : options.restitution) !== null && _options$restitution !== void 0 ? _options$restitution : 0).setRestitutionCombineRule((_options$restitutionC = options === null || options === void 0 ? void 0 : options.restitutionCombineRule) !== null && _options$restitutionC !== void 0 ? _options$restitutionC : rapier3dCompat.CoefficientCombineRule.Average).setFriction((_options$friction = options === null || options === void 0 ? void 0 : options.friction) !== null && _options$friction !== void 0 ? _options$friction : 0.7).setFrictionCombineRule((_options$frictionComb = options === null || options === void 0 ? void 0 : options.frictionCombineRule) !== null && _options$frictionComb !== void 0 ? _options$frictionComb : rapier3dCompat.CoefficientCombineRule.Average);
|
88
|
+
}).setRestitution((_options$restitution = options === null || options === void 0 ? void 0 : options.restitution) !== null && _options$restitution !== void 0 ? _options$restitution : 0).setRestitutionCombineRule((_options$restitutionC = options === null || options === void 0 ? void 0 : options.restitutionCombineRule) !== null && _options$restitutionC !== void 0 ? _options$restitutionC : rapier3dCompat.CoefficientCombineRule.Average).setFriction((_options$friction = options === null || options === void 0 ? void 0 : options.friction) !== null && _options$friction !== void 0 ? _options$friction : 0.7).setFrictionCombineRule((_options$frictionComb = options === null || options === void 0 ? void 0 : options.frictionCombineRule) !== null && _options$frictionComb !== void 0 ? _options$frictionComb : rapier3dCompat.CoefficientCombineRule.Average);
|
89
|
+
|
90
|
+
if (hasCollisionEvents) {
|
91
|
+
colliderDesc = colliderDesc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
|
92
|
+
} // If any of the mass properties are specified, add mass properties
|
93
|
+
|
89
94
|
|
90
95
|
if (options !== null && options !== void 0 && options.mass || options !== null && options !== void 0 && options.centerOfMass || options !== null && options !== void 0 && options.principalAngularInertia) {
|
91
96
|
colliderDesc.setDensity(0);
|
@@ -108,7 +113,7 @@ const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
|
|
108
113
|
const collider = world.createCollider(colliderDesc, rigidBodyHandle);
|
109
114
|
return collider;
|
110
115
|
};
|
111
|
-
const createCollidersFromChildren = (object, rigidBody, type, world) => {
|
116
|
+
const createCollidersFromChildren = (object, rigidBody, type, world, hasCollisionEvents = false) => {
|
112
117
|
const colliders = [];
|
113
118
|
let desc;
|
114
119
|
let offset = new three.Vector3();
|
@@ -181,6 +186,11 @@ const createCollidersFromChildren = (object, rigidBody, type, world) => {
|
|
181
186
|
z: rz,
|
182
187
|
w: rw
|
183
188
|
});
|
189
|
+
|
190
|
+
if (hasCollisionEvents) {
|
191
|
+
desc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
|
192
|
+
}
|
193
|
+
|
184
194
|
const collider = world.createCollider(desc, rigidBody.handle);
|
185
195
|
colliders.push(collider);
|
186
196
|
}
|
@@ -316,7 +326,9 @@ const Physics = ({
|
|
316
326
|
return worldRef.current;
|
317
327
|
});
|
318
328
|
const [colliderMeshes] = React.useState(() => new Map());
|
319
|
-
const [rigidBodyMeshes] = React.useState(() => new Map());
|
329
|
+
const [rigidBodyMeshes] = React.useState(() => new Map());
|
330
|
+
const [rigidBodyEvents] = React.useState(() => new Map());
|
331
|
+
const [eventQueue] = React.useState(() => new rapier3dCompat.EventQueue(false)); // Init world
|
320
332
|
|
321
333
|
React.useLayoutEffect(() => {
|
322
334
|
const world = getWorldRef.current();
|
@@ -336,10 +348,27 @@ const Physics = ({
|
|
336
348
|
const now = performance.now();
|
337
349
|
const delta = Math.min(100, now - time.current);
|
338
350
|
world.timestep = delta / 1000;
|
339
|
-
world.step(); // Update meshes
|
351
|
+
world.step(eventQueue); // Update meshes
|
340
352
|
|
341
353
|
rigidBodyMeshes.forEach((mesh, handle) => {
|
342
354
|
const rigidBody = world.getRigidBody(handle);
|
355
|
+
const events = rigidBodyEvents.get(handle);
|
356
|
+
|
357
|
+
if (events !== null && events !== void 0 && events.onSleep || events !== null && events !== void 0 && events.onWake) {
|
358
|
+
if (rigidBody.isSleeping() && !mesh.userData.isSleeping) {
|
359
|
+
var _events$onSleep;
|
360
|
+
|
361
|
+
events === null || events === void 0 ? void 0 : (_events$onSleep = events.onSleep) === null || _events$onSleep === void 0 ? void 0 : _events$onSleep.call(events);
|
362
|
+
}
|
363
|
+
|
364
|
+
if (!rigidBody.isSleeping() && mesh.userData.isSleeping) {
|
365
|
+
var _events$onWake;
|
366
|
+
|
367
|
+
events === null || events === void 0 ? void 0 : (_events$onWake = events.onWake) === null || _events$onWake === void 0 ? void 0 : _events$onWake.call(events);
|
368
|
+
}
|
369
|
+
|
370
|
+
mesh.userData.isSleeping = rigidBody.isSleeping();
|
371
|
+
}
|
343
372
|
|
344
373
|
if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !mesh.parent) {
|
345
374
|
return;
|
@@ -367,6 +396,48 @@ const Physics = ({
|
|
367
396
|
o.updateMatrix();
|
368
397
|
mesh.position.setFromMatrixPosition(o.matrix);
|
369
398
|
mesh.rotation.setFromRotationMatrix(o.matrix);
|
399
|
+
}); // Collision events
|
400
|
+
|
401
|
+
eventQueue.drainCollisionEvents((handle1, handle2, started) => {
|
402
|
+
const collider1 = world.getCollider(handle1);
|
403
|
+
const collider2 = world.getCollider(handle2);
|
404
|
+
const rigidBodyHandle1 = collider1.parent();
|
405
|
+
const rigidBodyHandle2 = collider2.parent();
|
406
|
+
|
407
|
+
if (!collider1 || !collider2 || !rigidBodyHandle1 || !rigidBodyHandle2) {
|
408
|
+
return;
|
409
|
+
}
|
410
|
+
|
411
|
+
const rigidBody1 = world.getRigidBody(rigidBodyHandle1);
|
412
|
+
const rigidBody2 = world.getRigidBody(rigidBodyHandle2);
|
413
|
+
const events1 = rigidBodyEvents.get(rigidBodyHandle1);
|
414
|
+
const events2 = rigidBodyEvents.get(rigidBodyHandle2);
|
415
|
+
|
416
|
+
if (started) {
|
417
|
+
world.contactPair(handle1, handle2, (manifold, flipped) => {
|
418
|
+
var _events1$onCollisionE, _events2$onCollisionE;
|
419
|
+
|
420
|
+
events1 === null || events1 === void 0 ? void 0 : (_events1$onCollisionE = events1.onCollisionEnter) === null || _events1$onCollisionE === void 0 ? void 0 : _events1$onCollisionE.call(events1, {
|
421
|
+
target: rigidBody2,
|
422
|
+
manifold,
|
423
|
+
flipped
|
424
|
+
});
|
425
|
+
events2 === null || events2 === void 0 ? void 0 : (_events2$onCollisionE = events2.onCollisionEnter) === null || _events2$onCollisionE === void 0 ? void 0 : _events2$onCollisionE.call(events2, {
|
426
|
+
target: rigidBody1,
|
427
|
+
manifold,
|
428
|
+
flipped
|
429
|
+
});
|
430
|
+
});
|
431
|
+
} else {
|
432
|
+
var _events1$onCollisionE2, _events2$onCollisionE2;
|
433
|
+
|
434
|
+
events1 === null || events1 === void 0 ? void 0 : (_events1$onCollisionE2 = events1.onCollisionExit) === null || _events1$onCollisionE2 === void 0 ? void 0 : _events1$onCollisionE2.call(events1, {
|
435
|
+
target: rigidBody2
|
436
|
+
});
|
437
|
+
events2 === null || events2 === void 0 ? void 0 : (_events2$onCollisionE2 = events2.onCollisionExit) === null || _events2$onCollisionE2 === void 0 ? void 0 : _events2$onCollisionE2.call(events2, {
|
438
|
+
target: rigidBody1
|
439
|
+
});
|
440
|
+
}
|
370
441
|
});
|
371
442
|
time.current = now;
|
372
443
|
});
|
@@ -379,7 +450,8 @@ const Physics = ({
|
|
379
450
|
gravity: _gravity
|
380
451
|
},
|
381
452
|
colliderMeshes,
|
382
|
-
rigidBodyMeshes
|
453
|
+
rigidBodyMeshes,
|
454
|
+
rigidBodyEvents
|
383
455
|
}), []);
|
384
456
|
return /*#__PURE__*/React__default["default"].createElement(RapierContext.Provider, {
|
385
457
|
value: context
|
@@ -435,7 +507,8 @@ const useRigidBody = (options = {}) => {
|
|
435
507
|
rapier,
|
436
508
|
world,
|
437
509
|
rigidBodyMeshes,
|
438
|
-
physicsOptions
|
510
|
+
physicsOptions,
|
511
|
+
rigidBodyEvents
|
439
512
|
} = useRapier();
|
440
513
|
const ref = React.useRef(); // Create rigidbody
|
441
514
|
|
@@ -470,9 +543,11 @@ const useRigidBody = (options = {}) => {
|
|
470
543
|
|
471
544
|
if (!ref.current) {
|
472
545
|
ref.current = new three.Object3D();
|
473
|
-
} //
|
546
|
+
} // isSleeping used for onSleep and onWake events
|
474
547
|
|
475
548
|
|
549
|
+
ref.current.userData.isSleeping = false; // Get intitial world transforms
|
550
|
+
|
476
551
|
const worldPosition = ref.current.getWorldPosition(new three.Vector3());
|
477
552
|
const worldRotation = ref.current.getWorldQuaternion(new three.Quaternion());
|
478
553
|
const scale = ((_ref$current$parent = ref.current.parent) === null || _ref$current$parent === void 0 ? void 0 : _ref$current$parent.getWorldScale(new three.Vector3())) || {
|
@@ -500,7 +575,8 @@ const useRigidBody = (options = {}) => {
|
|
500
575
|
rigidBody.resetForces(false);
|
501
576
|
rigidBody.resetTorques(false);
|
502
577
|
const colliderSetting = (_ref = (_options$colliders = options === null || options === void 0 ? void 0 : options.colliders) !== null && _options$colliders !== void 0 ? _options$colliders : physicsOptions.colliders) !== null && _ref !== void 0 ? _ref : false;
|
503
|
-
const
|
578
|
+
const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
|
579
|
+
const autoColliders = colliderSetting !== false ? createCollidersFromChildren(ref.current, rigidBody, colliderSetting, world, hasCollisionEvents) : [];
|
504
580
|
rigidBody.wakeUp();
|
505
581
|
rigidBodyMeshes.set(rigidBody.handle, ref.current);
|
506
582
|
return () => {
|
@@ -509,7 +585,20 @@ const useRigidBody = (options = {}) => {
|
|
509
585
|
rigidBodyRef.current = undefined;
|
510
586
|
rigidBodyMeshes.delete(rigidBody.handle);
|
511
587
|
};
|
512
|
-
}, []);
|
588
|
+
}, []); // Events
|
589
|
+
|
590
|
+
React.useEffect(() => {
|
591
|
+
const rigidBody = getRigidBodyRef.current();
|
592
|
+
rigidBodyEvents.set(rigidBody.handle, {
|
593
|
+
onCollisionEnter: options === null || options === void 0 ? void 0 : options.onCollisionEnter,
|
594
|
+
onCollisionExit: options === null || options === void 0 ? void 0 : options.onCollisionExit,
|
595
|
+
onSleep: options === null || options === void 0 ? void 0 : options.onSleep,
|
596
|
+
onWake: options === null || options === void 0 ? void 0 : options.onWake
|
597
|
+
});
|
598
|
+
return () => {
|
599
|
+
rigidBodyEvents.delete(rigidBody.handle);
|
600
|
+
};
|
601
|
+
}, [options.onCollisionEnter, options.onCollisionExit]);
|
513
602
|
const api = React.useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
|
514
603
|
return [ref, api];
|
515
604
|
};
|
@@ -823,7 +912,7 @@ const _excluded = ["children"],
|
|
823
912
|
_excluded2 = ["children"];
|
824
913
|
const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
|
825
914
|
|
826
|
-
const
|
915
|
+
const useRigidBodyContext = () => React.useContext(RigidBodyContext); // RigidBody
|
827
916
|
|
828
917
|
|
829
918
|
const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
@@ -835,7 +924,7 @@ const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
835
924
|
const [object, rigidBody] = useRigidBody(props);
|
836
925
|
React.useImperativeHandle(ref, () => rigidBody);
|
837
926
|
return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
|
838
|
-
value: [object, rigidBody]
|
927
|
+
value: [object, rigidBody, !!(props.onCollisionEnter || props.onCollisionExit)]
|
839
928
|
}, /*#__PURE__*/React__default["default"].createElement("object3D", {
|
840
929
|
ref: object
|
841
930
|
}, children));
|
@@ -850,11 +939,11 @@ const AnyCollider = _ref2 => {
|
|
850
939
|
const {
|
851
940
|
world
|
852
941
|
} = useRapier();
|
853
|
-
const [, rigidBody] =
|
942
|
+
const [, rigidBody, hasCollisionEvents] = useRigidBodyContext();
|
854
943
|
const ref = React.useRef(null);
|
855
944
|
React.useEffect(() => {
|
856
945
|
const scale = ref.current.getWorldScale(new three.Vector3());
|
857
|
-
const collider = createColliderFromOptions(props, world, rigidBody.handle, scale);
|
946
|
+
const collider = createColliderFromOptions(props, world, rigidBody.handle, scale, hasCollisionEvents);
|
858
947
|
return () => {
|
859
948
|
world.removeCollider(collider);
|
860
949
|
};
|
@@ -5,8 +5,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
5
|
var React = require('react');
|
6
6
|
var useAsset = require('use-asset');
|
7
7
|
var fiber = require('@react-three/fiber');
|
8
|
-
var three = require('three');
|
9
8
|
var rapier3dCompat = require('@dimforge/rapier3d-compat');
|
9
|
+
var three = require('three');
|
10
10
|
|
11
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
12
12
|
|
@@ -67,7 +67,7 @@ const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
|
|
67
67
|
x: 1,
|
68
68
|
y: 1,
|
69
69
|
z: 1
|
70
|
-
}) => {
|
70
|
+
}, hasCollisionEvents = false) => {
|
71
71
|
var _options$shape, _options$args, _options$restitution, _options$restitutionC, _options$friction, _options$frictionComb;
|
72
72
|
|
73
73
|
const mass = (options === null || options === void 0 ? void 0 : options.mass) || 1;
|
@@ -85,7 +85,12 @@ const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
|
|
85
85
|
y: ry,
|
86
86
|
z: rz,
|
87
87
|
w: 1
|
88
|
-
}).setRestitution((_options$restitution = options === null || options === void 0 ? void 0 : options.restitution) !== null && _options$restitution !== void 0 ? _options$restitution : 0).setRestitutionCombineRule((_options$restitutionC = options === null || options === void 0 ? void 0 : options.restitutionCombineRule) !== null && _options$restitutionC !== void 0 ? _options$restitutionC : rapier3dCompat.CoefficientCombineRule.Average).setFriction((_options$friction = options === null || options === void 0 ? void 0 : options.friction) !== null && _options$friction !== void 0 ? _options$friction : 0.7).setFrictionCombineRule((_options$frictionComb = options === null || options === void 0 ? void 0 : options.frictionCombineRule) !== null && _options$frictionComb !== void 0 ? _options$frictionComb : rapier3dCompat.CoefficientCombineRule.Average);
|
88
|
+
}).setRestitution((_options$restitution = options === null || options === void 0 ? void 0 : options.restitution) !== null && _options$restitution !== void 0 ? _options$restitution : 0).setRestitutionCombineRule((_options$restitutionC = options === null || options === void 0 ? void 0 : options.restitutionCombineRule) !== null && _options$restitutionC !== void 0 ? _options$restitutionC : rapier3dCompat.CoefficientCombineRule.Average).setFriction((_options$friction = options === null || options === void 0 ? void 0 : options.friction) !== null && _options$friction !== void 0 ? _options$friction : 0.7).setFrictionCombineRule((_options$frictionComb = options === null || options === void 0 ? void 0 : options.frictionCombineRule) !== null && _options$frictionComb !== void 0 ? _options$frictionComb : rapier3dCompat.CoefficientCombineRule.Average);
|
89
|
+
|
90
|
+
if (hasCollisionEvents) {
|
91
|
+
colliderDesc = colliderDesc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
|
92
|
+
} // If any of the mass properties are specified, add mass properties
|
93
|
+
|
89
94
|
|
90
95
|
if (options !== null && options !== void 0 && options.mass || options !== null && options !== void 0 && options.centerOfMass || options !== null && options !== void 0 && options.principalAngularInertia) {
|
91
96
|
colliderDesc.setDensity(0);
|
@@ -108,7 +113,7 @@ const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
|
|
108
113
|
const collider = world.createCollider(colliderDesc, rigidBodyHandle);
|
109
114
|
return collider;
|
110
115
|
};
|
111
|
-
const createCollidersFromChildren = (object, rigidBody, type, world) => {
|
116
|
+
const createCollidersFromChildren = (object, rigidBody, type, world, hasCollisionEvents = false) => {
|
112
117
|
const colliders = [];
|
113
118
|
let desc;
|
114
119
|
let offset = new three.Vector3();
|
@@ -181,6 +186,11 @@ const createCollidersFromChildren = (object, rigidBody, type, world) => {
|
|
181
186
|
z: rz,
|
182
187
|
w: rw
|
183
188
|
});
|
189
|
+
|
190
|
+
if (hasCollisionEvents) {
|
191
|
+
desc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
|
192
|
+
}
|
193
|
+
|
184
194
|
const collider = world.createCollider(desc, rigidBody.handle);
|
185
195
|
colliders.push(collider);
|
186
196
|
}
|
@@ -316,7 +326,9 @@ const Physics = ({
|
|
316
326
|
return worldRef.current;
|
317
327
|
});
|
318
328
|
const [colliderMeshes] = React.useState(() => new Map());
|
319
|
-
const [rigidBodyMeshes] = React.useState(() => new Map());
|
329
|
+
const [rigidBodyMeshes] = React.useState(() => new Map());
|
330
|
+
const [rigidBodyEvents] = React.useState(() => new Map());
|
331
|
+
const [eventQueue] = React.useState(() => new rapier3dCompat.EventQueue(false)); // Init world
|
320
332
|
|
321
333
|
React.useLayoutEffect(() => {
|
322
334
|
const world = getWorldRef.current();
|
@@ -336,10 +348,27 @@ const Physics = ({
|
|
336
348
|
const now = performance.now();
|
337
349
|
const delta = Math.min(100, now - time.current);
|
338
350
|
world.timestep = delta / 1000;
|
339
|
-
world.step(); // Update meshes
|
351
|
+
world.step(eventQueue); // Update meshes
|
340
352
|
|
341
353
|
rigidBodyMeshes.forEach((mesh, handle) => {
|
342
354
|
const rigidBody = world.getRigidBody(handle);
|
355
|
+
const events = rigidBodyEvents.get(handle);
|
356
|
+
|
357
|
+
if (events !== null && events !== void 0 && events.onSleep || events !== null && events !== void 0 && events.onWake) {
|
358
|
+
if (rigidBody.isSleeping() && !mesh.userData.isSleeping) {
|
359
|
+
var _events$onSleep;
|
360
|
+
|
361
|
+
events === null || events === void 0 ? void 0 : (_events$onSleep = events.onSleep) === null || _events$onSleep === void 0 ? void 0 : _events$onSleep.call(events);
|
362
|
+
}
|
363
|
+
|
364
|
+
if (!rigidBody.isSleeping() && mesh.userData.isSleeping) {
|
365
|
+
var _events$onWake;
|
366
|
+
|
367
|
+
events === null || events === void 0 ? void 0 : (_events$onWake = events.onWake) === null || _events$onWake === void 0 ? void 0 : _events$onWake.call(events);
|
368
|
+
}
|
369
|
+
|
370
|
+
mesh.userData.isSleeping = rigidBody.isSleeping();
|
371
|
+
}
|
343
372
|
|
344
373
|
if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !mesh.parent) {
|
345
374
|
return;
|
@@ -367,6 +396,48 @@ const Physics = ({
|
|
367
396
|
o.updateMatrix();
|
368
397
|
mesh.position.setFromMatrixPosition(o.matrix);
|
369
398
|
mesh.rotation.setFromRotationMatrix(o.matrix);
|
399
|
+
}); // Collision events
|
400
|
+
|
401
|
+
eventQueue.drainCollisionEvents((handle1, handle2, started) => {
|
402
|
+
const collider1 = world.getCollider(handle1);
|
403
|
+
const collider2 = world.getCollider(handle2);
|
404
|
+
const rigidBodyHandle1 = collider1.parent();
|
405
|
+
const rigidBodyHandle2 = collider2.parent();
|
406
|
+
|
407
|
+
if (!collider1 || !collider2 || !rigidBodyHandle1 || !rigidBodyHandle2) {
|
408
|
+
return;
|
409
|
+
}
|
410
|
+
|
411
|
+
const rigidBody1 = world.getRigidBody(rigidBodyHandle1);
|
412
|
+
const rigidBody2 = world.getRigidBody(rigidBodyHandle2);
|
413
|
+
const events1 = rigidBodyEvents.get(rigidBodyHandle1);
|
414
|
+
const events2 = rigidBodyEvents.get(rigidBodyHandle2);
|
415
|
+
|
416
|
+
if (started) {
|
417
|
+
world.contactPair(handle1, handle2, (manifold, flipped) => {
|
418
|
+
var _events1$onCollisionE, _events2$onCollisionE;
|
419
|
+
|
420
|
+
events1 === null || events1 === void 0 ? void 0 : (_events1$onCollisionE = events1.onCollisionEnter) === null || _events1$onCollisionE === void 0 ? void 0 : _events1$onCollisionE.call(events1, {
|
421
|
+
target: rigidBody2,
|
422
|
+
manifold,
|
423
|
+
flipped
|
424
|
+
});
|
425
|
+
events2 === null || events2 === void 0 ? void 0 : (_events2$onCollisionE = events2.onCollisionEnter) === null || _events2$onCollisionE === void 0 ? void 0 : _events2$onCollisionE.call(events2, {
|
426
|
+
target: rigidBody1,
|
427
|
+
manifold,
|
428
|
+
flipped
|
429
|
+
});
|
430
|
+
});
|
431
|
+
} else {
|
432
|
+
var _events1$onCollisionE2, _events2$onCollisionE2;
|
433
|
+
|
434
|
+
events1 === null || events1 === void 0 ? void 0 : (_events1$onCollisionE2 = events1.onCollisionExit) === null || _events1$onCollisionE2 === void 0 ? void 0 : _events1$onCollisionE2.call(events1, {
|
435
|
+
target: rigidBody2
|
436
|
+
});
|
437
|
+
events2 === null || events2 === void 0 ? void 0 : (_events2$onCollisionE2 = events2.onCollisionExit) === null || _events2$onCollisionE2 === void 0 ? void 0 : _events2$onCollisionE2.call(events2, {
|
438
|
+
target: rigidBody1
|
439
|
+
});
|
440
|
+
}
|
370
441
|
});
|
371
442
|
time.current = now;
|
372
443
|
});
|
@@ -379,7 +450,8 @@ const Physics = ({
|
|
379
450
|
gravity: _gravity
|
380
451
|
},
|
381
452
|
colliderMeshes,
|
382
|
-
rigidBodyMeshes
|
453
|
+
rigidBodyMeshes,
|
454
|
+
rigidBodyEvents
|
383
455
|
}), []);
|
384
456
|
return /*#__PURE__*/React__default["default"].createElement(RapierContext.Provider, {
|
385
457
|
value: context
|
@@ -435,7 +507,8 @@ const useRigidBody = (options = {}) => {
|
|
435
507
|
rapier,
|
436
508
|
world,
|
437
509
|
rigidBodyMeshes,
|
438
|
-
physicsOptions
|
510
|
+
physicsOptions,
|
511
|
+
rigidBodyEvents
|
439
512
|
} = useRapier();
|
440
513
|
const ref = React.useRef(); // Create rigidbody
|
441
514
|
|
@@ -470,9 +543,11 @@ const useRigidBody = (options = {}) => {
|
|
470
543
|
|
471
544
|
if (!ref.current) {
|
472
545
|
ref.current = new three.Object3D();
|
473
|
-
} //
|
546
|
+
} // isSleeping used for onSleep and onWake events
|
474
547
|
|
475
548
|
|
549
|
+
ref.current.userData.isSleeping = false; // Get intitial world transforms
|
550
|
+
|
476
551
|
const worldPosition = ref.current.getWorldPosition(new three.Vector3());
|
477
552
|
const worldRotation = ref.current.getWorldQuaternion(new three.Quaternion());
|
478
553
|
const scale = ((_ref$current$parent = ref.current.parent) === null || _ref$current$parent === void 0 ? void 0 : _ref$current$parent.getWorldScale(new three.Vector3())) || {
|
@@ -500,7 +575,8 @@ const useRigidBody = (options = {}) => {
|
|
500
575
|
rigidBody.resetForces(false);
|
501
576
|
rigidBody.resetTorques(false);
|
502
577
|
const colliderSetting = (_ref = (_options$colliders = options === null || options === void 0 ? void 0 : options.colliders) !== null && _options$colliders !== void 0 ? _options$colliders : physicsOptions.colliders) !== null && _ref !== void 0 ? _ref : false;
|
503
|
-
const
|
578
|
+
const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
|
579
|
+
const autoColliders = colliderSetting !== false ? createCollidersFromChildren(ref.current, rigidBody, colliderSetting, world, hasCollisionEvents) : [];
|
504
580
|
rigidBody.wakeUp();
|
505
581
|
rigidBodyMeshes.set(rigidBody.handle, ref.current);
|
506
582
|
return () => {
|
@@ -509,7 +585,20 @@ const useRigidBody = (options = {}) => {
|
|
509
585
|
rigidBodyRef.current = undefined;
|
510
586
|
rigidBodyMeshes.delete(rigidBody.handle);
|
511
587
|
};
|
512
|
-
}, []);
|
588
|
+
}, []); // Events
|
589
|
+
|
590
|
+
React.useEffect(() => {
|
591
|
+
const rigidBody = getRigidBodyRef.current();
|
592
|
+
rigidBodyEvents.set(rigidBody.handle, {
|
593
|
+
onCollisionEnter: options === null || options === void 0 ? void 0 : options.onCollisionEnter,
|
594
|
+
onCollisionExit: options === null || options === void 0 ? void 0 : options.onCollisionExit,
|
595
|
+
onSleep: options === null || options === void 0 ? void 0 : options.onSleep,
|
596
|
+
onWake: options === null || options === void 0 ? void 0 : options.onWake
|
597
|
+
});
|
598
|
+
return () => {
|
599
|
+
rigidBodyEvents.delete(rigidBody.handle);
|
600
|
+
};
|
601
|
+
}, [options.onCollisionEnter, options.onCollisionExit]);
|
513
602
|
const api = React.useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
|
514
603
|
return [ref, api];
|
515
604
|
};
|
@@ -823,7 +912,7 @@ const _excluded = ["children"],
|
|
823
912
|
_excluded2 = ["children"];
|
824
913
|
const RigidBodyContext = /*#__PURE__*/React.createContext(undefined);
|
825
914
|
|
826
|
-
const
|
915
|
+
const useRigidBodyContext = () => React.useContext(RigidBodyContext); // RigidBody
|
827
916
|
|
828
917
|
|
829
918
|
const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
@@ -835,7 +924,7 @@ const RigidBody = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
835
924
|
const [object, rigidBody] = useRigidBody(props);
|
836
925
|
React.useImperativeHandle(ref, () => rigidBody);
|
837
926
|
return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
|
838
|
-
value: [object, rigidBody]
|
927
|
+
value: [object, rigidBody, !!(props.onCollisionEnter || props.onCollisionExit)]
|
839
928
|
}, /*#__PURE__*/React__default["default"].createElement("object3D", {
|
840
929
|
ref: object
|
841
930
|
}, children));
|
@@ -850,11 +939,11 @@ const AnyCollider = _ref2 => {
|
|
850
939
|
const {
|
851
940
|
world
|
852
941
|
} = useRapier();
|
853
|
-
const [, rigidBody] =
|
942
|
+
const [, rigidBody, hasCollisionEvents] = useRigidBodyContext();
|
854
943
|
const ref = React.useRef(null);
|
855
944
|
React.useEffect(() => {
|
856
945
|
const scale = ref.current.getWorldScale(new three.Vector3());
|
857
|
-
const collider = createColliderFromOptions(props, world, rigidBody.handle, scale);
|
946
|
+
const collider = createColliderFromOptions(props, world, rigidBody.handle, scale, hasCollisionEvents);
|
858
947
|
return () => {
|
859
948
|
world.removeCollider(collider);
|
860
949
|
};
|
@@ -1,9 +1,9 @@
|
|
1
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 {
|
5
|
-
import { ColliderDesc, CoefficientCombineRule, ShapeType } from '@dimforge/rapier3d-compat';
|
4
|
+
import { ColliderDesc, CoefficientCombineRule, ActiveEvents, EventQueue, ShapeType } from '@dimforge/rapier3d-compat';
|
6
5
|
export { CoefficientCombineRule, Collider as RapierCollider, RigidBody as RapierRigidBody } from '@dimforge/rapier3d-compat';
|
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;
|
@@ -42,7 +42,7 @@ 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, rigidBodyHandle, 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);
|
@@ -83,7 +88,7 @@ const createColliderFromOptions = (options, world, rigidBodyHandle, scale = {
|
|
83
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;
|
89
94
|
let offset = new Vector3();
|
@@ -156,6 +161,11 @@ const createCollidersFromChildren = (object, rigidBody, type, world) => {
|
|
156
161
|
z: rz,
|
157
162
|
w: rw
|
158
163
|
});
|
164
|
+
|
165
|
+
if (hasCollisionEvents) {
|
166
|
+
desc.setActiveEvents(ActiveEvents.COLLISION_EVENTS);
|
167
|
+
}
|
168
|
+
|
159
169
|
const collider = world.createCollider(desc, rigidBody.handle);
|
160
170
|
colliders.push(collider);
|
161
171
|
}
|
@@ -291,7 +301,9 @@ const Physics = ({
|
|
291
301
|
return worldRef.current;
|
292
302
|
});
|
293
303
|
const [colliderMeshes] = useState(() => new Map());
|
294
|
-
const [rigidBodyMeshes] = useState(() => new Map());
|
304
|
+
const [rigidBodyMeshes] = useState(() => new Map());
|
305
|
+
const [rigidBodyEvents] = useState(() => new Map());
|
306
|
+
const [eventQueue] = useState(() => new EventQueue(false)); // Init world
|
295
307
|
|
296
308
|
useLayoutEffect(() => {
|
297
309
|
const world = getWorldRef.current();
|
@@ -311,10 +323,27 @@ const Physics = ({
|
|
311
323
|
const now = performance.now();
|
312
324
|
const delta = Math.min(100, now - time.current);
|
313
325
|
world.timestep = delta / 1000;
|
314
|
-
world.step(); // Update meshes
|
326
|
+
world.step(eventQueue); // Update meshes
|
315
327
|
|
316
328
|
rigidBodyMeshes.forEach((mesh, handle) => {
|
317
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;
|
341
|
+
|
342
|
+
events === null || events === void 0 ? void 0 : (_events$onWake = events.onWake) === null || _events$onWake === void 0 ? void 0 : _events$onWake.call(events);
|
343
|
+
}
|
344
|
+
|
345
|
+
mesh.userData.isSleeping = rigidBody.isSleeping();
|
346
|
+
}
|
318
347
|
|
319
348
|
if (!rigidBody || rigidBody.isSleeping() || rigidBody.isFixed() || !mesh.parent) {
|
320
349
|
return;
|
@@ -342,6 +371,48 @@ const Physics = ({
|
|
342
371
|
o.updateMatrix();
|
343
372
|
mesh.position.setFromMatrixPosition(o.matrix);
|
344
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
|
+
}
|
345
416
|
});
|
346
417
|
time.current = now;
|
347
418
|
});
|
@@ -354,7 +425,8 @@ const Physics = ({
|
|
354
425
|
gravity: _gravity
|
355
426
|
},
|
356
427
|
colliderMeshes,
|
357
|
-
rigidBodyMeshes
|
428
|
+
rigidBodyMeshes,
|
429
|
+
rigidBodyEvents
|
358
430
|
}), []);
|
359
431
|
return /*#__PURE__*/React.createElement(RapierContext.Provider, {
|
360
432
|
value: context
|
@@ -410,7 +482,8 @@ const useRigidBody = (options = {}) => {
|
|
410
482
|
rapier,
|
411
483
|
world,
|
412
484
|
rigidBodyMeshes,
|
413
|
-
physicsOptions
|
485
|
+
physicsOptions,
|
486
|
+
rigidBodyEvents
|
414
487
|
} = useRapier();
|
415
488
|
const ref = useRef(); // Create rigidbody
|
416
489
|
|
@@ -445,8 +518,10 @@ const useRigidBody = (options = {}) => {
|
|
445
518
|
|
446
519
|
if (!ref.current) {
|
447
520
|
ref.current = new Object3D();
|
448
|
-
} //
|
521
|
+
} // isSleeping used for onSleep and onWake events
|
522
|
+
|
449
523
|
|
524
|
+
ref.current.userData.isSleeping = false; // Get intitial world transforms
|
450
525
|
|
451
526
|
const worldPosition = ref.current.getWorldPosition(new Vector3());
|
452
527
|
const worldRotation = ref.current.getWorldQuaternion(new Quaternion());
|
@@ -475,7 +550,8 @@ const useRigidBody = (options = {}) => {
|
|
475
550
|
rigidBody.resetForces(false);
|
476
551
|
rigidBody.resetTorques(false);
|
477
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;
|
478
|
-
const
|
553
|
+
const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
|
554
|
+
const autoColliders = colliderSetting !== false ? createCollidersFromChildren(ref.current, rigidBody, colliderSetting, world, hasCollisionEvents) : [];
|
479
555
|
rigidBody.wakeUp();
|
480
556
|
rigidBodyMeshes.set(rigidBody.handle, ref.current);
|
481
557
|
return () => {
|
@@ -484,7 +560,20 @@ const useRigidBody = (options = {}) => {
|
|
484
560
|
rigidBodyRef.current = undefined;
|
485
561
|
rigidBodyMeshes.delete(rigidBody.handle);
|
486
562
|
};
|
487
|
-
}, []);
|
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]);
|
488
577
|
const api = useMemo(() => createRigidBodyApi(getRigidBodyRef), []);
|
489
578
|
return [ref, api];
|
490
579
|
};
|
@@ -798,7 +887,7 @@ const _excluded = ["children"],
|
|
798
887
|
_excluded2 = ["children"];
|
799
888
|
const RigidBodyContext = /*#__PURE__*/createContext(undefined);
|
800
889
|
|
801
|
-
const
|
890
|
+
const useRigidBodyContext = () => useContext(RigidBodyContext); // RigidBody
|
802
891
|
|
803
892
|
|
804
893
|
const RigidBody = /*#__PURE__*/forwardRef((_ref, ref) => {
|
@@ -810,7 +899,7 @@ const RigidBody = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
810
899
|
const [object, rigidBody] = useRigidBody(props);
|
811
900
|
useImperativeHandle(ref, () => rigidBody);
|
812
901
|
return /*#__PURE__*/React.createElement(RigidBodyContext.Provider, {
|
813
|
-
value: [object, rigidBody]
|
902
|
+
value: [object, rigidBody, !!(props.onCollisionEnter || props.onCollisionExit)]
|
814
903
|
}, /*#__PURE__*/React.createElement("object3D", {
|
815
904
|
ref: object
|
816
905
|
}, children));
|
@@ -825,11 +914,11 @@ const AnyCollider = _ref2 => {
|
|
825
914
|
const {
|
826
915
|
world
|
827
916
|
} = useRapier();
|
828
|
-
const [, rigidBody] =
|
917
|
+
const [, rigidBody, hasCollisionEvents] = useRigidBodyContext();
|
829
918
|
const ref = useRef(null);
|
830
919
|
useEffect(() => {
|
831
920
|
const scale = ref.current.getWorldScale(new Vector3());
|
832
|
-
const collider = createColliderFromOptions(props, world, rigidBody.handle, scale);
|
921
|
+
const collider = createColliderFromOptions(props, world, rigidBody.handle, scale, hasCollisionEvents);
|
833
922
|
return () => {
|
834
923
|
world.removeCollider(collider);
|
835
924
|
};
|