@react-three/rapier 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/declarations/src/components/Physics.d.ts +9 -6
- package/dist/declarations/src/index.d.ts +0 -3
- package/dist/react-three-rapier.cjs.dev.js +77 -239
- package/dist/react-three-rapier.cjs.prod.js +77 -239
- package/dist/react-three-rapier.esm.js +81 -241
- package/package.json +3 -3
- package/readme.md +7 -52
- package/dist/declarations/src/components/Attractor.d.ts +0 -50
@@ -178,6 +178,61 @@ function useConst(initialValue) {
|
|
178
178
|
return ref.current.value;
|
179
179
|
}
|
180
180
|
|
181
|
+
const useRaf = callback => {
|
182
|
+
const cb = React.useRef(callback);
|
183
|
+
const raf = React.useRef(0);
|
184
|
+
const lastFrame = React.useRef(0);
|
185
|
+
React.useEffect(() => {
|
186
|
+
cb.current = callback;
|
187
|
+
}, [callback]);
|
188
|
+
React.useEffect(() => {
|
189
|
+
const loop = () => {
|
190
|
+
const now = performance.now();
|
191
|
+
const delta = now - lastFrame.current;
|
192
|
+
raf.current = requestAnimationFrame(loop);
|
193
|
+
cb.current(delta / 1000);
|
194
|
+
lastFrame.current = now;
|
195
|
+
};
|
196
|
+
|
197
|
+
raf.current = requestAnimationFrame(loop);
|
198
|
+
return () => cancelAnimationFrame(raf.current);
|
199
|
+
}, []);
|
200
|
+
};
|
201
|
+
|
202
|
+
const UseFrameStepper = ({
|
203
|
+
onStep,
|
204
|
+
updatePriority
|
205
|
+
}) => {
|
206
|
+
fiber.useFrame((_, dt) => {
|
207
|
+
onStep(dt);
|
208
|
+
}, updatePriority);
|
209
|
+
return null;
|
210
|
+
};
|
211
|
+
|
212
|
+
const RafStepper = ({
|
213
|
+
onStep
|
214
|
+
}) => {
|
215
|
+
useRaf(dt => {
|
216
|
+
onStep(dt);
|
217
|
+
});
|
218
|
+
return null;
|
219
|
+
};
|
220
|
+
|
221
|
+
const FrameStepper = ({
|
222
|
+
onStep,
|
223
|
+
type,
|
224
|
+
updatePriority
|
225
|
+
}) => {
|
226
|
+
return type === "independent" ? /*#__PURE__*/React__default["default"].createElement(RafStepper, {
|
227
|
+
onStep: onStep
|
228
|
+
}) : /*#__PURE__*/React__default["default"].createElement(UseFrameStepper, {
|
229
|
+
onStep: onStep,
|
230
|
+
updatePriority: updatePriority
|
231
|
+
});
|
232
|
+
};
|
233
|
+
|
234
|
+
var FrameStepper$1 = /*#__PURE__*/React.memo(FrameStepper);
|
235
|
+
|
181
236
|
function _objectWithoutPropertiesLoose(source, excluded) {
|
182
237
|
if (source == null) return {};
|
183
238
|
var target = {};
|
@@ -606,146 +661,27 @@ const useChildColliderProps = (ref, options, ignoreMeshColliders = true) => {
|
|
606
661
|
return colliderProps;
|
607
662
|
};
|
608
663
|
|
609
|
-
const
|
610
|
-
static: (s, m2, r, d, G) => s,
|
611
|
-
linear: (s, m2, r, d, G) => s * (d / r),
|
612
|
-
newtonian: (s, m2, r, d, G) => G * s * m2 / Math.pow(d, 2)
|
613
|
-
};
|
614
|
-
const applyAttractorForceOnRigidBody = (rigidBody, {
|
615
|
-
object,
|
616
|
-
strength,
|
617
|
-
range,
|
618
|
-
gravitationalConstant,
|
619
|
-
collisionGroups,
|
620
|
-
type
|
621
|
-
}) => {
|
622
|
-
const rbPosition = rigidBody.translation();
|
623
|
-
|
624
|
-
_position.set(rbPosition.x, rbPosition.y, rbPosition.z);
|
625
|
-
|
626
|
-
const worldPosition = object.getWorldPosition(new three.Vector3());
|
627
|
-
const distance = worldPosition.distanceTo(_position);
|
628
|
-
|
629
|
-
if (distance < range) {
|
630
|
-
let force = calcForceByType[type](strength, rigidBody.mass(), range, distance, gravitationalConstant); // Prevent wild forces when Attractors collide
|
631
|
-
|
632
|
-
force = force === Infinity ? strength : force; // Naively test if the rigidBody contains a collider in one of the collision groups
|
633
|
-
|
634
|
-
let isRigidBodyInCollisionGroup = collisionGroups === undefined ? true : false;
|
635
|
-
|
636
|
-
if (collisionGroups !== undefined) {
|
637
|
-
for (let i = 0; i < rigidBody.numColliders(); i++) {
|
638
|
-
const collider = rigidBody.collider(i);
|
639
|
-
const colliderCollisionGroups = collider.collisionGroups();
|
640
|
-
|
641
|
-
if ((collisionGroups >> 16 & colliderCollisionGroups) != 0 && (colliderCollisionGroups >> 16 & collisionGroups) != 0) {
|
642
|
-
isRigidBodyInCollisionGroup = true;
|
643
|
-
break;
|
644
|
-
}
|
645
|
-
}
|
646
|
-
}
|
647
|
-
|
648
|
-
if (isRigidBodyInCollisionGroup) {
|
649
|
-
_vector3.set(0, 0, 0).subVectors(worldPosition, _position).normalize().multiplyScalar(force);
|
650
|
-
|
651
|
-
rigidBody.applyImpulse(_vector3, true);
|
652
|
-
}
|
653
|
-
}
|
654
|
-
};
|
655
|
-
const Attractor = /*#__PURE__*/React.memo(props => {
|
656
|
-
const {
|
657
|
-
position = [0, 0, 0],
|
658
|
-
strength = 1,
|
659
|
-
range = 10,
|
660
|
-
type = "static",
|
661
|
-
gravitationalConstant = 6.673e-11,
|
662
|
-
collisionGroups
|
663
|
-
} = props;
|
664
|
+
const Debug = /*#__PURE__*/React.memo(() => {
|
664
665
|
const {
|
665
|
-
|
666
|
+
world
|
666
667
|
} = useRapier();
|
667
|
-
const
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
attractorStates.set(uuid, {
|
675
|
-
object: object.current,
|
676
|
-
strength,
|
677
|
-
range,
|
678
|
-
type,
|
679
|
-
gravitationalConstant,
|
680
|
-
collisionGroups
|
681
|
-
});
|
682
|
-
}
|
683
|
-
|
684
|
-
return () => {
|
685
|
-
attractorStates.delete(uuid);
|
686
|
-
};
|
687
|
-
}, [props]);
|
688
|
-
return /*#__PURE__*/React__default["default"].createElement("object3D", {
|
689
|
-
ref: object,
|
690
|
-
position: position
|
668
|
+
const ref = React.useRef(null);
|
669
|
+
fiber.useFrame(() => {
|
670
|
+
const mesh = ref.current;
|
671
|
+
if (!mesh) return;
|
672
|
+
const buffers = world.debugRender();
|
673
|
+
mesh.geometry.setAttribute("position", new three.BufferAttribute(buffers.vertices, 3));
|
674
|
+
mesh.geometry.setAttribute("color", new three.BufferAttribute(buffers.colors, 4));
|
691
675
|
});
|
676
|
+
return /*#__PURE__*/React__default["default"].createElement("group", null, /*#__PURE__*/React__default["default"].createElement("lineSegments", {
|
677
|
+
ref: ref,
|
678
|
+
frustumCulled: false
|
679
|
+
}, /*#__PURE__*/React__default["default"].createElement("lineBasicMaterial", {
|
680
|
+
color: 0xffffff,
|
681
|
+
vertexColors: true
|
682
|
+
}), /*#__PURE__*/React__default["default"].createElement("bufferGeometry", null)));
|
692
683
|
});
|
693
684
|
|
694
|
-
const useRaf = callback => {
|
695
|
-
const cb = React.useRef(callback);
|
696
|
-
const raf = React.useRef(0);
|
697
|
-
const lastFrame = React.useRef(0);
|
698
|
-
React.useEffect(() => {
|
699
|
-
cb.current = callback;
|
700
|
-
}, [callback]);
|
701
|
-
React.useEffect(() => {
|
702
|
-
const loop = () => {
|
703
|
-
const now = performance.now();
|
704
|
-
const delta = now - lastFrame.current;
|
705
|
-
raf.current = requestAnimationFrame(loop);
|
706
|
-
cb.current(delta / 1000);
|
707
|
-
lastFrame.current = now;
|
708
|
-
};
|
709
|
-
|
710
|
-
raf.current = requestAnimationFrame(loop);
|
711
|
-
return () => cancelAnimationFrame(raf.current);
|
712
|
-
}, []);
|
713
|
-
};
|
714
|
-
|
715
|
-
const UseFrameStepper = ({
|
716
|
-
onStep,
|
717
|
-
updatePriority
|
718
|
-
}) => {
|
719
|
-
fiber.useFrame((_, dt) => {
|
720
|
-
onStep(dt);
|
721
|
-
}, updatePriority);
|
722
|
-
return null;
|
723
|
-
};
|
724
|
-
|
725
|
-
const RafStepper = ({
|
726
|
-
onStep
|
727
|
-
}) => {
|
728
|
-
useRaf(dt => {
|
729
|
-
onStep(dt);
|
730
|
-
});
|
731
|
-
return null;
|
732
|
-
};
|
733
|
-
|
734
|
-
const FrameStepper = ({
|
735
|
-
onStep,
|
736
|
-
type,
|
737
|
-
updatePriority
|
738
|
-
}) => {
|
739
|
-
return type === "independent" ? /*#__PURE__*/React__default["default"].createElement(RafStepper, {
|
740
|
-
onStep: onStep
|
741
|
-
}) : /*#__PURE__*/React__default["default"].createElement(UseFrameStepper, {
|
742
|
-
onStep: onStep,
|
743
|
-
updatePriority: updatePriority
|
744
|
-
});
|
745
|
-
};
|
746
|
-
|
747
|
-
var FrameStepper$1 = /*#__PURE__*/React.memo(FrameStepper);
|
748
|
-
|
749
685
|
const rapierContext = /*#__PURE__*/React.createContext(undefined);
|
750
686
|
|
751
687
|
const getCollisionPayloadFromSource = (target, other) => {
|
@@ -789,7 +725,8 @@ const Physics = ({
|
|
789
725
|
paused: _paused = false,
|
790
726
|
interpolate: _interpolate = true,
|
791
727
|
updatePriority,
|
792
|
-
updateLoop: _updateLoop = "follow"
|
728
|
+
updateLoop: _updateLoop = "follow",
|
729
|
+
debug: _debug = false
|
793
730
|
}) => {
|
794
731
|
const rapier = useAsset.useAsset(importRapier);
|
795
732
|
const {
|
@@ -809,7 +746,6 @@ const Physics = ({
|
|
809
746
|
const rigidBodyEvents = useConst(() => new Map());
|
810
747
|
const colliderEvents = useConst(() => new Map());
|
811
748
|
const eventQueue = useConst(() => new rapier3dCompat.EventQueue(false));
|
812
|
-
const attractorStates = useConst(() => new Map());
|
813
749
|
const beforeStepCallbacks = useConst(() => new Set());
|
814
750
|
const afterStepCallbacks = useConst(() => new Set()); // Init world
|
815
751
|
|
@@ -878,13 +814,7 @@ const Physics = ({
|
|
878
814
|
const clampedDelta = three.MathUtils.clamp(dt, 0, 0.2);
|
879
815
|
|
880
816
|
const stepWorld = () => {
|
881
|
-
//
|
882
|
-
world.forEachRigidBody(body => {
|
883
|
-
attractorStates.forEach(attractorState => {
|
884
|
-
applyAttractorForceOnRigidBody(body, attractorState);
|
885
|
-
});
|
886
|
-
}); // Trigger beforeStep callbacks
|
887
|
-
|
817
|
+
// Trigger beforeStep callbacks
|
888
818
|
beforeStepCallbacks.forEach(callback => {
|
889
819
|
callback.current(api);
|
890
820
|
});
|
@@ -1090,12 +1020,12 @@ const Physics = ({
|
|
1090
1020
|
colliderStates,
|
1091
1021
|
rigidBodyEvents,
|
1092
1022
|
colliderEvents,
|
1093
|
-
attractorStates,
|
1094
1023
|
beforeStepCallbacks,
|
1095
1024
|
afterStepCallbacks,
|
1096
1025
|
isPaused: _paused,
|
1026
|
+
isDebug: _debug,
|
1097
1027
|
step
|
1098
|
-
}), [_paused, step]);
|
1028
|
+
}), [_paused, step, _debug, _colliders, _gravity]);
|
1099
1029
|
const stepCallback = React.useCallback(delta => {
|
1100
1030
|
if (!_paused) {
|
1101
1031
|
step(delta);
|
@@ -1107,7 +1037,7 @@ const Physics = ({
|
|
1107
1037
|
onStep: stepCallback,
|
1108
1038
|
type: _updateLoop,
|
1109
1039
|
updatePriority: updatePriority
|
1110
|
-
}), children);
|
1040
|
+
}), _debug && /*#__PURE__*/React__default["default"].createElement(Debug, null), children);
|
1111
1041
|
};
|
1112
1042
|
|
1113
1043
|
function _extends() {
|
@@ -1623,96 +1553,6 @@ const MeshCollider = /*#__PURE__*/React.memo(props => {
|
|
1623
1553
|
});
|
1624
1554
|
MeshCollider.displayName = "MeshCollider";
|
1625
1555
|
|
1626
|
-
function mapsEqual(map1, map2) {
|
1627
|
-
var testVal;
|
1628
|
-
|
1629
|
-
if (map1.size !== map2.size) {
|
1630
|
-
return false;
|
1631
|
-
}
|
1632
|
-
|
1633
|
-
for (var [key, val] of map1) {
|
1634
|
-
testVal = map2.get(key);
|
1635
|
-
|
1636
|
-
if (testVal !== val || testVal === undefined && !map2.has(key)) {
|
1637
|
-
return false;
|
1638
|
-
}
|
1639
|
-
}
|
1640
|
-
|
1641
|
-
return true;
|
1642
|
-
}
|
1643
|
-
|
1644
|
-
const AttractorHelper = props => {
|
1645
|
-
const {
|
1646
|
-
scene
|
1647
|
-
} = fiber.useThree();
|
1648
|
-
const ref = React.useRef(null);
|
1649
|
-
const normalsHelper = React.useRef();
|
1650
|
-
const color = props.strength > 0 ? 0x0000ff : 0xff0000;
|
1651
|
-
React.useEffect(() => {
|
1652
|
-
if (ref.current) {
|
1653
|
-
normalsHelper.current = new threeStdlib.VertexNormalsHelper(ref.current, props.range, color);
|
1654
|
-
normalsHelper.current.frustumCulled = false;
|
1655
|
-
scene.add(normalsHelper.current);
|
1656
|
-
}
|
1657
|
-
|
1658
|
-
return () => {
|
1659
|
-
if (normalsHelper.current) {
|
1660
|
-
scene.remove(normalsHelper.current);
|
1661
|
-
}
|
1662
|
-
};
|
1663
|
-
}, [props]);
|
1664
|
-
fiber.useFrame(() => {
|
1665
|
-
if (ref.current) {
|
1666
|
-
var _normalsHelper$curren;
|
1667
|
-
|
1668
|
-
const worldPosition = props.object.getWorldPosition(_vector3);
|
1669
|
-
ref.current.position.copy(worldPosition);
|
1670
|
-
(_normalsHelper$curren = normalsHelper.current) === null || _normalsHelper$curren === void 0 ? void 0 : _normalsHelper$curren.update();
|
1671
|
-
}
|
1672
|
-
});
|
1673
|
-
return /*#__PURE__*/React__default["default"].createElement("mesh", {
|
1674
|
-
ref: ref,
|
1675
|
-
position: props.object.position,
|
1676
|
-
frustumCulled: false
|
1677
|
-
}, /*#__PURE__*/React__default["default"].createElement("sphereGeometry", {
|
1678
|
-
args: [0.2, 6, 6]
|
1679
|
-
}), /*#__PURE__*/React__default["default"].createElement("meshBasicMaterial", {
|
1680
|
-
color: color,
|
1681
|
-
wireframe: true
|
1682
|
-
}));
|
1683
|
-
};
|
1684
|
-
|
1685
|
-
const Debug = /*#__PURE__*/React.memo(() => {
|
1686
|
-
const {
|
1687
|
-
world,
|
1688
|
-
attractorStates
|
1689
|
-
} = useRapier();
|
1690
|
-
const ref = React.useRef(null);
|
1691
|
-
const [attractors, setAttractors] = React.useState([]);
|
1692
|
-
const currMap = React.useRef(new Map());
|
1693
|
-
fiber.useFrame(() => {
|
1694
|
-
const mesh = ref.current;
|
1695
|
-
if (!mesh) return;
|
1696
|
-
const buffers = world.debugRender();
|
1697
|
-
mesh.geometry.setAttribute("position", new three.BufferAttribute(buffers.vertices, 3));
|
1698
|
-
mesh.geometry.setAttribute("color", new three.BufferAttribute(buffers.colors, 4)); // Update attractors
|
1699
|
-
|
1700
|
-
if (!mapsEqual(currMap.current, attractorStates)) {
|
1701
|
-
setAttractors([...attractorStates.values()]);
|
1702
|
-
currMap.current = new Map(attractorStates);
|
1703
|
-
}
|
1704
|
-
});
|
1705
|
-
return /*#__PURE__*/React__default["default"].createElement("group", null, /*#__PURE__*/React__default["default"].createElement("lineSegments", {
|
1706
|
-
ref: ref,
|
1707
|
-
frustumCulled: false
|
1708
|
-
}, /*#__PURE__*/React__default["default"].createElement("lineBasicMaterial", {
|
1709
|
-
color: 0xffffff,
|
1710
|
-
vertexColors: true
|
1711
|
-
}), /*#__PURE__*/React__default["default"].createElement("bufferGeometry", null)), attractors.map((attractor, i) => /*#__PURE__*/React__default["default"].createElement(AttractorHelper, _extends({
|
1712
|
-
key: attractor.object.uuid
|
1713
|
-
}, attractor))));
|
1714
|
-
});
|
1715
|
-
|
1716
1556
|
const _excluded = ["children", "instances", "colliderNodes", "position", "rotation", "quaternion", "scale"];
|
1717
1557
|
const InstancedRigidBodies = /*#__PURE__*/React.memo( /*#__PURE__*/React.forwardRef((props, ref) => {
|
1718
1558
|
const object = React.useRef(null);
|
@@ -1941,14 +1781,12 @@ Object.defineProperty(exports, 'RapierRigidBody', {
|
|
1941
1781
|
get: function () { return rapier3dCompat.RigidBody; }
|
1942
1782
|
});
|
1943
1783
|
exports.AnyCollider = AnyCollider;
|
1944
|
-
exports.Attractor = Attractor;
|
1945
1784
|
exports.BallCollider = BallCollider;
|
1946
1785
|
exports.CapsuleCollider = CapsuleCollider;
|
1947
1786
|
exports.ConeCollider = ConeCollider;
|
1948
1787
|
exports.ConvexHullCollider = ConvexHullCollider;
|
1949
1788
|
exports.CuboidCollider = CuboidCollider;
|
1950
1789
|
exports.CylinderCollider = CylinderCollider;
|
1951
|
-
exports.Debug = Debug;
|
1952
1790
|
exports.HeightfieldCollider = HeightfieldCollider;
|
1953
1791
|
exports.InstancedRigidBodies = InstancedRigidBodies;
|
1954
1792
|
exports.MeshCollider = MeshCollider;
|