@react-three/rapier 0.16.0-canary.1 → 1.0.0-canary.2
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/components/Physics.d.ts +3 -4
- package/dist/declarations/src/index.d.ts +0 -1
- package/dist/declarations/src/utils/singleton-proxy.d.ts +10 -0
- package/dist/declarations/src/utils/utils-collider.d.ts +2 -3
- package/dist/react-three-rapier.cjs.dev.js +79 -75
- package/dist/react-three-rapier.cjs.prod.js +79 -75
- package/dist/react-three-rapier.esm.js +80 -76
- package/package.json +2 -4
- package/dist/declarations/src/utils/api.d.ts +0 -17
@@ -1,9 +1,8 @@
|
|
1
1
|
import type Rapier from "@dimforge/rapier3d-compat";
|
2
|
-
import { Collider, ColliderHandle, RigidBody, RigidBodyHandle } from "@dimforge/rapier3d-compat";
|
2
|
+
import { Collider, ColliderHandle, RigidBody, RigidBodyHandle, World } from "@dimforge/rapier3d-compat";
|
3
3
|
import React, { FC, ReactNode } from "react";
|
4
4
|
import { Matrix4, Object3D, Vector3 } from "three";
|
5
5
|
import { CollisionEnterHandler, CollisionExitHandler, ContactForceHandler, IntersectionEnterHandler, IntersectionExitHandler, RigidBodyAutoCollider, Vector3Tuple } from "../types";
|
6
|
-
import { WorldApi } from "../utils/api";
|
7
6
|
export interface RigidBodyState {
|
8
7
|
meshType: "instancedMesh" | "mesh";
|
9
8
|
rigidBody: RigidBody;
|
@@ -18,7 +17,7 @@ export interface RigidBodyState {
|
|
18
17
|
isSleeping: boolean;
|
19
18
|
}
|
20
19
|
export declare type RigidBodyStateMap = Map<RigidBody["handle"], RigidBodyState>;
|
21
|
-
export declare type WorldStepCallback = (
|
20
|
+
export declare type WorldStepCallback = (world: World) => void;
|
22
21
|
export declare type WorldStepCallbackSet = Set<{
|
23
22
|
current: WorldStepCallback;
|
24
23
|
}>;
|
@@ -77,7 +76,7 @@ export interface RapierContext {
|
|
77
76
|
/**
|
78
77
|
* The Rapier physics world
|
79
78
|
*/
|
80
|
-
world:
|
79
|
+
world: World;
|
81
80
|
/**
|
82
81
|
* If the physics simulation is paused
|
83
82
|
*/
|
@@ -4,7 +4,6 @@ export type { InstancedRigidBodiesProps, InstancedRigidBodyProps } from "./compo
|
|
4
4
|
export type { CylinderColliderProps, BallColliderProps, CapsuleColliderProps, ConeColliderProps, ConvexHullColliderProps, CuboidColliderProps, HeightfieldColliderProps, RoundCuboidColliderProps, TrimeshColliderProps, ColliderOptionsRequiredArgs } from "./components/AnyCollider";
|
5
5
|
export type { PhysicsProps, RapierContext, WorldStepCallback } from "./components/Physics";
|
6
6
|
export type { MeshColliderProps } from "./components/MeshCollider";
|
7
|
-
export type { WorldApi } from "./utils/api";
|
8
7
|
export { Physics } from "./components/Physics";
|
9
8
|
export { RigidBody } from "./components/RigidBody";
|
10
9
|
export { MeshCollider } from "./components/MeshCollider";
|
@@ -0,0 +1,10 @@
|
|
1
|
+
/**
|
2
|
+
* Creates a proxy that will create a singleton instance of the given class
|
3
|
+
* when a property is accessed, and not before.
|
4
|
+
*
|
5
|
+
* @returns A proxy and a reset function, so that the instance can created again
|
6
|
+
*/
|
7
|
+
export declare const createSingletonProxy: <SingletonClass extends object, CreationFn extends () => SingletonClass = () => SingletonClass>(createInstance: CreationFn) => {
|
8
|
+
proxy: SingletonClass;
|
9
|
+
reset: () => void;
|
10
|
+
};
|
@@ -1,7 +1,6 @@
|
|
1
|
-
import { Collider, RigidBody } from "@dimforge/rapier3d-compat";
|
1
|
+
import { Collider, RigidBody, World } from "@dimforge/rapier3d-compat";
|
2
2
|
import { BufferGeometry, Object3D, Vector3 } from "three";
|
3
3
|
import { ColliderProps, RigidBodyProps } from "..";
|
4
|
-
import { WorldApi } from "./api";
|
5
4
|
import { ColliderState, ColliderStateMap, EventMap } from "../components/Physics";
|
6
5
|
import { ColliderShape, RigidBodyAutoCollider } from "../types";
|
7
6
|
export declare const scaleColliderArgs: (shape: ColliderShape, args: (number | ArrayLike<number> | {
|
@@ -13,7 +12,7 @@ export declare const scaleColliderArgs: (shape: ColliderShape, args: (number | A
|
|
13
12
|
y: number;
|
14
13
|
z: number;
|
15
14
|
})[];
|
16
|
-
export declare const createColliderFromOptions: (options: ColliderProps, world:
|
15
|
+
export declare const createColliderFromOptions: (options: ColliderProps, world: World, scale: Vector3, getRigidBody?: () => RigidBody) => Collider;
|
17
16
|
declare type ImmutableColliderOptions = (keyof ColliderProps)[];
|
18
17
|
export declare const immutableColliderOptions: ImmutableColliderOptions;
|
19
18
|
export declare const setColliderOptions: (collider: Collider, options: ColliderProps, states: ColliderStateMap) => void;
|
@@ -72,40 +72,6 @@ function _objectSpread2(target) {
|
|
72
72
|
return target;
|
73
73
|
}
|
74
74
|
|
75
|
-
const createWorldApi = getWorld => {
|
76
|
-
return {
|
77
|
-
raw: () => getWorld(),
|
78
|
-
getCollider: handle => getWorld().getCollider(handle),
|
79
|
-
getRigidBody: handle => getWorld().getRigidBody(handle),
|
80
|
-
createRigidBody: desc => getWorld().createRigidBody(desc),
|
81
|
-
createCollider: (desc, rigidBody) => getWorld().createCollider(desc, rigidBody),
|
82
|
-
removeRigidBody: rigidBody => {
|
83
|
-
if (!getWorld().bodies.contains(rigidBody.handle)) return;
|
84
|
-
getWorld().removeRigidBody(rigidBody);
|
85
|
-
},
|
86
|
-
removeCollider: (collider, wakeUp = true) => {
|
87
|
-
if (!getWorld().colliders.contains(collider.handle)) return;
|
88
|
-
getWorld().removeCollider(collider, wakeUp);
|
89
|
-
},
|
90
|
-
createImpulseJoint: (params, rigidBodyA, rigidBodyB, wakeUp = true) => getWorld().createImpulseJoint(params, rigidBodyA, rigidBodyB, wakeUp),
|
91
|
-
removeImpulseJoint: (joint, wakeUp = true) => {
|
92
|
-
if (!getWorld().impulseJoints.contains(joint.handle)) return;
|
93
|
-
getWorld().removeImpulseJoint(joint, wakeUp);
|
94
|
-
},
|
95
|
-
forEachCollider: callback => getWorld().forEachCollider(callback),
|
96
|
-
setGravity: ({
|
97
|
-
x,
|
98
|
-
y,
|
99
|
-
z
|
100
|
-
}) => getWorld().gravity = {
|
101
|
-
x,
|
102
|
-
y,
|
103
|
-
z
|
104
|
-
},
|
105
|
-
debugRender: () => getWorld().debugRender()
|
106
|
-
};
|
107
|
-
};
|
108
|
-
|
109
75
|
const _quaternion = new three.Quaternion();
|
110
76
|
new three.Euler();
|
111
77
|
const _vector3 = new three.Vector3();
|
@@ -684,30 +650,37 @@ const Debug = /*#__PURE__*/React.memo(() => {
|
|
684
650
|
});
|
685
651
|
|
686
652
|
/**
|
687
|
-
*
|
653
|
+
* Creates a proxy that will create a singleton instance of the given class
|
654
|
+
* when a property is accessed, and not before.
|
655
|
+
*
|
656
|
+
* @returns A proxy and a reset function, so that the instance can created again
|
688
657
|
*/
|
658
|
+
const createSingletonProxy = createInstance => {
|
659
|
+
let instance;
|
660
|
+
const handler = {
|
661
|
+
get(target, prop) {
|
662
|
+
if (!instance) {
|
663
|
+
instance = createInstance();
|
664
|
+
}
|
689
665
|
|
690
|
-
|
691
|
-
const ref = React.useRef();
|
692
|
-
const getInstance = React.useCallback(() => {
|
693
|
-
if (!ref.current) {
|
694
|
-
ref.current = createFn();
|
666
|
+
return Reflect.get(instance, prop);
|
695
667
|
}
|
696
668
|
|
697
|
-
|
698
|
-
},
|
699
|
-
React.useEffect(() => {
|
700
|
-
// Save the destroy function and instance
|
701
|
-
const instance = getInstance();
|
669
|
+
};
|
670
|
+
const proxy = new Proxy({}, handler);
|
702
671
|
|
703
|
-
|
672
|
+
const reset = () => {
|
673
|
+
instance = undefined;
|
674
|
+
};
|
675
|
+
/**
|
676
|
+
* Return the proxy and a reset function
|
677
|
+
*/
|
704
678
|
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
}
|
710
|
-
return getInstance;
|
679
|
+
|
680
|
+
return {
|
681
|
+
proxy,
|
682
|
+
reset
|
683
|
+
};
|
711
684
|
};
|
712
685
|
|
713
686
|
const rapierContext = /*#__PURE__*/React.createContext(undefined);
|
@@ -759,38 +732,42 @@ const Physics = ({
|
|
759
732
|
const rapier = useAsset.useAsset(importRapier);
|
760
733
|
const {
|
761
734
|
invalidate
|
762
|
-
} = fiber.useThree();
|
763
|
-
|
764
|
-
const getWorld = useImperativeInstance(() => {
|
765
|
-
return new rapier.World(vectorArrayToVector3(_gravity));
|
766
|
-
}, world => {
|
767
|
-
world.free();
|
768
|
-
}, []);
|
735
|
+
} = fiber.useThree();
|
769
736
|
const rigidBodyStates = useConst(() => new Map());
|
770
737
|
const colliderStates = useConst(() => new Map());
|
771
738
|
const rigidBodyEvents = useConst(() => new Map());
|
772
739
|
const colliderEvents = useConst(() => new Map());
|
773
740
|
const eventQueue = useConst(() => new rapier3dCompat.EventQueue(false));
|
774
741
|
const beforeStepCallbacks = useConst(() => new Set());
|
775
|
-
const afterStepCallbacks = useConst(() => new Set());
|
742
|
+
const afterStepCallbacks = useConst(() => new Set());
|
743
|
+
/**
|
744
|
+
* Initiate the world
|
745
|
+
* This creates a singleton proxy, so that the world is only created when
|
746
|
+
* something within it is accessed.
|
747
|
+
*/
|
776
748
|
|
749
|
+
const {
|
750
|
+
proxy: worldProxy,
|
751
|
+
reset: resetWorldProxy
|
752
|
+
} = useConst(() => createSingletonProxy(() => new rapier.World(vectorArrayToVector3(_gravity))));
|
777
753
|
React.useEffect(() => {
|
778
|
-
|
754
|
+
return () => {
|
755
|
+
worldProxy.free();
|
756
|
+
resetWorldProxy();
|
757
|
+
};
|
758
|
+
}, []); // Update gravity
|
779
759
|
|
780
|
-
|
781
|
-
|
782
|
-
}
|
760
|
+
React.useEffect(() => {
|
761
|
+
worldProxy.gravity = vectorArrayToVector3(_gravity);
|
783
762
|
}, [_gravity]);
|
784
|
-
const api = React.useMemo(() => createWorldApi(getWorld), []);
|
785
763
|
const getSourceFromColliderHandle = React.useCallback(handle => {
|
786
764
|
var _collider$parent;
|
787
765
|
|
788
|
-
const
|
789
|
-
const collider = world.getCollider(handle);
|
766
|
+
const collider = worldProxy.getCollider(handle);
|
790
767
|
const colEvents = colliderEvents.get(handle);
|
791
768
|
const colliderState = colliderStates.get(handle);
|
792
769
|
const rigidBodyHandle = collider === null || collider === void 0 ? void 0 : (_collider$parent = collider.parent()) === null || _collider$parent === void 0 ? void 0 : _collider$parent.handle;
|
793
|
-
const rigidBody = rigidBodyHandle !== undefined ?
|
770
|
+
const rigidBody = rigidBodyHandle !== undefined ? worldProxy.getRigidBody(rigidBodyHandle) : undefined;
|
794
771
|
const rbEvents = rigidBody && rigidBodyHandle !== undefined ? rigidBodyEvents.get(rigidBodyHandle) : undefined;
|
795
772
|
const rigidBodyState = rigidBodyHandle !== undefined ? rigidBodyStates.get(rigidBodyHandle) : undefined;
|
796
773
|
const source = {
|
@@ -812,7 +789,7 @@ const Physics = ({
|
|
812
789
|
accumulator: 0
|
813
790
|
});
|
814
791
|
const step = React.useCallback(dt => {
|
815
|
-
const world =
|
792
|
+
const world = worldProxy;
|
816
793
|
/* Check if the timestep is supposed to be variable. We'll do this here
|
817
794
|
once so we don't have to string-check every frame. */
|
818
795
|
|
@@ -827,12 +804,12 @@ const Physics = ({
|
|
827
804
|
const stepWorld = () => {
|
828
805
|
// Trigger beforeStep callbacks
|
829
806
|
beforeStepCallbacks.forEach(callback => {
|
830
|
-
callback.current(
|
807
|
+
callback.current(worldProxy);
|
831
808
|
});
|
832
809
|
world.step(eventQueue); // Trigger afterStep callbacks
|
833
810
|
|
834
811
|
afterStepCallbacks.forEach(callback => {
|
835
|
-
callback.current(
|
812
|
+
callback.current(worldProxy);
|
836
813
|
});
|
837
814
|
};
|
838
815
|
|
@@ -1022,7 +999,7 @@ const Physics = ({
|
|
1022
999
|
}, [_paused, _timeStep, _interpolate]);
|
1023
1000
|
const context = React.useMemo(() => ({
|
1024
1001
|
rapier,
|
1025
|
-
world:
|
1002
|
+
world: worldProxy,
|
1026
1003
|
physicsOptions: {
|
1027
1004
|
colliders: _colliders,
|
1028
1005
|
gravity: _gravity
|
@@ -1068,6 +1045,33 @@ function _extends() {
|
|
1068
1045
|
return _extends.apply(this, arguments);
|
1069
1046
|
}
|
1070
1047
|
|
1048
|
+
/**
|
1049
|
+
* Initiate an instance and return a safe getter
|
1050
|
+
*/
|
1051
|
+
|
1052
|
+
const useImperativeInstance = (createFn, destroyFn, dependencyList) => {
|
1053
|
+
const ref = React.useRef();
|
1054
|
+
const getInstance = React.useCallback(() => {
|
1055
|
+
if (!ref.current) {
|
1056
|
+
ref.current = createFn();
|
1057
|
+
}
|
1058
|
+
|
1059
|
+
return ref.current;
|
1060
|
+
}, dependencyList);
|
1061
|
+
React.useEffect(() => {
|
1062
|
+
// Save the destroy function and instance
|
1063
|
+
const instance = getInstance();
|
1064
|
+
|
1065
|
+
const destroy = () => destroyFn(instance);
|
1066
|
+
|
1067
|
+
return () => {
|
1068
|
+
destroy();
|
1069
|
+
ref.current = undefined;
|
1070
|
+
};
|
1071
|
+
}, [getInstance]);
|
1072
|
+
return getInstance;
|
1073
|
+
};
|
1074
|
+
|
1071
1075
|
/**
|
1072
1076
|
* Takes an object resembling a Vector3 and returs a Three.Vector3
|
1073
1077
|
* @category Math helpers
|
@@ -1167,7 +1171,7 @@ const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((prop
|
|
1167
1171
|
colliderRef.current = collider;
|
1168
1172
|
return collider;
|
1169
1173
|
}, collider => {
|
1170
|
-
world.removeCollider(collider);
|
1174
|
+
world.removeCollider(collider, true);
|
1171
1175
|
}, [...immutablePropArray, rigidBodyContext]);
|
1172
1176
|
React.useEffect(() => {
|
1173
1177
|
const collider = getInstance();
|
@@ -1669,7 +1673,7 @@ const useImpulseJoint = (body1, body2, params) => {
|
|
1669
1673
|
const jointRef = React.useRef();
|
1670
1674
|
useImperativeInstance(() => {
|
1671
1675
|
if (body1.current && body2.current) {
|
1672
|
-
const newJoint = world.createImpulseJoint(params, body1.current, body2.current);
|
1676
|
+
const newJoint = world.createImpulseJoint(params, body1.current, body2.current, true);
|
1673
1677
|
jointRef.current = newJoint; // console.log(body1.current, body2.current, newJoint);
|
1674
1678
|
|
1675
1679
|
return newJoint;
|
@@ -1677,7 +1681,7 @@ const useImpulseJoint = (body1, body2, params) => {
|
|
1677
1681
|
}, joint => {
|
1678
1682
|
if (joint) {
|
1679
1683
|
jointRef.current = undefined;
|
1680
|
-
world.removeImpulseJoint(joint);
|
1684
|
+
world.removeImpulseJoint(joint, true);
|
1681
1685
|
}
|
1682
1686
|
}, []);
|
1683
1687
|
return jointRef;
|
@@ -72,40 +72,6 @@ function _objectSpread2(target) {
|
|
72
72
|
return target;
|
73
73
|
}
|
74
74
|
|
75
|
-
const createWorldApi = getWorld => {
|
76
|
-
return {
|
77
|
-
raw: () => getWorld(),
|
78
|
-
getCollider: handle => getWorld().getCollider(handle),
|
79
|
-
getRigidBody: handle => getWorld().getRigidBody(handle),
|
80
|
-
createRigidBody: desc => getWorld().createRigidBody(desc),
|
81
|
-
createCollider: (desc, rigidBody) => getWorld().createCollider(desc, rigidBody),
|
82
|
-
removeRigidBody: rigidBody => {
|
83
|
-
if (!getWorld().bodies.contains(rigidBody.handle)) return;
|
84
|
-
getWorld().removeRigidBody(rigidBody);
|
85
|
-
},
|
86
|
-
removeCollider: (collider, wakeUp = true) => {
|
87
|
-
if (!getWorld().colliders.contains(collider.handle)) return;
|
88
|
-
getWorld().removeCollider(collider, wakeUp);
|
89
|
-
},
|
90
|
-
createImpulseJoint: (params, rigidBodyA, rigidBodyB, wakeUp = true) => getWorld().createImpulseJoint(params, rigidBodyA, rigidBodyB, wakeUp),
|
91
|
-
removeImpulseJoint: (joint, wakeUp = true) => {
|
92
|
-
if (!getWorld().impulseJoints.contains(joint.handle)) return;
|
93
|
-
getWorld().removeImpulseJoint(joint, wakeUp);
|
94
|
-
},
|
95
|
-
forEachCollider: callback => getWorld().forEachCollider(callback),
|
96
|
-
setGravity: ({
|
97
|
-
x,
|
98
|
-
y,
|
99
|
-
z
|
100
|
-
}) => getWorld().gravity = {
|
101
|
-
x,
|
102
|
-
y,
|
103
|
-
z
|
104
|
-
},
|
105
|
-
debugRender: () => getWorld().debugRender()
|
106
|
-
};
|
107
|
-
};
|
108
|
-
|
109
75
|
const _quaternion = new three.Quaternion();
|
110
76
|
new three.Euler();
|
111
77
|
const _vector3 = new three.Vector3();
|
@@ -684,30 +650,37 @@ const Debug = /*#__PURE__*/React.memo(() => {
|
|
684
650
|
});
|
685
651
|
|
686
652
|
/**
|
687
|
-
*
|
653
|
+
* Creates a proxy that will create a singleton instance of the given class
|
654
|
+
* when a property is accessed, and not before.
|
655
|
+
*
|
656
|
+
* @returns A proxy and a reset function, so that the instance can created again
|
688
657
|
*/
|
658
|
+
const createSingletonProxy = createInstance => {
|
659
|
+
let instance;
|
660
|
+
const handler = {
|
661
|
+
get(target, prop) {
|
662
|
+
if (!instance) {
|
663
|
+
instance = createInstance();
|
664
|
+
}
|
689
665
|
|
690
|
-
|
691
|
-
const ref = React.useRef();
|
692
|
-
const getInstance = React.useCallback(() => {
|
693
|
-
if (!ref.current) {
|
694
|
-
ref.current = createFn();
|
666
|
+
return Reflect.get(instance, prop);
|
695
667
|
}
|
696
668
|
|
697
|
-
|
698
|
-
},
|
699
|
-
React.useEffect(() => {
|
700
|
-
// Save the destroy function and instance
|
701
|
-
const instance = getInstance();
|
669
|
+
};
|
670
|
+
const proxy = new Proxy({}, handler);
|
702
671
|
|
703
|
-
|
672
|
+
const reset = () => {
|
673
|
+
instance = undefined;
|
674
|
+
};
|
675
|
+
/**
|
676
|
+
* Return the proxy and a reset function
|
677
|
+
*/
|
704
678
|
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
}
|
710
|
-
return getInstance;
|
679
|
+
|
680
|
+
return {
|
681
|
+
proxy,
|
682
|
+
reset
|
683
|
+
};
|
711
684
|
};
|
712
685
|
|
713
686
|
const rapierContext = /*#__PURE__*/React.createContext(undefined);
|
@@ -759,38 +732,42 @@ const Physics = ({
|
|
759
732
|
const rapier = useAsset.useAsset(importRapier);
|
760
733
|
const {
|
761
734
|
invalidate
|
762
|
-
} = fiber.useThree();
|
763
|
-
|
764
|
-
const getWorld = useImperativeInstance(() => {
|
765
|
-
return new rapier.World(vectorArrayToVector3(_gravity));
|
766
|
-
}, world => {
|
767
|
-
world.free();
|
768
|
-
}, []);
|
735
|
+
} = fiber.useThree();
|
769
736
|
const rigidBodyStates = useConst(() => new Map());
|
770
737
|
const colliderStates = useConst(() => new Map());
|
771
738
|
const rigidBodyEvents = useConst(() => new Map());
|
772
739
|
const colliderEvents = useConst(() => new Map());
|
773
740
|
const eventQueue = useConst(() => new rapier3dCompat.EventQueue(false));
|
774
741
|
const beforeStepCallbacks = useConst(() => new Set());
|
775
|
-
const afterStepCallbacks = useConst(() => new Set());
|
742
|
+
const afterStepCallbacks = useConst(() => new Set());
|
743
|
+
/**
|
744
|
+
* Initiate the world
|
745
|
+
* This creates a singleton proxy, so that the world is only created when
|
746
|
+
* something within it is accessed.
|
747
|
+
*/
|
776
748
|
|
749
|
+
const {
|
750
|
+
proxy: worldProxy,
|
751
|
+
reset: resetWorldProxy
|
752
|
+
} = useConst(() => createSingletonProxy(() => new rapier.World(vectorArrayToVector3(_gravity))));
|
777
753
|
React.useEffect(() => {
|
778
|
-
|
754
|
+
return () => {
|
755
|
+
worldProxy.free();
|
756
|
+
resetWorldProxy();
|
757
|
+
};
|
758
|
+
}, []); // Update gravity
|
779
759
|
|
780
|
-
|
781
|
-
|
782
|
-
}
|
760
|
+
React.useEffect(() => {
|
761
|
+
worldProxy.gravity = vectorArrayToVector3(_gravity);
|
783
762
|
}, [_gravity]);
|
784
|
-
const api = React.useMemo(() => createWorldApi(getWorld), []);
|
785
763
|
const getSourceFromColliderHandle = React.useCallback(handle => {
|
786
764
|
var _collider$parent;
|
787
765
|
|
788
|
-
const
|
789
|
-
const collider = world.getCollider(handle);
|
766
|
+
const collider = worldProxy.getCollider(handle);
|
790
767
|
const colEvents = colliderEvents.get(handle);
|
791
768
|
const colliderState = colliderStates.get(handle);
|
792
769
|
const rigidBodyHandle = collider === null || collider === void 0 ? void 0 : (_collider$parent = collider.parent()) === null || _collider$parent === void 0 ? void 0 : _collider$parent.handle;
|
793
|
-
const rigidBody = rigidBodyHandle !== undefined ?
|
770
|
+
const rigidBody = rigidBodyHandle !== undefined ? worldProxy.getRigidBody(rigidBodyHandle) : undefined;
|
794
771
|
const rbEvents = rigidBody && rigidBodyHandle !== undefined ? rigidBodyEvents.get(rigidBodyHandle) : undefined;
|
795
772
|
const rigidBodyState = rigidBodyHandle !== undefined ? rigidBodyStates.get(rigidBodyHandle) : undefined;
|
796
773
|
const source = {
|
@@ -812,7 +789,7 @@ const Physics = ({
|
|
812
789
|
accumulator: 0
|
813
790
|
});
|
814
791
|
const step = React.useCallback(dt => {
|
815
|
-
const world =
|
792
|
+
const world = worldProxy;
|
816
793
|
/* Check if the timestep is supposed to be variable. We'll do this here
|
817
794
|
once so we don't have to string-check every frame. */
|
818
795
|
|
@@ -827,12 +804,12 @@ const Physics = ({
|
|
827
804
|
const stepWorld = () => {
|
828
805
|
// Trigger beforeStep callbacks
|
829
806
|
beforeStepCallbacks.forEach(callback => {
|
830
|
-
callback.current(
|
807
|
+
callback.current(worldProxy);
|
831
808
|
});
|
832
809
|
world.step(eventQueue); // Trigger afterStep callbacks
|
833
810
|
|
834
811
|
afterStepCallbacks.forEach(callback => {
|
835
|
-
callback.current(
|
812
|
+
callback.current(worldProxy);
|
836
813
|
});
|
837
814
|
};
|
838
815
|
|
@@ -1022,7 +999,7 @@ const Physics = ({
|
|
1022
999
|
}, [_paused, _timeStep, _interpolate]);
|
1023
1000
|
const context = React.useMemo(() => ({
|
1024
1001
|
rapier,
|
1025
|
-
world:
|
1002
|
+
world: worldProxy,
|
1026
1003
|
physicsOptions: {
|
1027
1004
|
colliders: _colliders,
|
1028
1005
|
gravity: _gravity
|
@@ -1068,6 +1045,33 @@ function _extends() {
|
|
1068
1045
|
return _extends.apply(this, arguments);
|
1069
1046
|
}
|
1070
1047
|
|
1048
|
+
/**
|
1049
|
+
* Initiate an instance and return a safe getter
|
1050
|
+
*/
|
1051
|
+
|
1052
|
+
const useImperativeInstance = (createFn, destroyFn, dependencyList) => {
|
1053
|
+
const ref = React.useRef();
|
1054
|
+
const getInstance = React.useCallback(() => {
|
1055
|
+
if (!ref.current) {
|
1056
|
+
ref.current = createFn();
|
1057
|
+
}
|
1058
|
+
|
1059
|
+
return ref.current;
|
1060
|
+
}, dependencyList);
|
1061
|
+
React.useEffect(() => {
|
1062
|
+
// Save the destroy function and instance
|
1063
|
+
const instance = getInstance();
|
1064
|
+
|
1065
|
+
const destroy = () => destroyFn(instance);
|
1066
|
+
|
1067
|
+
return () => {
|
1068
|
+
destroy();
|
1069
|
+
ref.current = undefined;
|
1070
|
+
};
|
1071
|
+
}, [getInstance]);
|
1072
|
+
return getInstance;
|
1073
|
+
};
|
1074
|
+
|
1071
1075
|
/**
|
1072
1076
|
* Takes an object resembling a Vector3 and returs a Three.Vector3
|
1073
1077
|
* @category Math helpers
|
@@ -1167,7 +1171,7 @@ const AnyCollider = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((prop
|
|
1167
1171
|
colliderRef.current = collider;
|
1168
1172
|
return collider;
|
1169
1173
|
}, collider => {
|
1170
|
-
world.removeCollider(collider);
|
1174
|
+
world.removeCollider(collider, true);
|
1171
1175
|
}, [...immutablePropArray, rigidBodyContext]);
|
1172
1176
|
React.useEffect(() => {
|
1173
1177
|
const collider = getInstance();
|
@@ -1669,7 +1673,7 @@ const useImpulseJoint = (body1, body2, params) => {
|
|
1669
1673
|
const jointRef = React.useRef();
|
1670
1674
|
useImperativeInstance(() => {
|
1671
1675
|
if (body1.current && body2.current) {
|
1672
|
-
const newJoint = world.createImpulseJoint(params, body1.current, body2.current);
|
1676
|
+
const newJoint = world.createImpulseJoint(params, body1.current, body2.current, true);
|
1673
1677
|
jointRef.current = newJoint; // console.log(body1.current, body2.current, newJoint);
|
1674
1678
|
|
1675
1679
|
return newJoint;
|
@@ -1677,7 +1681,7 @@ const useImpulseJoint = (body1, body2, params) => {
|
|
1677
1681
|
}, joint => {
|
1678
1682
|
if (joint) {
|
1679
1683
|
jointRef.current = undefined;
|
1680
|
-
world.removeImpulseJoint(joint);
|
1684
|
+
world.removeImpulseJoint(joint, true);
|
1681
1685
|
}
|
1682
1686
|
}, []);
|
1683
1687
|
return jointRef;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { ActiveEvents, ColliderDesc, EventQueue, RigidBodyDesc } from '@dimforge/rapier3d-compat';
|
2
2
|
export { CoefficientCombineRule, Collider as RapierCollider, RigidBody as RapierRigidBody } from '@dimforge/rapier3d-compat';
|
3
3
|
import { useFrame, useThree } from '@react-three/fiber';
|
4
|
-
import React, { useRef, useEffect, memo, useMemo, useContext, useState,
|
4
|
+
import React, { useRef, useEffect, memo, useMemo, useContext, useState, createContext, useCallback, forwardRef, Fragment } from 'react';
|
5
5
|
import { Quaternion, Euler, Vector3, Object3D, Matrix4, BufferAttribute, MathUtils, DynamicDrawUsage } from 'three';
|
6
6
|
import { useAsset } from 'use-asset';
|
7
7
|
import { mergeVertices } from 'three-stdlib';
|
@@ -47,40 +47,6 @@ function _objectSpread2(target) {
|
|
47
47
|
return target;
|
48
48
|
}
|
49
49
|
|
50
|
-
const createWorldApi = getWorld => {
|
51
|
-
return {
|
52
|
-
raw: () => getWorld(),
|
53
|
-
getCollider: handle => getWorld().getCollider(handle),
|
54
|
-
getRigidBody: handle => getWorld().getRigidBody(handle),
|
55
|
-
createRigidBody: desc => getWorld().createRigidBody(desc),
|
56
|
-
createCollider: (desc, rigidBody) => getWorld().createCollider(desc, rigidBody),
|
57
|
-
removeRigidBody: rigidBody => {
|
58
|
-
if (!getWorld().bodies.contains(rigidBody.handle)) return;
|
59
|
-
getWorld().removeRigidBody(rigidBody);
|
60
|
-
},
|
61
|
-
removeCollider: (collider, wakeUp = true) => {
|
62
|
-
if (!getWorld().colliders.contains(collider.handle)) return;
|
63
|
-
getWorld().removeCollider(collider, wakeUp);
|
64
|
-
},
|
65
|
-
createImpulseJoint: (params, rigidBodyA, rigidBodyB, wakeUp = true) => getWorld().createImpulseJoint(params, rigidBodyA, rigidBodyB, wakeUp),
|
66
|
-
removeImpulseJoint: (joint, wakeUp = true) => {
|
67
|
-
if (!getWorld().impulseJoints.contains(joint.handle)) return;
|
68
|
-
getWorld().removeImpulseJoint(joint, wakeUp);
|
69
|
-
},
|
70
|
-
forEachCollider: callback => getWorld().forEachCollider(callback),
|
71
|
-
setGravity: ({
|
72
|
-
x,
|
73
|
-
y,
|
74
|
-
z
|
75
|
-
}) => getWorld().gravity = {
|
76
|
-
x,
|
77
|
-
y,
|
78
|
-
z
|
79
|
-
},
|
80
|
-
debugRender: () => getWorld().debugRender()
|
81
|
-
};
|
82
|
-
};
|
83
|
-
|
84
50
|
const _quaternion = new Quaternion();
|
85
51
|
new Euler();
|
86
52
|
const _vector3 = new Vector3();
|
@@ -659,30 +625,37 @@ const Debug = /*#__PURE__*/memo(() => {
|
|
659
625
|
});
|
660
626
|
|
661
627
|
/**
|
662
|
-
*
|
628
|
+
* Creates a proxy that will create a singleton instance of the given class
|
629
|
+
* when a property is accessed, and not before.
|
630
|
+
*
|
631
|
+
* @returns A proxy and a reset function, so that the instance can created again
|
663
632
|
*/
|
633
|
+
const createSingletonProxy = createInstance => {
|
634
|
+
let instance;
|
635
|
+
const handler = {
|
636
|
+
get(target, prop) {
|
637
|
+
if (!instance) {
|
638
|
+
instance = createInstance();
|
639
|
+
}
|
664
640
|
|
665
|
-
|
666
|
-
const ref = useRef();
|
667
|
-
const getInstance = useCallback(() => {
|
668
|
-
if (!ref.current) {
|
669
|
-
ref.current = createFn();
|
641
|
+
return Reflect.get(instance, prop);
|
670
642
|
}
|
671
643
|
|
672
|
-
|
673
|
-
},
|
674
|
-
useEffect(() => {
|
675
|
-
// Save the destroy function and instance
|
676
|
-
const instance = getInstance();
|
644
|
+
};
|
645
|
+
const proxy = new Proxy({}, handler);
|
677
646
|
|
678
|
-
|
647
|
+
const reset = () => {
|
648
|
+
instance = undefined;
|
649
|
+
};
|
650
|
+
/**
|
651
|
+
* Return the proxy and a reset function
|
652
|
+
*/
|
679
653
|
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
}
|
685
|
-
return getInstance;
|
654
|
+
|
655
|
+
return {
|
656
|
+
proxy,
|
657
|
+
reset
|
658
|
+
};
|
686
659
|
};
|
687
660
|
|
688
661
|
const rapierContext = /*#__PURE__*/createContext(undefined);
|
@@ -734,38 +707,42 @@ const Physics = ({
|
|
734
707
|
const rapier = useAsset(importRapier);
|
735
708
|
const {
|
736
709
|
invalidate
|
737
|
-
} = useThree();
|
738
|
-
|
739
|
-
const getWorld = useImperativeInstance(() => {
|
740
|
-
return new rapier.World(vectorArrayToVector3(_gravity));
|
741
|
-
}, world => {
|
742
|
-
world.free();
|
743
|
-
}, []);
|
710
|
+
} = useThree();
|
744
711
|
const rigidBodyStates = useConst(() => new Map());
|
745
712
|
const colliderStates = useConst(() => new Map());
|
746
713
|
const rigidBodyEvents = useConst(() => new Map());
|
747
714
|
const colliderEvents = useConst(() => new Map());
|
748
715
|
const eventQueue = useConst(() => new EventQueue(false));
|
749
716
|
const beforeStepCallbacks = useConst(() => new Set());
|
750
|
-
const afterStepCallbacks = useConst(() => new Set());
|
717
|
+
const afterStepCallbacks = useConst(() => new Set());
|
718
|
+
/**
|
719
|
+
* Initiate the world
|
720
|
+
* This creates a singleton proxy, so that the world is only created when
|
721
|
+
* something within it is accessed.
|
722
|
+
*/
|
751
723
|
|
724
|
+
const {
|
725
|
+
proxy: worldProxy,
|
726
|
+
reset: resetWorldProxy
|
727
|
+
} = useConst(() => createSingletonProxy(() => new rapier.World(vectorArrayToVector3(_gravity))));
|
752
728
|
useEffect(() => {
|
753
|
-
|
729
|
+
return () => {
|
730
|
+
worldProxy.free();
|
731
|
+
resetWorldProxy();
|
732
|
+
};
|
733
|
+
}, []); // Update gravity
|
754
734
|
|
755
|
-
|
756
|
-
|
757
|
-
}
|
735
|
+
useEffect(() => {
|
736
|
+
worldProxy.gravity = vectorArrayToVector3(_gravity);
|
758
737
|
}, [_gravity]);
|
759
|
-
const api = useMemo(() => createWorldApi(getWorld), []);
|
760
738
|
const getSourceFromColliderHandle = useCallback(handle => {
|
761
739
|
var _collider$parent;
|
762
740
|
|
763
|
-
const
|
764
|
-
const collider = world.getCollider(handle);
|
741
|
+
const collider = worldProxy.getCollider(handle);
|
765
742
|
const colEvents = colliderEvents.get(handle);
|
766
743
|
const colliderState = colliderStates.get(handle);
|
767
744
|
const rigidBodyHandle = collider === null || collider === void 0 ? void 0 : (_collider$parent = collider.parent()) === null || _collider$parent === void 0 ? void 0 : _collider$parent.handle;
|
768
|
-
const rigidBody = rigidBodyHandle !== undefined ?
|
745
|
+
const rigidBody = rigidBodyHandle !== undefined ? worldProxy.getRigidBody(rigidBodyHandle) : undefined;
|
769
746
|
const rbEvents = rigidBody && rigidBodyHandle !== undefined ? rigidBodyEvents.get(rigidBodyHandle) : undefined;
|
770
747
|
const rigidBodyState = rigidBodyHandle !== undefined ? rigidBodyStates.get(rigidBodyHandle) : undefined;
|
771
748
|
const source = {
|
@@ -787,7 +764,7 @@ const Physics = ({
|
|
787
764
|
accumulator: 0
|
788
765
|
});
|
789
766
|
const step = useCallback(dt => {
|
790
|
-
const world =
|
767
|
+
const world = worldProxy;
|
791
768
|
/* Check if the timestep is supposed to be variable. We'll do this here
|
792
769
|
once so we don't have to string-check every frame. */
|
793
770
|
|
@@ -802,12 +779,12 @@ const Physics = ({
|
|
802
779
|
const stepWorld = () => {
|
803
780
|
// Trigger beforeStep callbacks
|
804
781
|
beforeStepCallbacks.forEach(callback => {
|
805
|
-
callback.current(
|
782
|
+
callback.current(worldProxy);
|
806
783
|
});
|
807
784
|
world.step(eventQueue); // Trigger afterStep callbacks
|
808
785
|
|
809
786
|
afterStepCallbacks.forEach(callback => {
|
810
|
-
callback.current(
|
787
|
+
callback.current(worldProxy);
|
811
788
|
});
|
812
789
|
};
|
813
790
|
|
@@ -997,7 +974,7 @@ const Physics = ({
|
|
997
974
|
}, [_paused, _timeStep, _interpolate]);
|
998
975
|
const context = useMemo(() => ({
|
999
976
|
rapier,
|
1000
|
-
world:
|
977
|
+
world: worldProxy,
|
1001
978
|
physicsOptions: {
|
1002
979
|
colliders: _colliders,
|
1003
980
|
gravity: _gravity
|
@@ -1043,6 +1020,33 @@ function _extends() {
|
|
1043
1020
|
return _extends.apply(this, arguments);
|
1044
1021
|
}
|
1045
1022
|
|
1023
|
+
/**
|
1024
|
+
* Initiate an instance and return a safe getter
|
1025
|
+
*/
|
1026
|
+
|
1027
|
+
const useImperativeInstance = (createFn, destroyFn, dependencyList) => {
|
1028
|
+
const ref = useRef();
|
1029
|
+
const getInstance = useCallback(() => {
|
1030
|
+
if (!ref.current) {
|
1031
|
+
ref.current = createFn();
|
1032
|
+
}
|
1033
|
+
|
1034
|
+
return ref.current;
|
1035
|
+
}, dependencyList);
|
1036
|
+
useEffect(() => {
|
1037
|
+
// Save the destroy function and instance
|
1038
|
+
const instance = getInstance();
|
1039
|
+
|
1040
|
+
const destroy = () => destroyFn(instance);
|
1041
|
+
|
1042
|
+
return () => {
|
1043
|
+
destroy();
|
1044
|
+
ref.current = undefined;
|
1045
|
+
};
|
1046
|
+
}, [getInstance]);
|
1047
|
+
return getInstance;
|
1048
|
+
};
|
1049
|
+
|
1046
1050
|
/**
|
1047
1051
|
* Takes an object resembling a Vector3 and returs a Three.Vector3
|
1048
1052
|
* @category Math helpers
|
@@ -1142,7 +1146,7 @@ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwarded
|
|
1142
1146
|
colliderRef.current = collider;
|
1143
1147
|
return collider;
|
1144
1148
|
}, collider => {
|
1145
|
-
world.removeCollider(collider);
|
1149
|
+
world.removeCollider(collider, true);
|
1146
1150
|
}, [...immutablePropArray, rigidBodyContext]);
|
1147
1151
|
useEffect(() => {
|
1148
1152
|
const collider = getInstance();
|
@@ -1644,7 +1648,7 @@ const useImpulseJoint = (body1, body2, params) => {
|
|
1644
1648
|
const jointRef = useRef();
|
1645
1649
|
useImperativeInstance(() => {
|
1646
1650
|
if (body1.current && body2.current) {
|
1647
|
-
const newJoint = world.createImpulseJoint(params, body1.current, body2.current);
|
1651
|
+
const newJoint = world.createImpulseJoint(params, body1.current, body2.current, true);
|
1648
1652
|
jointRef.current = newJoint; // console.log(body1.current, body2.current, newJoint);
|
1649
1653
|
|
1650
1654
|
return newJoint;
|
@@ -1652,7 +1656,7 @@ const useImpulseJoint = (body1, body2, params) => {
|
|
1652
1656
|
}, joint => {
|
1653
1657
|
if (joint) {
|
1654
1658
|
jointRef.current = undefined;
|
1655
|
-
world.removeImpulseJoint(joint);
|
1659
|
+
world.removeImpulseJoint(joint, true);
|
1656
1660
|
}
|
1657
1661
|
}, []);
|
1658
1662
|
return jointRef;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@react-three/rapier",
|
3
|
-
"version": "0.
|
3
|
+
"version": "1.0.0-canary.2",
|
4
4
|
"source": "src/index.ts",
|
5
5
|
"main": "dist/react-three-rapier.cjs.js",
|
6
6
|
"module": "dist/react-three-rapier.esm.js",
|
@@ -8,9 +8,7 @@
|
|
8
8
|
"files": [
|
9
9
|
"dist"
|
10
10
|
],
|
11
|
-
"scripts": {
|
12
|
-
"ts": "tsc -w"
|
13
|
-
},
|
11
|
+
"scripts": {},
|
14
12
|
"devDependencies": {
|
15
13
|
"@react-three/drei": "9.45.0",
|
16
14
|
"@react-three/fiber": "8.9.1",
|
@@ -1,17 +0,0 @@
|
|
1
|
-
import { Collider, ColliderDesc, DebugRenderBuffers, ImpulseJoint, JointData, RigidBody, RigidBodyDesc, World } from "@dimforge/rapier3d-compat";
|
2
|
-
import { Vector3 } from "three";
|
3
|
-
export interface WorldApi {
|
4
|
-
raw(): World;
|
5
|
-
getCollider(handle: number): Collider | undefined;
|
6
|
-
getRigidBody(handle: number): RigidBody | undefined;
|
7
|
-
createRigidBody(desc: RigidBodyDesc): RigidBody;
|
8
|
-
createCollider(desc: ColliderDesc, parent?: RigidBody): Collider;
|
9
|
-
removeRigidBody(rigidBody: RigidBody): void;
|
10
|
-
removeCollider(collider: Collider, wakeUp?: boolean): void;
|
11
|
-
createImpulseJoint(params: JointData, rigidBodyA: RigidBody, rigidBodyB: RigidBody, wakeUp?: boolean): ImpulseJoint;
|
12
|
-
removeImpulseJoint(joint: ImpulseJoint, wakeUp?: boolean): void;
|
13
|
-
forEachCollider(callback: (collider: Collider) => void): void;
|
14
|
-
setGravity(gravity: Vector3): void;
|
15
|
-
debugRender(): DebugRenderBuffers;
|
16
|
-
}
|
17
|
-
export declare const createWorldApi: (getWorld: () => World) => WorldApi;
|