@react-three/rapier 0.6.1 → 0.6.4
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/InstancedRigidBodies.d.ts +2 -2
- package/dist/declarations/src/Physics.d.ts +8 -1
- package/dist/declarations/src/RigidBody.d.ts +12 -4
- package/dist/declarations/src/api.d.ts +16 -0
- package/dist/declarations/src/types.d.ts +6 -2
- package/dist/declarations/src/utils.d.ts +12 -7
- package/dist/react-three-rapier.cjs.dev.js +133 -51
- package/dist/react-three-rapier.cjs.prod.js +133 -51
- package/dist/react-three-rapier.esm.js +134 -52
- package/package.json +1 -1
- package/readme.md +19 -2
@@ -2,9 +2,9 @@ import React from "react";
|
|
2
2
|
import { InstancedRigidBodyApi } from "./api";
|
3
3
|
import { RigidBodyProps } from "./RigidBody";
|
4
4
|
import { Vector3Array } from "./types";
|
5
|
-
interface InstancedRigidBodiesProps extends Omit<RigidBodyProps, "position" | "rotation" | "onCollisionEnter" | "onCollisionExit"> {
|
5
|
+
export interface InstancedRigidBodiesProps extends Omit<RigidBodyProps, "position" | "rotation" | "onCollisionEnter" | "onCollisionExit"> {
|
6
6
|
positions?: Vector3Array[];
|
7
7
|
rotations?: Vector3Array[];
|
8
|
+
scales?: Vector3Array[];
|
8
9
|
}
|
9
10
|
export declare const InstancedRigidBodies: React.ForwardRefExoticComponent<InstancedRigidBodiesProps & React.RefAttributes<InstancedRigidBodyApi>>;
|
10
|
-
export {};
|
@@ -10,7 +10,8 @@ export interface RapierContext {
|
|
10
10
|
rigidBodyStates: Map<RigidBodyHandle, {
|
11
11
|
mesh: Object3D;
|
12
12
|
isSleeping: boolean;
|
13
|
-
setMatrix
|
13
|
+
setMatrix(mat: Matrix4): void;
|
14
|
+
getMatrix(): Matrix4;
|
14
15
|
worldScale: Vector3;
|
15
16
|
invertedMatrixWorld: Matrix4;
|
16
17
|
}>;
|
@@ -58,6 +59,12 @@ interface RapierWorldProps {
|
|
58
59
|
* @defaultValue "vary"
|
59
60
|
*/
|
60
61
|
timeStep?: number | "vary";
|
62
|
+
/**
|
63
|
+
* Pause the physics simulation
|
64
|
+
*
|
65
|
+
* @defaultValue false
|
66
|
+
*/
|
67
|
+
paused?: boolean;
|
61
68
|
}
|
62
69
|
export declare const Physics: FC<RapierWorldProps>;
|
63
70
|
export {};
|
@@ -1,12 +1,20 @@
|
|
1
|
-
import React, { MutableRefObject } from "react";
|
1
|
+
import React, { MutableRefObject, RefObject } from "react";
|
2
2
|
import { ReactNode } from "react";
|
3
3
|
import { Object3D } from "three";
|
4
|
+
import { InstancedRigidBodyApi } from "./api";
|
5
|
+
import { InstancedRigidBodiesProps } from "./InstancedRigidBodies";
|
4
6
|
import { RigidBodyApi, UseRigidBodyOptions } from "./types";
|
7
|
+
export declare const RigidBodyContext: React.Context<{
|
8
|
+
ref: RefObject<Object3D> | MutableRefObject<Object3D>;
|
9
|
+
api: RigidBodyApi | InstancedRigidBodyApi;
|
10
|
+
hasCollisionEvents: boolean;
|
11
|
+
options: UseRigidBodyOptions | InstancedRigidBodiesProps;
|
12
|
+
}>;
|
5
13
|
export declare const useRigidBodyContext: () => {
|
6
|
-
ref: MutableRefObject<Object3D>;
|
7
|
-
api: RigidBodyApi;
|
14
|
+
ref: RefObject<Object3D> | MutableRefObject<Object3D>;
|
15
|
+
api: RigidBodyApi | InstancedRigidBodyApi;
|
8
16
|
hasCollisionEvents: boolean;
|
9
|
-
options: UseRigidBodyOptions;
|
17
|
+
options: UseRigidBodyOptions | InstancedRigidBodiesProps;
|
10
18
|
};
|
11
19
|
export interface RigidBodyProps extends UseRigidBodyOptions {
|
12
20
|
children?: ReactNode;
|
@@ -75,6 +75,22 @@ export interface RigidBodyApi {
|
|
75
75
|
* Sets the angular velocity of this rigid-body.
|
76
76
|
*/
|
77
77
|
setAngvel(velocity: Vector3Object): void;
|
78
|
+
/**
|
79
|
+
* The linear damping of this rigid-body.
|
80
|
+
*/
|
81
|
+
linearDamping(): number;
|
82
|
+
/**
|
83
|
+
* Sets the linear damping factor applied to this rigid-body.
|
84
|
+
*/
|
85
|
+
setLinearDamping(factor: number): void;
|
86
|
+
/**
|
87
|
+
* The angular damping of this rigid-body.
|
88
|
+
*/
|
89
|
+
angularDamping(): number;
|
90
|
+
/**
|
91
|
+
* Sets the anugular damping factor applied to this rigid-body.
|
92
|
+
*/
|
93
|
+
setAngularDamping(factor: number): void;
|
78
94
|
/**
|
79
95
|
* If this rigid body is kinematic, sets its future rotation after the next timestep integration.
|
80
96
|
*
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import { MutableRefObject } from "react";
|
2
|
-
import { CoefficientCombineRule,
|
2
|
+
import { CoefficientCombineRule, Collider as RapierCollider, RigidBody as RapierRigidBody, TempContactManifold } from "@dimforge/rapier3d-compat";
|
3
3
|
import { createColliderApi, createJointApi, createRigidBodyApi, createWorldApi } from "./api";
|
4
|
-
export { RapierRigidBody, RapierCollider };
|
5
4
|
export { CoefficientCombineRule as CoefficientCombineRule } from "@dimforge/rapier3d-compat";
|
5
|
+
export { RapierRigidBody, RapierCollider };
|
6
6
|
export declare type RefGetter<T> = MutableRefObject<() => T | undefined>;
|
7
7
|
export declare type RigidBodyAutoCollider = "ball" | "cuboid" | "hull" | "trimesh" | false;
|
8
8
|
export interface UseRigidBodyAPI {
|
@@ -126,6 +126,10 @@ export interface UseRigidBodyOptions {
|
|
126
126
|
* default: true
|
127
127
|
*/
|
128
128
|
canSleep?: boolean;
|
129
|
+
/** The linear damping coefficient of this rigid-body.*/
|
130
|
+
linearDamping?: number;
|
131
|
+
/** The angular damping coefficient of this rigid-body.*/
|
132
|
+
angularDamping?: number;
|
129
133
|
/** The linear velocity of this body.
|
130
134
|
* default: zero velocity
|
131
135
|
*/
|
@@ -1,11 +1,7 @@
|
|
1
|
-
import { Collider, ColliderDesc, RigidBody, RigidBodyDesc, Vector3 as RapierVector3
|
1
|
+
import { Collider, ColliderDesc, Quaternion as RapierQuaternion, RigidBody, RigidBodyDesc, Vector3 as RapierVector3 } from "@dimforge/rapier3d-compat";
|
2
2
|
import { BufferGeometry, Matrix4, Object3D, Quaternion, Vector3 } from "three";
|
3
3
|
import { RigidBodyApi, RigidBodyAutoCollider, RigidBodyShape, RigidBodyTypeString, UseColliderOptions, UseRigidBodyOptions, Vector3Array, WorldApi } from "./types";
|
4
|
-
export declare const
|
5
|
-
x: number;
|
6
|
-
y: number;
|
7
|
-
z: number;
|
8
|
-
};
|
4
|
+
export declare const vectorArrayToVector3: (arr: Vector3Array) => Vector3;
|
9
5
|
export declare const vector3ToQuaternion: (v: Vector3) => Quaternion;
|
10
6
|
export declare const rapierVector3ToVector3: ({ x, y, z }: RapierVector3) => Vector3;
|
11
7
|
export declare const rapierQuaternionToQuaternion: ({ x, y, z, w, }: RapierQuaternion) => Quaternion;
|
@@ -30,7 +26,16 @@ interface CreateColliderFromOptions {
|
|
30
26
|
}): Collider;
|
31
27
|
}
|
32
28
|
export declare const createColliderFromOptions: CreateColliderFromOptions;
|
33
|
-
|
29
|
+
interface CreateCollidersFromChildren {
|
30
|
+
(options: {
|
31
|
+
object: Object3D;
|
32
|
+
rigidBody?: Pick<RigidBodyApi | RigidBody, "handle">;
|
33
|
+
options: UseRigidBodyOptions;
|
34
|
+
world: WorldApi;
|
35
|
+
ignoreMeshColliders: boolean;
|
36
|
+
}): Collider[];
|
37
|
+
}
|
38
|
+
export declare const createCollidersFromChildren: CreateCollidersFromChildren;
|
34
39
|
export declare const colliderDescFromGeometry: (geometry: BufferGeometry, colliders: RigidBodyAutoCollider, scale: Vector3, hasCollisionEvents: boolean) => ColliderDesc;
|
35
40
|
export declare const scaleVertices: (vertices: ArrayLike<number>, scale: Vector3) => number[];
|
36
41
|
export declare const rigidBodyDescFromOptions: (options: UseRigidBodyOptions) => RigidBodyDesc;
|
@@ -36,13 +36,9 @@ const _vector3 = new three.Vector3();
|
|
36
36
|
new three.Object3D();
|
37
37
|
const _matrix4 = new three.Matrix4();
|
38
38
|
|
39
|
-
const
|
39
|
+
const vectorArrayToVector3 = arr => {
|
40
40
|
const [x, y, z] = arr;
|
41
|
-
return
|
42
|
-
x,
|
43
|
-
y,
|
44
|
-
z
|
45
|
-
};
|
41
|
+
return new three.Vector3(x, y, z);
|
46
42
|
};
|
47
43
|
const vector3ToQuaternion = v => {
|
48
44
|
return _quaternion.setFromEuler(_euler.setFromVector3(v));
|
@@ -158,13 +154,19 @@ const isChildOfMeshCollider = child => {
|
|
158
154
|
return flag;
|
159
155
|
};
|
160
156
|
|
161
|
-
const createCollidersFromChildren = (
|
157
|
+
const createCollidersFromChildren = ({
|
158
|
+
object,
|
159
|
+
rigidBody,
|
160
|
+
options,
|
161
|
+
world,
|
162
|
+
ignoreMeshColliders: _ignoreMeshColliders = true
|
163
|
+
}) => {
|
162
164
|
const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
|
163
165
|
const colliders = [];
|
164
166
|
new three.Vector3();
|
165
|
-
object.
|
167
|
+
object.traverseVisible(child => {
|
166
168
|
if ("isMesh" in child) {
|
167
|
-
if (
|
169
|
+
if (_ignoreMeshColliders && isChildOfMeshCollider(child)) return;
|
168
170
|
const {
|
169
171
|
geometry
|
170
172
|
} = child;
|
@@ -205,7 +207,7 @@ const createCollidersFromChildren = (object, rigidBody, options, world, ignoreMe
|
|
205
207
|
z: rz,
|
206
208
|
w: rw
|
207
209
|
});
|
208
|
-
const actualRigidBody = world.getRigidBody(rigidBody
|
210
|
+
const actualRigidBody = rigidBody ? world.getRigidBody(rigidBody.handle) : undefined;
|
209
211
|
const collider = world.createCollider(desc, actualRigidBody);
|
210
212
|
colliders.push(collider);
|
211
213
|
}
|
@@ -271,11 +273,13 @@ const scaleVertices = (vertices, scale) => {
|
|
271
273
|
return scaledVerts;
|
272
274
|
};
|
273
275
|
const rigidBodyDescFromOptions = options => {
|
274
|
-
var _options$linearVeloci, _options$angularVeloc, _options$gravityScale, _options$canSleep, _options$ccd, _options$enabledRotat, _options$enabledTrans;
|
276
|
+
var _options$linearVeloci, _options$angularVeloc, _options$angularDampi, _options$linearDampin, _options$gravityScale, _options$canSleep, _options$ccd, _options$enabledRotat, _options$enabledTrans;
|
275
277
|
|
276
278
|
const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
|
277
279
|
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];
|
278
280
|
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];
|
281
|
+
const angularDamping = (_options$angularDampi = options === null || options === void 0 ? void 0 : options.angularDamping) !== null && _options$angularDampi !== void 0 ? _options$angularDampi : 0;
|
282
|
+
const linearDamping = (_options$linearDampin = options === null || options === void 0 ? void 0 : options.linearDamping) !== null && _options$linearDampin !== void 0 ? _options$linearDampin : 0;
|
279
283
|
const gravityScale = (_options$gravityScale = options === null || options === void 0 ? void 0 : options.gravityScale) !== null && _options$gravityScale !== void 0 ? _options$gravityScale : 1;
|
280
284
|
const canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
|
281
285
|
const ccdEnabled = (_options$ccd = options === null || options === void 0 ? void 0 : options.ccd) !== null && _options$ccd !== void 0 ? _options$ccd : false;
|
@@ -285,7 +289,7 @@ const rigidBodyDescFromOptions = options => {
|
|
285
289
|
x: avx,
|
286
290
|
y: avy,
|
287
291
|
z: avz
|
288
|
-
}).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled).enabledRotations(erx, ery, erz).enabledTranslations(etx, ety, etz);
|
292
|
+
}).setLinearDamping(linearDamping).setAngularDamping(angularDamping).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled).enabledRotations(erx, ery, erz).enabledTranslations(etx, ety, etz);
|
289
293
|
if (options.lockRotations) desc.lockRotations();
|
290
294
|
if (options.lockTranslations) desc.lockTranslations();
|
291
295
|
return desc;
|
@@ -370,6 +374,18 @@ const createRigidBodyApi = ref => {
|
|
370
374
|
},
|
371
375
|
|
372
376
|
setAngvel: velocity => ref.current().setAngvel(velocity, true),
|
377
|
+
|
378
|
+
linearDamping() {
|
379
|
+
return ref.current().linearDamping();
|
380
|
+
},
|
381
|
+
|
382
|
+
setLinearDamping: factor => ref.current().setLinearDamping(factor),
|
383
|
+
|
384
|
+
angularDamping() {
|
385
|
+
return ref.current().angularDamping();
|
386
|
+
},
|
387
|
+
|
388
|
+
setAngularDamping: factor => ref.current().setAngularDamping(factor),
|
373
389
|
setNextKinematicRotation: ({
|
374
390
|
x,
|
375
391
|
y,
|
@@ -453,13 +469,14 @@ const Physics = ({
|
|
453
469
|
colliders: _colliders = "cuboid",
|
454
470
|
gravity: _gravity = [0, -9.81, 0],
|
455
471
|
children,
|
456
|
-
timeStep: _timeStep = "vary"
|
472
|
+
timeStep: _timeStep = "vary",
|
473
|
+
paused: _paused = false
|
457
474
|
}) => {
|
458
475
|
const rapier = useAsset.useAsset(importRapier);
|
459
476
|
const worldRef = React.useRef();
|
460
477
|
const getWorldRef = React.useRef(() => {
|
461
478
|
if (!worldRef.current) {
|
462
|
-
const world = new rapier.World(
|
479
|
+
const world = new rapier.World(vectorArrayToVector3(_gravity));
|
463
480
|
worldRef.current = world;
|
464
481
|
}
|
465
482
|
|
@@ -484,7 +501,7 @@ const Physics = ({
|
|
484
501
|
const world = worldRef.current;
|
485
502
|
|
486
503
|
if (world) {
|
487
|
-
world.gravity =
|
504
|
+
world.gravity = vectorArrayToVector3(_gravity);
|
488
505
|
}
|
489
506
|
}, [_gravity]);
|
490
507
|
const time = React.useRef(performance.now());
|
@@ -502,7 +519,7 @@ const Physics = ({
|
|
502
519
|
world.timestep = _timeStep;
|
503
520
|
}
|
504
521
|
|
505
|
-
world.step(eventQueue); // Update meshes
|
522
|
+
if (!_paused) world.step(eventQueue); // Update meshes
|
506
523
|
|
507
524
|
rigidBodyStates.forEach((state, handle) => {
|
508
525
|
const rigidBody = world.getRigidBody(handle);
|
@@ -734,15 +751,22 @@ const useRigidBody = (options = {}) => {
|
|
734
751
|
rigidBody.resetForces(false);
|
735
752
|
rigidBody.resetTorques(false);
|
736
753
|
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;
|
737
|
-
const autoColliders = colliderSetting !== false ? createCollidersFromChildren(
|
738
|
-
|
739
|
-
|
754
|
+
const autoColliders = colliderSetting !== false ? createCollidersFromChildren({
|
755
|
+
object: ref.current,
|
756
|
+
rigidBody,
|
757
|
+
options: _objectSpread2(_objectSpread2({}, options), {}, {
|
758
|
+
colliders: colliderSetting
|
759
|
+
}),
|
760
|
+
world,
|
761
|
+
ignoreMeshColliders: true
|
762
|
+
}) : [];
|
740
763
|
rigidBodyStates.set(rigidBody.handle, {
|
741
764
|
mesh: ref.current,
|
742
765
|
invertedMatrixWorld: ref.current.parent.matrixWorld.clone().invert(),
|
743
766
|
isSleeping: false,
|
744
767
|
worldScale: ref.current.getWorldScale(_vector3).clone(),
|
745
|
-
setMatrix: mat => ref.current.matrix.copy(mat)
|
768
|
+
setMatrix: mat => ref.current.matrix.copy(mat),
|
769
|
+
getMatrix: () => ref.current.matrix
|
746
770
|
});
|
747
771
|
ref.current.matrixAutoUpdate = false;
|
748
772
|
return () => {
|
@@ -812,9 +836,9 @@ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor,
|
|
812
836
|
const {
|
813
837
|
rapier
|
814
838
|
} = useRapier();
|
815
|
-
return useImpulseJoint(body1, body2, rapier.JointData.fixed(
|
839
|
+
return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToVector3(body1Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body1LocalFrame)), {}, {
|
816
840
|
w: 1
|
817
|
-
}),
|
841
|
+
}), vectorArrayToVector3(body2Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body2LocalFrame)), {}, {
|
818
842
|
w: 1
|
819
843
|
})));
|
820
844
|
};
|
@@ -829,7 +853,7 @@ const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
|
829
853
|
const {
|
830
854
|
rapier
|
831
855
|
} = useRapier();
|
832
|
-
return useImpulseJoint(body1, body2, rapier.JointData.spherical(
|
856
|
+
return useImpulseJoint(body1, body2, rapier.JointData.spherical(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor)));
|
833
857
|
};
|
834
858
|
/**
|
835
859
|
* The revolute joint prevents any relative movement between two rigid-bodies, except for relative
|
@@ -841,7 +865,7 @@ const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
|
841
865
|
const {
|
842
866
|
rapier
|
843
867
|
} = useRapier();
|
844
|
-
return useImpulseJoint(body1, body2, rapier.JointData.revolute(
|
868
|
+
return useImpulseJoint(body1, body2, rapier.JointData.revolute(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
|
845
869
|
};
|
846
870
|
/**
|
847
871
|
* The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
|
@@ -853,7 +877,7 @@ const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
|
853
877
|
const {
|
854
878
|
rapier
|
855
879
|
} = useRapier();
|
856
|
-
return useImpulseJoint(body1, body2, rapier.JointData.prismatic(
|
880
|
+
return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
|
857
881
|
};
|
858
882
|
|
859
883
|
const _excluded$1 = ["children"];
|
@@ -900,9 +924,18 @@ const MeshCollider = ({
|
|
900
924
|
var _ref;
|
901
925
|
|
902
926
|
const colliderSetting = (_ref = type !== null && type !== void 0 ? type : physicsOptions.colliders) !== null && _ref !== void 0 ? _ref : false;
|
903
|
-
|
904
|
-
|
905
|
-
|
927
|
+
|
928
|
+
if ("raw" in api) {
|
929
|
+
autoColliders = createCollidersFromChildren({
|
930
|
+
object: object.current,
|
931
|
+
rigidBody: api,
|
932
|
+
options: _objectSpread2(_objectSpread2({}, options), {}, {
|
933
|
+
colliders: colliderSetting
|
934
|
+
}),
|
935
|
+
world,
|
936
|
+
ignoreMeshColliders: false
|
937
|
+
});
|
938
|
+
}
|
906
939
|
}
|
907
940
|
|
908
941
|
return () => {
|
@@ -1049,12 +1082,12 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1049
1082
|
|
1050
1083
|
return instancesRef.current;
|
1051
1084
|
});
|
1052
|
-
React.
|
1085
|
+
React.useLayoutEffect(() => {
|
1053
1086
|
const colliders = [];
|
1054
1087
|
const rigidBodies = instancesRefGetter.current();
|
1055
1088
|
|
1056
1089
|
if (object.current) {
|
1057
|
-
const
|
1090
|
+
const worldScale = object.current.getWorldScale(new three.Vector3());
|
1058
1091
|
let hasOneMesh = false;
|
1059
1092
|
object.current.traverse(mesh => {
|
1060
1093
|
if (mesh instanceof three.InstancedMesh) {
|
@@ -1065,21 +1098,34 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1065
1098
|
|
1066
1099
|
hasOneMesh = true;
|
1067
1100
|
mesh.instanceMatrix.setUsage(three.DynamicDrawUsage);
|
1068
|
-
const rigidBodyDesc = rigidBodyDescFromOptions(props);
|
1069
|
-
const colliderDesc = colliderDescFromGeometry(mesh.geometry, props.colliders || physicsOptions.colliders, scale, false // Collisions currently not enabled for instances
|
1070
|
-
);
|
1071
1101
|
|
1072
1102
|
for (let index = 0; index < mesh.count; index++) {
|
1103
|
+
const scale = worldScale.clone();
|
1104
|
+
const rigidBodyDesc = rigidBodyDescFromOptions(props);
|
1105
|
+
|
1106
|
+
if (props.scales && props.scales[index]) {
|
1107
|
+
const s = vectorArrayToVector3(props.scales[index]);
|
1108
|
+
scale.multiply(s);
|
1109
|
+
}
|
1110
|
+
|
1073
1111
|
const rigidBody = world.createRigidBody(rigidBodyDesc);
|
1074
1112
|
const matrix = new three.Matrix4();
|
1075
1113
|
mesh.getMatrixAt(index, matrix);
|
1076
1114
|
const {
|
1077
1115
|
position,
|
1078
1116
|
rotation
|
1079
|
-
} = decomposeMatrix4(matrix);
|
1117
|
+
} = decomposeMatrix4(matrix);
|
1118
|
+
|
1119
|
+
if (props.colliders !== false) {
|
1120
|
+
const colliderDesc = colliderDescFromGeometry(mesh.geometry, props.colliders !== undefined ? props.colliders : physicsOptions.colliders, scale, false // Collisions currently not enabled for instances
|
1121
|
+
);
|
1122
|
+
const collider = world.createCollider(colliderDesc, rigidBody);
|
1123
|
+
colliders.push(collider);
|
1124
|
+
} // Set positions
|
1125
|
+
|
1080
1126
|
|
1081
1127
|
if (props.positions && props.positions[index]) {
|
1082
|
-
rigidBody.setTranslation(
|
1128
|
+
rigidBody.setTranslation(vectorArrayToVector3(props.positions[index]), true);
|
1083
1129
|
} else {
|
1084
1130
|
rigidBody.setTranslation(position, true);
|
1085
1131
|
} // Set rotations
|
@@ -1092,13 +1138,19 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1092
1138
|
rigidBody.setRotation(rotation, true);
|
1093
1139
|
}
|
1094
1140
|
|
1095
|
-
const collider = world.createCollider(colliderDesc, rigidBody);
|
1096
1141
|
rigidBodyStates.set(rigidBody.handle, {
|
1097
1142
|
mesh: mesh,
|
1098
1143
|
isSleeping: false,
|
1099
1144
|
invertedMatrixWorld: object.current.matrixWorld.clone().invert(),
|
1100
1145
|
setMatrix: matrix => mesh.setMatrixAt(index, matrix),
|
1101
|
-
|
1146
|
+
getMatrix: () => {
|
1147
|
+
const m = new three.Matrix4();
|
1148
|
+
mesh.getMatrixAt(index, m);
|
1149
|
+
return m;
|
1150
|
+
},
|
1151
|
+
// Setting the world scale to the scale here, because
|
1152
|
+
// we want the scales to be reflected by instance
|
1153
|
+
worldScale: scale
|
1102
1154
|
});
|
1103
1155
|
const api = createRigidBodyApi({
|
1104
1156
|
current() {
|
@@ -1106,7 +1158,6 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1106
1158
|
}
|
1107
1159
|
|
1108
1160
|
});
|
1109
|
-
colliders.push(collider);
|
1110
1161
|
rigidBodies.push({
|
1111
1162
|
rigidBody,
|
1112
1163
|
api
|
@@ -1125,10 +1176,19 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1125
1176
|
};
|
1126
1177
|
}
|
1127
1178
|
}, []);
|
1128
|
-
React.
|
1129
|
-
|
1179
|
+
const api = React.useMemo(() => createInstancedRigidBodiesApi(instancesRefGetter), []);
|
1180
|
+
React.useImperativeHandle(ref, () => api); // console.log(api);
|
1181
|
+
|
1182
|
+
return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
|
1183
|
+
value: {
|
1184
|
+
ref: object,
|
1185
|
+
api,
|
1186
|
+
hasCollisionEvents: false,
|
1187
|
+
options: props
|
1188
|
+
}
|
1189
|
+
}, /*#__PURE__*/React__default["default"].createElement("object3D", {
|
1130
1190
|
ref: object
|
1131
|
-
}, props.children);
|
1191
|
+
}, props.children));
|
1132
1192
|
});
|
1133
1193
|
|
1134
1194
|
function _extends() {
|
@@ -1163,18 +1223,40 @@ const AnyCollider = _ref => {
|
|
1163
1223
|
const rigidBodyContext = useRigidBodyContext();
|
1164
1224
|
const ref = React.useRef(null);
|
1165
1225
|
React.useEffect(() => {
|
1166
|
-
var _rigidBodyContext$api;
|
1167
|
-
|
1168
1226
|
const scale = ref.current.getWorldScale(new three.Vector3());
|
1169
|
-
const
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1227
|
+
const colliders = []; // If this is an InstancedRigidBody api
|
1228
|
+
|
1229
|
+
if (rigidBodyContext && "at" in rigidBodyContext.api) {
|
1230
|
+
rigidBodyContext.api.forEach((body, index) => {
|
1231
|
+
var _rigidBodyContext$opt, _rigidBodyContext$opt2;
|
1232
|
+
|
1233
|
+
let instanceScale = scale.clone();
|
1234
|
+
|
1235
|
+
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]) {
|
1236
|
+
instanceScale.multiply(vectorArrayToVector3(rigidBodyContext.options.scales[index]));
|
1237
|
+
}
|
1238
|
+
|
1239
|
+
colliders.push(createColliderFromOptions({
|
1240
|
+
options: props,
|
1241
|
+
world,
|
1242
|
+
rigidBody: body.raw(),
|
1243
|
+
scale: instanceScale,
|
1244
|
+
hasCollisionEvents: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.hasCollisionEvents
|
1245
|
+
}));
|
1246
|
+
});
|
1247
|
+
} else {
|
1248
|
+
colliders.push(createColliderFromOptions({
|
1249
|
+
options: props,
|
1250
|
+
world,
|
1251
|
+
// Initiate with a rigidbody, or undefined, because colliders can exist without a rigid body
|
1252
|
+
rigidBody: rigidBodyContext && "raw" in rigidBodyContext.api ? rigidBodyContext.api.raw() : undefined,
|
1253
|
+
scale,
|
1254
|
+
hasCollisionEvents: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.hasCollisionEvents
|
1255
|
+
}));
|
1256
|
+
}
|
1257
|
+
|
1176
1258
|
return () => {
|
1177
|
-
world.removeCollider(collider);
|
1259
|
+
colliders.forEach(collider => world.removeCollider(collider));
|
1178
1260
|
};
|
1179
1261
|
}, []);
|
1180
1262
|
return /*#__PURE__*/React__default["default"].createElement("object3D", {
|
@@ -36,13 +36,9 @@ const _vector3 = new three.Vector3();
|
|
36
36
|
new three.Object3D();
|
37
37
|
const _matrix4 = new three.Matrix4();
|
38
38
|
|
39
|
-
const
|
39
|
+
const vectorArrayToVector3 = arr => {
|
40
40
|
const [x, y, z] = arr;
|
41
|
-
return
|
42
|
-
x,
|
43
|
-
y,
|
44
|
-
z
|
45
|
-
};
|
41
|
+
return new three.Vector3(x, y, z);
|
46
42
|
};
|
47
43
|
const vector3ToQuaternion = v => {
|
48
44
|
return _quaternion.setFromEuler(_euler.setFromVector3(v));
|
@@ -158,13 +154,19 @@ const isChildOfMeshCollider = child => {
|
|
158
154
|
return flag;
|
159
155
|
};
|
160
156
|
|
161
|
-
const createCollidersFromChildren = (
|
157
|
+
const createCollidersFromChildren = ({
|
158
|
+
object,
|
159
|
+
rigidBody,
|
160
|
+
options,
|
161
|
+
world,
|
162
|
+
ignoreMeshColliders: _ignoreMeshColliders = true
|
163
|
+
}) => {
|
162
164
|
const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
|
163
165
|
const colliders = [];
|
164
166
|
new three.Vector3();
|
165
|
-
object.
|
167
|
+
object.traverseVisible(child => {
|
166
168
|
if ("isMesh" in child) {
|
167
|
-
if (
|
169
|
+
if (_ignoreMeshColliders && isChildOfMeshCollider(child)) return;
|
168
170
|
const {
|
169
171
|
geometry
|
170
172
|
} = child;
|
@@ -205,7 +207,7 @@ const createCollidersFromChildren = (object, rigidBody, options, world, ignoreMe
|
|
205
207
|
z: rz,
|
206
208
|
w: rw
|
207
209
|
});
|
208
|
-
const actualRigidBody = world.getRigidBody(rigidBody
|
210
|
+
const actualRigidBody = rigidBody ? world.getRigidBody(rigidBody.handle) : undefined;
|
209
211
|
const collider = world.createCollider(desc, actualRigidBody);
|
210
212
|
colliders.push(collider);
|
211
213
|
}
|
@@ -271,11 +273,13 @@ const scaleVertices = (vertices, scale) => {
|
|
271
273
|
return scaledVerts;
|
272
274
|
};
|
273
275
|
const rigidBodyDescFromOptions = options => {
|
274
|
-
var _options$linearVeloci, _options$angularVeloc, _options$gravityScale, _options$canSleep, _options$ccd, _options$enabledRotat, _options$enabledTrans;
|
276
|
+
var _options$linearVeloci, _options$angularVeloc, _options$angularDampi, _options$linearDampin, _options$gravityScale, _options$canSleep, _options$ccd, _options$enabledRotat, _options$enabledTrans;
|
275
277
|
|
276
278
|
const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
|
277
279
|
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];
|
278
280
|
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];
|
281
|
+
const angularDamping = (_options$angularDampi = options === null || options === void 0 ? void 0 : options.angularDamping) !== null && _options$angularDampi !== void 0 ? _options$angularDampi : 0;
|
282
|
+
const linearDamping = (_options$linearDampin = options === null || options === void 0 ? void 0 : options.linearDamping) !== null && _options$linearDampin !== void 0 ? _options$linearDampin : 0;
|
279
283
|
const gravityScale = (_options$gravityScale = options === null || options === void 0 ? void 0 : options.gravityScale) !== null && _options$gravityScale !== void 0 ? _options$gravityScale : 1;
|
280
284
|
const canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
|
281
285
|
const ccdEnabled = (_options$ccd = options === null || options === void 0 ? void 0 : options.ccd) !== null && _options$ccd !== void 0 ? _options$ccd : false;
|
@@ -285,7 +289,7 @@ const rigidBodyDescFromOptions = options => {
|
|
285
289
|
x: avx,
|
286
290
|
y: avy,
|
287
291
|
z: avz
|
288
|
-
}).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled).enabledRotations(erx, ery, erz).enabledTranslations(etx, ety, etz);
|
292
|
+
}).setLinearDamping(linearDamping).setAngularDamping(angularDamping).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled).enabledRotations(erx, ery, erz).enabledTranslations(etx, ety, etz);
|
289
293
|
if (options.lockRotations) desc.lockRotations();
|
290
294
|
if (options.lockTranslations) desc.lockTranslations();
|
291
295
|
return desc;
|
@@ -370,6 +374,18 @@ const createRigidBodyApi = ref => {
|
|
370
374
|
},
|
371
375
|
|
372
376
|
setAngvel: velocity => ref.current().setAngvel(velocity, true),
|
377
|
+
|
378
|
+
linearDamping() {
|
379
|
+
return ref.current().linearDamping();
|
380
|
+
},
|
381
|
+
|
382
|
+
setLinearDamping: factor => ref.current().setLinearDamping(factor),
|
383
|
+
|
384
|
+
angularDamping() {
|
385
|
+
return ref.current().angularDamping();
|
386
|
+
},
|
387
|
+
|
388
|
+
setAngularDamping: factor => ref.current().setAngularDamping(factor),
|
373
389
|
setNextKinematicRotation: ({
|
374
390
|
x,
|
375
391
|
y,
|
@@ -453,13 +469,14 @@ const Physics = ({
|
|
453
469
|
colliders: _colliders = "cuboid",
|
454
470
|
gravity: _gravity = [0, -9.81, 0],
|
455
471
|
children,
|
456
|
-
timeStep: _timeStep = "vary"
|
472
|
+
timeStep: _timeStep = "vary",
|
473
|
+
paused: _paused = false
|
457
474
|
}) => {
|
458
475
|
const rapier = useAsset.useAsset(importRapier);
|
459
476
|
const worldRef = React.useRef();
|
460
477
|
const getWorldRef = React.useRef(() => {
|
461
478
|
if (!worldRef.current) {
|
462
|
-
const world = new rapier.World(
|
479
|
+
const world = new rapier.World(vectorArrayToVector3(_gravity));
|
463
480
|
worldRef.current = world;
|
464
481
|
}
|
465
482
|
|
@@ -484,7 +501,7 @@ const Physics = ({
|
|
484
501
|
const world = worldRef.current;
|
485
502
|
|
486
503
|
if (world) {
|
487
|
-
world.gravity =
|
504
|
+
world.gravity = vectorArrayToVector3(_gravity);
|
488
505
|
}
|
489
506
|
}, [_gravity]);
|
490
507
|
const time = React.useRef(performance.now());
|
@@ -502,7 +519,7 @@ const Physics = ({
|
|
502
519
|
world.timestep = _timeStep;
|
503
520
|
}
|
504
521
|
|
505
|
-
world.step(eventQueue); // Update meshes
|
522
|
+
if (!_paused) world.step(eventQueue); // Update meshes
|
506
523
|
|
507
524
|
rigidBodyStates.forEach((state, handle) => {
|
508
525
|
const rigidBody = world.getRigidBody(handle);
|
@@ -734,15 +751,22 @@ const useRigidBody = (options = {}) => {
|
|
734
751
|
rigidBody.resetForces(false);
|
735
752
|
rigidBody.resetTorques(false);
|
736
753
|
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;
|
737
|
-
const autoColliders = colliderSetting !== false ? createCollidersFromChildren(
|
738
|
-
|
739
|
-
|
754
|
+
const autoColliders = colliderSetting !== false ? createCollidersFromChildren({
|
755
|
+
object: ref.current,
|
756
|
+
rigidBody,
|
757
|
+
options: _objectSpread2(_objectSpread2({}, options), {}, {
|
758
|
+
colliders: colliderSetting
|
759
|
+
}),
|
760
|
+
world,
|
761
|
+
ignoreMeshColliders: true
|
762
|
+
}) : [];
|
740
763
|
rigidBodyStates.set(rigidBody.handle, {
|
741
764
|
mesh: ref.current,
|
742
765
|
invertedMatrixWorld: ref.current.parent.matrixWorld.clone().invert(),
|
743
766
|
isSleeping: false,
|
744
767
|
worldScale: ref.current.getWorldScale(_vector3).clone(),
|
745
|
-
setMatrix: mat => ref.current.matrix.copy(mat)
|
768
|
+
setMatrix: mat => ref.current.matrix.copy(mat),
|
769
|
+
getMatrix: () => ref.current.matrix
|
746
770
|
});
|
747
771
|
ref.current.matrixAutoUpdate = false;
|
748
772
|
return () => {
|
@@ -812,9 +836,9 @@ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor,
|
|
812
836
|
const {
|
813
837
|
rapier
|
814
838
|
} = useRapier();
|
815
|
-
return useImpulseJoint(body1, body2, rapier.JointData.fixed(
|
839
|
+
return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToVector3(body1Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body1LocalFrame)), {}, {
|
816
840
|
w: 1
|
817
|
-
}),
|
841
|
+
}), vectorArrayToVector3(body2Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body2LocalFrame)), {}, {
|
818
842
|
w: 1
|
819
843
|
})));
|
820
844
|
};
|
@@ -829,7 +853,7 @@ const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
|
829
853
|
const {
|
830
854
|
rapier
|
831
855
|
} = useRapier();
|
832
|
-
return useImpulseJoint(body1, body2, rapier.JointData.spherical(
|
856
|
+
return useImpulseJoint(body1, body2, rapier.JointData.spherical(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor)));
|
833
857
|
};
|
834
858
|
/**
|
835
859
|
* The revolute joint prevents any relative movement between two rigid-bodies, except for relative
|
@@ -841,7 +865,7 @@ const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
|
841
865
|
const {
|
842
866
|
rapier
|
843
867
|
} = useRapier();
|
844
|
-
return useImpulseJoint(body1, body2, rapier.JointData.revolute(
|
868
|
+
return useImpulseJoint(body1, body2, rapier.JointData.revolute(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
|
845
869
|
};
|
846
870
|
/**
|
847
871
|
* The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
|
@@ -853,7 +877,7 @@ const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
|
853
877
|
const {
|
854
878
|
rapier
|
855
879
|
} = useRapier();
|
856
|
-
return useImpulseJoint(body1, body2, rapier.JointData.prismatic(
|
880
|
+
return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
|
857
881
|
};
|
858
882
|
|
859
883
|
const _excluded$1 = ["children"];
|
@@ -900,9 +924,18 @@ const MeshCollider = ({
|
|
900
924
|
var _ref;
|
901
925
|
|
902
926
|
const colliderSetting = (_ref = type !== null && type !== void 0 ? type : physicsOptions.colliders) !== null && _ref !== void 0 ? _ref : false;
|
903
|
-
|
904
|
-
|
905
|
-
|
927
|
+
|
928
|
+
if ("raw" in api) {
|
929
|
+
autoColliders = createCollidersFromChildren({
|
930
|
+
object: object.current,
|
931
|
+
rigidBody: api,
|
932
|
+
options: _objectSpread2(_objectSpread2({}, options), {}, {
|
933
|
+
colliders: colliderSetting
|
934
|
+
}),
|
935
|
+
world,
|
936
|
+
ignoreMeshColliders: false
|
937
|
+
});
|
938
|
+
}
|
906
939
|
}
|
907
940
|
|
908
941
|
return () => {
|
@@ -1049,12 +1082,12 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1049
1082
|
|
1050
1083
|
return instancesRef.current;
|
1051
1084
|
});
|
1052
|
-
React.
|
1085
|
+
React.useLayoutEffect(() => {
|
1053
1086
|
const colliders = [];
|
1054
1087
|
const rigidBodies = instancesRefGetter.current();
|
1055
1088
|
|
1056
1089
|
if (object.current) {
|
1057
|
-
const
|
1090
|
+
const worldScale = object.current.getWorldScale(new three.Vector3());
|
1058
1091
|
let hasOneMesh = false;
|
1059
1092
|
object.current.traverse(mesh => {
|
1060
1093
|
if (mesh instanceof three.InstancedMesh) {
|
@@ -1065,21 +1098,34 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1065
1098
|
|
1066
1099
|
hasOneMesh = true;
|
1067
1100
|
mesh.instanceMatrix.setUsage(three.DynamicDrawUsage);
|
1068
|
-
const rigidBodyDesc = rigidBodyDescFromOptions(props);
|
1069
|
-
const colliderDesc = colliderDescFromGeometry(mesh.geometry, props.colliders || physicsOptions.colliders, scale, false // Collisions currently not enabled for instances
|
1070
|
-
);
|
1071
1101
|
|
1072
1102
|
for (let index = 0; index < mesh.count; index++) {
|
1103
|
+
const scale = worldScale.clone();
|
1104
|
+
const rigidBodyDesc = rigidBodyDescFromOptions(props);
|
1105
|
+
|
1106
|
+
if (props.scales && props.scales[index]) {
|
1107
|
+
const s = vectorArrayToVector3(props.scales[index]);
|
1108
|
+
scale.multiply(s);
|
1109
|
+
}
|
1110
|
+
|
1073
1111
|
const rigidBody = world.createRigidBody(rigidBodyDesc);
|
1074
1112
|
const matrix = new three.Matrix4();
|
1075
1113
|
mesh.getMatrixAt(index, matrix);
|
1076
1114
|
const {
|
1077
1115
|
position,
|
1078
1116
|
rotation
|
1079
|
-
} = decomposeMatrix4(matrix);
|
1117
|
+
} = decomposeMatrix4(matrix);
|
1118
|
+
|
1119
|
+
if (props.colliders !== false) {
|
1120
|
+
const colliderDesc = colliderDescFromGeometry(mesh.geometry, props.colliders !== undefined ? props.colliders : physicsOptions.colliders, scale, false // Collisions currently not enabled for instances
|
1121
|
+
);
|
1122
|
+
const collider = world.createCollider(colliderDesc, rigidBody);
|
1123
|
+
colliders.push(collider);
|
1124
|
+
} // Set positions
|
1125
|
+
|
1080
1126
|
|
1081
1127
|
if (props.positions && props.positions[index]) {
|
1082
|
-
rigidBody.setTranslation(
|
1128
|
+
rigidBody.setTranslation(vectorArrayToVector3(props.positions[index]), true);
|
1083
1129
|
} else {
|
1084
1130
|
rigidBody.setTranslation(position, true);
|
1085
1131
|
} // Set rotations
|
@@ -1092,13 +1138,19 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1092
1138
|
rigidBody.setRotation(rotation, true);
|
1093
1139
|
}
|
1094
1140
|
|
1095
|
-
const collider = world.createCollider(colliderDesc, rigidBody);
|
1096
1141
|
rigidBodyStates.set(rigidBody.handle, {
|
1097
1142
|
mesh: mesh,
|
1098
1143
|
isSleeping: false,
|
1099
1144
|
invertedMatrixWorld: object.current.matrixWorld.clone().invert(),
|
1100
1145
|
setMatrix: matrix => mesh.setMatrixAt(index, matrix),
|
1101
|
-
|
1146
|
+
getMatrix: () => {
|
1147
|
+
const m = new three.Matrix4();
|
1148
|
+
mesh.getMatrixAt(index, m);
|
1149
|
+
return m;
|
1150
|
+
},
|
1151
|
+
// Setting the world scale to the scale here, because
|
1152
|
+
// we want the scales to be reflected by instance
|
1153
|
+
worldScale: scale
|
1102
1154
|
});
|
1103
1155
|
const api = createRigidBodyApi({
|
1104
1156
|
current() {
|
@@ -1106,7 +1158,6 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1106
1158
|
}
|
1107
1159
|
|
1108
1160
|
});
|
1109
|
-
colliders.push(collider);
|
1110
1161
|
rigidBodies.push({
|
1111
1162
|
rigidBody,
|
1112
1163
|
api
|
@@ -1125,10 +1176,19 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1125
1176
|
};
|
1126
1177
|
}
|
1127
1178
|
}, []);
|
1128
|
-
React.
|
1129
|
-
|
1179
|
+
const api = React.useMemo(() => createInstancedRigidBodiesApi(instancesRefGetter), []);
|
1180
|
+
React.useImperativeHandle(ref, () => api); // console.log(api);
|
1181
|
+
|
1182
|
+
return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
|
1183
|
+
value: {
|
1184
|
+
ref: object,
|
1185
|
+
api,
|
1186
|
+
hasCollisionEvents: false,
|
1187
|
+
options: props
|
1188
|
+
}
|
1189
|
+
}, /*#__PURE__*/React__default["default"].createElement("object3D", {
|
1130
1190
|
ref: object
|
1131
|
-
}, props.children);
|
1191
|
+
}, props.children));
|
1132
1192
|
});
|
1133
1193
|
|
1134
1194
|
function _extends() {
|
@@ -1163,18 +1223,40 @@ const AnyCollider = _ref => {
|
|
1163
1223
|
const rigidBodyContext = useRigidBodyContext();
|
1164
1224
|
const ref = React.useRef(null);
|
1165
1225
|
React.useEffect(() => {
|
1166
|
-
var _rigidBodyContext$api;
|
1167
|
-
|
1168
1226
|
const scale = ref.current.getWorldScale(new three.Vector3());
|
1169
|
-
const
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1227
|
+
const colliders = []; // If this is an InstancedRigidBody api
|
1228
|
+
|
1229
|
+
if (rigidBodyContext && "at" in rigidBodyContext.api) {
|
1230
|
+
rigidBodyContext.api.forEach((body, index) => {
|
1231
|
+
var _rigidBodyContext$opt, _rigidBodyContext$opt2;
|
1232
|
+
|
1233
|
+
let instanceScale = scale.clone();
|
1234
|
+
|
1235
|
+
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]) {
|
1236
|
+
instanceScale.multiply(vectorArrayToVector3(rigidBodyContext.options.scales[index]));
|
1237
|
+
}
|
1238
|
+
|
1239
|
+
colliders.push(createColliderFromOptions({
|
1240
|
+
options: props,
|
1241
|
+
world,
|
1242
|
+
rigidBody: body.raw(),
|
1243
|
+
scale: instanceScale,
|
1244
|
+
hasCollisionEvents: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.hasCollisionEvents
|
1245
|
+
}));
|
1246
|
+
});
|
1247
|
+
} else {
|
1248
|
+
colliders.push(createColliderFromOptions({
|
1249
|
+
options: props,
|
1250
|
+
world,
|
1251
|
+
// Initiate with a rigidbody, or undefined, because colliders can exist without a rigid body
|
1252
|
+
rigidBody: rigidBodyContext && "raw" in rigidBodyContext.api ? rigidBodyContext.api.raw() : undefined,
|
1253
|
+
scale,
|
1254
|
+
hasCollisionEvents: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.hasCollisionEvents
|
1255
|
+
}));
|
1256
|
+
}
|
1257
|
+
|
1176
1258
|
return () => {
|
1177
|
-
world.removeCollider(collider);
|
1259
|
+
colliders.forEach(collider => world.removeCollider(collider));
|
1178
1260
|
};
|
1179
1261
|
}, []);
|
1180
1262
|
return /*#__PURE__*/React__default["default"].createElement("object3D", {
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { ColliderDesc, ActiveEvents, RigidBodyDesc, CoefficientCombineRule, EventQueue, ShapeType } from '@dimforge/rapier3d-compat';
|
2
2
|
export { CoefficientCombineRule, Collider as RapierCollider, RigidBody as RapierRigidBody } from '@dimforge/rapier3d-compat';
|
3
|
-
import React, { useRef, useState, useEffect, useMemo, createContext, useContext, forwardRef, useImperativeHandle, memo } from 'react';
|
3
|
+
import React, { useRef, useState, useEffect, useMemo, createContext, useContext, forwardRef, useImperativeHandle, memo, useLayoutEffect } from 'react';
|
4
4
|
import { useAsset } from 'use-asset';
|
5
5
|
import { useFrame } from '@react-three/fiber';
|
6
6
|
import { Quaternion, Euler, Vector3, Object3D, Matrix4, InstancedMesh, CylinderBufferGeometry, BufferGeometry, BufferAttribute, SphereBufferGeometry, BoxBufferGeometry, DynamicDrawUsage } from 'three';
|
@@ -11,13 +11,9 @@ const _vector3 = new Vector3();
|
|
11
11
|
new Object3D();
|
12
12
|
const _matrix4 = new Matrix4();
|
13
13
|
|
14
|
-
const
|
14
|
+
const vectorArrayToVector3 = arr => {
|
15
15
|
const [x, y, z] = arr;
|
16
|
-
return
|
17
|
-
x,
|
18
|
-
y,
|
19
|
-
z
|
20
|
-
};
|
16
|
+
return new Vector3(x, y, z);
|
21
17
|
};
|
22
18
|
const vector3ToQuaternion = v => {
|
23
19
|
return _quaternion.setFromEuler(_euler.setFromVector3(v));
|
@@ -133,13 +129,19 @@ const isChildOfMeshCollider = child => {
|
|
133
129
|
return flag;
|
134
130
|
};
|
135
131
|
|
136
|
-
const createCollidersFromChildren = (
|
132
|
+
const createCollidersFromChildren = ({
|
133
|
+
object,
|
134
|
+
rigidBody,
|
135
|
+
options,
|
136
|
+
world,
|
137
|
+
ignoreMeshColliders: _ignoreMeshColliders = true
|
138
|
+
}) => {
|
137
139
|
const hasCollisionEvents = !!(options.onCollisionEnter || options.onCollisionExit);
|
138
140
|
const colliders = [];
|
139
141
|
new Vector3();
|
140
|
-
object.
|
142
|
+
object.traverseVisible(child => {
|
141
143
|
if ("isMesh" in child) {
|
142
|
-
if (
|
144
|
+
if (_ignoreMeshColliders && isChildOfMeshCollider(child)) return;
|
143
145
|
const {
|
144
146
|
geometry
|
145
147
|
} = child;
|
@@ -180,7 +182,7 @@ const createCollidersFromChildren = (object, rigidBody, options, world, ignoreMe
|
|
180
182
|
z: rz,
|
181
183
|
w: rw
|
182
184
|
});
|
183
|
-
const actualRigidBody = world.getRigidBody(rigidBody
|
185
|
+
const actualRigidBody = rigidBody ? world.getRigidBody(rigidBody.handle) : undefined;
|
184
186
|
const collider = world.createCollider(desc, actualRigidBody);
|
185
187
|
colliders.push(collider);
|
186
188
|
}
|
@@ -246,11 +248,13 @@ const scaleVertices = (vertices, scale) => {
|
|
246
248
|
return scaledVerts;
|
247
249
|
};
|
248
250
|
const rigidBodyDescFromOptions = options => {
|
249
|
-
var _options$linearVeloci, _options$angularVeloc, _options$gravityScale, _options$canSleep, _options$ccd, _options$enabledRotat, _options$enabledTrans;
|
251
|
+
var _options$linearVeloci, _options$angularVeloc, _options$angularDampi, _options$linearDampin, _options$gravityScale, _options$canSleep, _options$ccd, _options$enabledRotat, _options$enabledTrans;
|
250
252
|
|
251
253
|
const type = rigidBodyTypeFromString((options === null || options === void 0 ? void 0 : options.type) || "dynamic");
|
252
254
|
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];
|
253
255
|
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];
|
256
|
+
const angularDamping = (_options$angularDampi = options === null || options === void 0 ? void 0 : options.angularDamping) !== null && _options$angularDampi !== void 0 ? _options$angularDampi : 0;
|
257
|
+
const linearDamping = (_options$linearDampin = options === null || options === void 0 ? void 0 : options.linearDamping) !== null && _options$linearDampin !== void 0 ? _options$linearDampin : 0;
|
254
258
|
const gravityScale = (_options$gravityScale = options === null || options === void 0 ? void 0 : options.gravityScale) !== null && _options$gravityScale !== void 0 ? _options$gravityScale : 1;
|
255
259
|
const canSleep = (_options$canSleep = options === null || options === void 0 ? void 0 : options.canSleep) !== null && _options$canSleep !== void 0 ? _options$canSleep : true;
|
256
260
|
const ccdEnabled = (_options$ccd = options === null || options === void 0 ? void 0 : options.ccd) !== null && _options$ccd !== void 0 ? _options$ccd : false;
|
@@ -260,7 +264,7 @@ const rigidBodyDescFromOptions = options => {
|
|
260
264
|
x: avx,
|
261
265
|
y: avy,
|
262
266
|
z: avz
|
263
|
-
}).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled).enabledRotations(erx, ery, erz).enabledTranslations(etx, ety, etz);
|
267
|
+
}).setLinearDamping(linearDamping).setAngularDamping(angularDamping).setGravityScale(gravityScale).setCanSleep(canSleep).setCcdEnabled(ccdEnabled).enabledRotations(erx, ery, erz).enabledTranslations(etx, ety, etz);
|
264
268
|
if (options.lockRotations) desc.lockRotations();
|
265
269
|
if (options.lockTranslations) desc.lockTranslations();
|
266
270
|
return desc;
|
@@ -345,6 +349,18 @@ const createRigidBodyApi = ref => {
|
|
345
349
|
},
|
346
350
|
|
347
351
|
setAngvel: velocity => ref.current().setAngvel(velocity, true),
|
352
|
+
|
353
|
+
linearDamping() {
|
354
|
+
return ref.current().linearDamping();
|
355
|
+
},
|
356
|
+
|
357
|
+
setLinearDamping: factor => ref.current().setLinearDamping(factor),
|
358
|
+
|
359
|
+
angularDamping() {
|
360
|
+
return ref.current().angularDamping();
|
361
|
+
},
|
362
|
+
|
363
|
+
setAngularDamping: factor => ref.current().setAngularDamping(factor),
|
348
364
|
setNextKinematicRotation: ({
|
349
365
|
x,
|
350
366
|
y,
|
@@ -428,13 +444,14 @@ const Physics = ({
|
|
428
444
|
colliders: _colliders = "cuboid",
|
429
445
|
gravity: _gravity = [0, -9.81, 0],
|
430
446
|
children,
|
431
|
-
timeStep: _timeStep = "vary"
|
447
|
+
timeStep: _timeStep = "vary",
|
448
|
+
paused: _paused = false
|
432
449
|
}) => {
|
433
450
|
const rapier = useAsset(importRapier);
|
434
451
|
const worldRef = useRef();
|
435
452
|
const getWorldRef = useRef(() => {
|
436
453
|
if (!worldRef.current) {
|
437
|
-
const world = new rapier.World(
|
454
|
+
const world = new rapier.World(vectorArrayToVector3(_gravity));
|
438
455
|
worldRef.current = world;
|
439
456
|
}
|
440
457
|
|
@@ -459,7 +476,7 @@ const Physics = ({
|
|
459
476
|
const world = worldRef.current;
|
460
477
|
|
461
478
|
if (world) {
|
462
|
-
world.gravity =
|
479
|
+
world.gravity = vectorArrayToVector3(_gravity);
|
463
480
|
}
|
464
481
|
}, [_gravity]);
|
465
482
|
const time = useRef(performance.now());
|
@@ -477,7 +494,7 @@ const Physics = ({
|
|
477
494
|
world.timestep = _timeStep;
|
478
495
|
}
|
479
496
|
|
480
|
-
world.step(eventQueue); // Update meshes
|
497
|
+
if (!_paused) world.step(eventQueue); // Update meshes
|
481
498
|
|
482
499
|
rigidBodyStates.forEach((state, handle) => {
|
483
500
|
const rigidBody = world.getRigidBody(handle);
|
@@ -709,15 +726,22 @@ const useRigidBody = (options = {}) => {
|
|
709
726
|
rigidBody.resetForces(false);
|
710
727
|
rigidBody.resetTorques(false);
|
711
728
|
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;
|
712
|
-
const autoColliders = colliderSetting !== false ? createCollidersFromChildren(
|
713
|
-
|
714
|
-
|
729
|
+
const autoColliders = colliderSetting !== false ? createCollidersFromChildren({
|
730
|
+
object: ref.current,
|
731
|
+
rigidBody,
|
732
|
+
options: _objectSpread2(_objectSpread2({}, options), {}, {
|
733
|
+
colliders: colliderSetting
|
734
|
+
}),
|
735
|
+
world,
|
736
|
+
ignoreMeshColliders: true
|
737
|
+
}) : [];
|
715
738
|
rigidBodyStates.set(rigidBody.handle, {
|
716
739
|
mesh: ref.current,
|
717
740
|
invertedMatrixWorld: ref.current.parent.matrixWorld.clone().invert(),
|
718
741
|
isSleeping: false,
|
719
742
|
worldScale: ref.current.getWorldScale(_vector3).clone(),
|
720
|
-
setMatrix: mat => ref.current.matrix.copy(mat)
|
743
|
+
setMatrix: mat => ref.current.matrix.copy(mat),
|
744
|
+
getMatrix: () => ref.current.matrix
|
721
745
|
});
|
722
746
|
ref.current.matrixAutoUpdate = false;
|
723
747
|
return () => {
|
@@ -787,9 +811,9 @@ const useFixedJoint = (body1, body2, [body1Anchor, body1LocalFrame, body2Anchor,
|
|
787
811
|
const {
|
788
812
|
rapier
|
789
813
|
} = useRapier();
|
790
|
-
return useImpulseJoint(body1, body2, rapier.JointData.fixed(
|
814
|
+
return useImpulseJoint(body1, body2, rapier.JointData.fixed(vectorArrayToVector3(body1Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body1LocalFrame)), {}, {
|
791
815
|
w: 1
|
792
|
-
}),
|
816
|
+
}), vectorArrayToVector3(body2Anchor), _objectSpread2(_objectSpread2({}, vectorArrayToVector3(body2LocalFrame)), {}, {
|
793
817
|
w: 1
|
794
818
|
})));
|
795
819
|
};
|
@@ -804,7 +828,7 @@ const useSphericalJoint = (body1, body2, [body1Anchor, body2Anchor]) => {
|
|
804
828
|
const {
|
805
829
|
rapier
|
806
830
|
} = useRapier();
|
807
|
-
return useImpulseJoint(body1, body2, rapier.JointData.spherical(
|
831
|
+
return useImpulseJoint(body1, body2, rapier.JointData.spherical(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor)));
|
808
832
|
};
|
809
833
|
/**
|
810
834
|
* The revolute joint prevents any relative movement between two rigid-bodies, except for relative
|
@@ -816,7 +840,7 @@ const useRevoluteJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
|
816
840
|
const {
|
817
841
|
rapier
|
818
842
|
} = useRapier();
|
819
|
-
return useImpulseJoint(body1, body2, rapier.JointData.revolute(
|
843
|
+
return useImpulseJoint(body1, body2, rapier.JointData.revolute(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
|
820
844
|
};
|
821
845
|
/**
|
822
846
|
* The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
|
@@ -828,7 +852,7 @@ const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
|
828
852
|
const {
|
829
853
|
rapier
|
830
854
|
} = useRapier();
|
831
|
-
return useImpulseJoint(body1, body2, rapier.JointData.prismatic(
|
855
|
+
return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
|
832
856
|
};
|
833
857
|
|
834
858
|
const _excluded$1 = ["children"];
|
@@ -875,9 +899,18 @@ const MeshCollider = ({
|
|
875
899
|
var _ref;
|
876
900
|
|
877
901
|
const colliderSetting = (_ref = type !== null && type !== void 0 ? type : physicsOptions.colliders) !== null && _ref !== void 0 ? _ref : false;
|
878
|
-
|
879
|
-
|
880
|
-
|
902
|
+
|
903
|
+
if ("raw" in api) {
|
904
|
+
autoColliders = createCollidersFromChildren({
|
905
|
+
object: object.current,
|
906
|
+
rigidBody: api,
|
907
|
+
options: _objectSpread2(_objectSpread2({}, options), {}, {
|
908
|
+
colliders: colliderSetting
|
909
|
+
}),
|
910
|
+
world,
|
911
|
+
ignoreMeshColliders: false
|
912
|
+
});
|
913
|
+
}
|
881
914
|
}
|
882
915
|
|
883
916
|
return () => {
|
@@ -1024,12 +1057,12 @@ const InstancedRigidBodies = /*#__PURE__*/forwardRef((props, ref) => {
|
|
1024
1057
|
|
1025
1058
|
return instancesRef.current;
|
1026
1059
|
});
|
1027
|
-
|
1060
|
+
useLayoutEffect(() => {
|
1028
1061
|
const colliders = [];
|
1029
1062
|
const rigidBodies = instancesRefGetter.current();
|
1030
1063
|
|
1031
1064
|
if (object.current) {
|
1032
|
-
const
|
1065
|
+
const worldScale = object.current.getWorldScale(new Vector3());
|
1033
1066
|
let hasOneMesh = false;
|
1034
1067
|
object.current.traverse(mesh => {
|
1035
1068
|
if (mesh instanceof InstancedMesh) {
|
@@ -1040,21 +1073,34 @@ const InstancedRigidBodies = /*#__PURE__*/forwardRef((props, ref) => {
|
|
1040
1073
|
|
1041
1074
|
hasOneMesh = true;
|
1042
1075
|
mesh.instanceMatrix.setUsage(DynamicDrawUsage);
|
1043
|
-
const rigidBodyDesc = rigidBodyDescFromOptions(props);
|
1044
|
-
const colliderDesc = colliderDescFromGeometry(mesh.geometry, props.colliders || physicsOptions.colliders, scale, false // Collisions currently not enabled for instances
|
1045
|
-
);
|
1046
1076
|
|
1047
1077
|
for (let index = 0; index < mesh.count; index++) {
|
1078
|
+
const scale = worldScale.clone();
|
1079
|
+
const rigidBodyDesc = rigidBodyDescFromOptions(props);
|
1080
|
+
|
1081
|
+
if (props.scales && props.scales[index]) {
|
1082
|
+
const s = vectorArrayToVector3(props.scales[index]);
|
1083
|
+
scale.multiply(s);
|
1084
|
+
}
|
1085
|
+
|
1048
1086
|
const rigidBody = world.createRigidBody(rigidBodyDesc);
|
1049
1087
|
const matrix = new Matrix4();
|
1050
1088
|
mesh.getMatrixAt(index, matrix);
|
1051
1089
|
const {
|
1052
1090
|
position,
|
1053
1091
|
rotation
|
1054
|
-
} = decomposeMatrix4(matrix);
|
1092
|
+
} = decomposeMatrix4(matrix);
|
1093
|
+
|
1094
|
+
if (props.colliders !== false) {
|
1095
|
+
const colliderDesc = colliderDescFromGeometry(mesh.geometry, props.colliders !== undefined ? props.colliders : physicsOptions.colliders, scale, false // Collisions currently not enabled for instances
|
1096
|
+
);
|
1097
|
+
const collider = world.createCollider(colliderDesc, rigidBody);
|
1098
|
+
colliders.push(collider);
|
1099
|
+
} // Set positions
|
1100
|
+
|
1055
1101
|
|
1056
1102
|
if (props.positions && props.positions[index]) {
|
1057
|
-
rigidBody.setTranslation(
|
1103
|
+
rigidBody.setTranslation(vectorArrayToVector3(props.positions[index]), true);
|
1058
1104
|
} else {
|
1059
1105
|
rigidBody.setTranslation(position, true);
|
1060
1106
|
} // Set rotations
|
@@ -1067,13 +1113,19 @@ const InstancedRigidBodies = /*#__PURE__*/forwardRef((props, ref) => {
|
|
1067
1113
|
rigidBody.setRotation(rotation, true);
|
1068
1114
|
}
|
1069
1115
|
|
1070
|
-
const collider = world.createCollider(colliderDesc, rigidBody);
|
1071
1116
|
rigidBodyStates.set(rigidBody.handle, {
|
1072
1117
|
mesh: mesh,
|
1073
1118
|
isSleeping: false,
|
1074
1119
|
invertedMatrixWorld: object.current.matrixWorld.clone().invert(),
|
1075
1120
|
setMatrix: matrix => mesh.setMatrixAt(index, matrix),
|
1076
|
-
|
1121
|
+
getMatrix: () => {
|
1122
|
+
const m = new Matrix4();
|
1123
|
+
mesh.getMatrixAt(index, m);
|
1124
|
+
return m;
|
1125
|
+
},
|
1126
|
+
// Setting the world scale to the scale here, because
|
1127
|
+
// we want the scales to be reflected by instance
|
1128
|
+
worldScale: scale
|
1077
1129
|
});
|
1078
1130
|
const api = createRigidBodyApi({
|
1079
1131
|
current() {
|
@@ -1081,7 +1133,6 @@ const InstancedRigidBodies = /*#__PURE__*/forwardRef((props, ref) => {
|
|
1081
1133
|
}
|
1082
1134
|
|
1083
1135
|
});
|
1084
|
-
colliders.push(collider);
|
1085
1136
|
rigidBodies.push({
|
1086
1137
|
rigidBody,
|
1087
1138
|
api
|
@@ -1100,10 +1151,19 @@ const InstancedRigidBodies = /*#__PURE__*/forwardRef((props, ref) => {
|
|
1100
1151
|
};
|
1101
1152
|
}
|
1102
1153
|
}, []);
|
1103
|
-
|
1104
|
-
|
1154
|
+
const api = useMemo(() => createInstancedRigidBodiesApi(instancesRefGetter), []);
|
1155
|
+
useImperativeHandle(ref, () => api); // console.log(api);
|
1156
|
+
|
1157
|
+
return /*#__PURE__*/React.createElement(RigidBodyContext.Provider, {
|
1158
|
+
value: {
|
1159
|
+
ref: object,
|
1160
|
+
api,
|
1161
|
+
hasCollisionEvents: false,
|
1162
|
+
options: props
|
1163
|
+
}
|
1164
|
+
}, /*#__PURE__*/React.createElement("object3D", {
|
1105
1165
|
ref: object
|
1106
|
-
}, props.children);
|
1166
|
+
}, props.children));
|
1107
1167
|
});
|
1108
1168
|
|
1109
1169
|
function _extends() {
|
@@ -1138,18 +1198,40 @@ const AnyCollider = _ref => {
|
|
1138
1198
|
const rigidBodyContext = useRigidBodyContext();
|
1139
1199
|
const ref = useRef(null);
|
1140
1200
|
useEffect(() => {
|
1141
|
-
var _rigidBodyContext$api;
|
1142
|
-
|
1143
1201
|
const scale = ref.current.getWorldScale(new Vector3());
|
1144
|
-
const
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1202
|
+
const colliders = []; // If this is an InstancedRigidBody api
|
1203
|
+
|
1204
|
+
if (rigidBodyContext && "at" in rigidBodyContext.api) {
|
1205
|
+
rigidBodyContext.api.forEach((body, index) => {
|
1206
|
+
var _rigidBodyContext$opt, _rigidBodyContext$opt2;
|
1207
|
+
|
1208
|
+
let instanceScale = scale.clone();
|
1209
|
+
|
1210
|
+
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]) {
|
1211
|
+
instanceScale.multiply(vectorArrayToVector3(rigidBodyContext.options.scales[index]));
|
1212
|
+
}
|
1213
|
+
|
1214
|
+
colliders.push(createColliderFromOptions({
|
1215
|
+
options: props,
|
1216
|
+
world,
|
1217
|
+
rigidBody: body.raw(),
|
1218
|
+
scale: instanceScale,
|
1219
|
+
hasCollisionEvents: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.hasCollisionEvents
|
1220
|
+
}));
|
1221
|
+
});
|
1222
|
+
} else {
|
1223
|
+
colliders.push(createColliderFromOptions({
|
1224
|
+
options: props,
|
1225
|
+
world,
|
1226
|
+
// Initiate with a rigidbody, or undefined, because colliders can exist without a rigid body
|
1227
|
+
rigidBody: rigidBodyContext && "raw" in rigidBodyContext.api ? rigidBodyContext.api.raw() : undefined,
|
1228
|
+
scale,
|
1229
|
+
hasCollisionEvents: rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.hasCollisionEvents
|
1230
|
+
}));
|
1231
|
+
}
|
1232
|
+
|
1151
1233
|
return () => {
|
1152
|
-
world.removeCollider(collider);
|
1234
|
+
colliders.forEach(collider => world.removeCollider(collider));
|
1153
1235
|
};
|
1154
1236
|
}, []);
|
1155
1237
|
return /*#__PURE__*/React.createElement("object3D", {
|
package/package.json
CHANGED
package/readme.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
<p align="center">
|
2
|
-
<img src="misc/hero.svg" />
|
2
|
+
<img src="https://raw.githubusercontent.com/pmndrs/react-three-rapier/HEAD/packages/react-three-rapier/misc/hero.svg" alt="@react-three/rapier" />
|
3
|
+
</p>
|
4
|
+
|
5
|
+
<p align="center">
|
6
|
+
<img src="https://img.shields.io/npm/v/@react-three/rapier?style=for-the-badge&colorA=0099DA&colorB=ffffff" />
|
7
|
+
<img src="https://img.shields.io/discord/740090768164651008?style=for-the-badge&colorA=0099DA&colorB=ffffff&label=discord&logo=discord&logoColor=ffffff)](https://discord.gg/ZZjjNvJ" />
|
3
8
|
</p>
|
4
9
|
|
5
10
|
<p align="center">⚠️ Under heavy development. All APIs are subject to change. ⚠️</p>
|
@@ -121,6 +126,8 @@ Instanced meshes can also be used and have automatic colliders generated from th
|
|
121
126
|
|
122
127
|
By wrapping the `InstancedMesh` in `<InstancedRigidBodies />`, each instance will be attached to an individual `RigidBody`.
|
123
128
|
|
129
|
+
> Note: Custom colliders (compound shapes) for InstancedMesh is currently not supported
|
130
|
+
|
124
131
|
```tsx
|
125
132
|
import { InstancedRigidBodies } from "@react-three/rapier";
|
126
133
|
|
@@ -139,7 +146,8 @@ const Scene = () => {
|
|
139
146
|
});
|
140
147
|
}, []);
|
141
148
|
|
142
|
-
// We can set the initial positions, and rotations,
|
149
|
+
// We can set the initial positions, and rotations, and scales, of
|
150
|
+
// the instances by providing an array equal to the instance count
|
143
151
|
const positions = Array.from({ length: COUNT }, (_, index) => [index, 0, 0]);
|
144
152
|
|
145
153
|
const rotations = Array.from({ length: COUNT }, (_, index) => [
|
@@ -148,16 +156,25 @@ const Scene = () => {
|
|
148
156
|
Math.random(),
|
149
157
|
]);
|
150
158
|
|
159
|
+
const scales = Array.from({ length: COUNT }, (_, index) => [
|
160
|
+
Math.random(),
|
161
|
+
Math.random(),
|
162
|
+
Math.random(),
|
163
|
+
]);
|
164
|
+
|
151
165
|
return (
|
152
166
|
<InstancedRigidBodies
|
153
167
|
ref={instancedApi}
|
154
168
|
positions={positions}
|
155
169
|
rotations={rotations}
|
170
|
+
scales={scales}
|
156
171
|
colliders="ball"
|
157
172
|
>
|
158
173
|
<instancedMesh args={[undefined, undefined, COUNT]}>
|
159
174
|
<sphereBufferGeometry args={[0.2]} />
|
160
175
|
<meshPhysicalGeometry color="blue" />
|
176
|
+
|
177
|
+
<CuboidCollider args={[0.1, 0.2, 0.1]} />
|
161
178
|
</instancedMesh>
|
162
179
|
</InstancedRigidBodies>
|
163
180
|
);
|