@react-three/rapier 0.7.1 → 0.7.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.
@@ -63,11 +63,13 @@ interface RapierWorldProps {
|
|
63
63
|
/**
|
64
64
|
* Set the timestep for the simulation.
|
65
65
|
* Setting this to a number (eg. 1/60) will run the
|
66
|
-
* simulation at that framerate.
|
66
|
+
* simulation at that framerate. Alternatively, you can set this to
|
67
|
+
* "vary", which will cause the simulation to always synchronize with
|
68
|
+
* the current frame delta times.
|
67
69
|
*
|
68
70
|
* @defaultValue 1/60
|
69
71
|
*/
|
70
|
-
timeStep?: number;
|
72
|
+
timeStep?: number | "vary";
|
71
73
|
/**
|
72
74
|
* Pause the physics simulation
|
73
75
|
*
|
@@ -118,11 +118,11 @@ export interface UseColliderOptions<ColliderArgs extends Array<unknown>> {
|
|
118
118
|
/**
|
119
119
|
* The position of this collider relative to the rigid body
|
120
120
|
*/
|
121
|
-
position?:
|
121
|
+
position?: Object3DProps['position'];
|
122
122
|
/**
|
123
123
|
* The rotation of this collider relative to the rigid body
|
124
124
|
*/
|
125
|
-
rotation?:
|
125
|
+
rotation?: Object3DProps['rotation'];
|
126
126
|
/**
|
127
127
|
* The rotation, as a Quaternion, of this collider relative to the rigid body
|
128
128
|
*/
|
@@ -219,11 +219,11 @@ export interface UseRigidBodyOptions extends ColliderProps {
|
|
219
219
|
/**
|
220
220
|
* Initial position of the RigidBody
|
221
221
|
*/
|
222
|
-
position?:
|
222
|
+
position?: Object3DProps['position'];
|
223
223
|
/**
|
224
224
|
* Initial rotation of the RigidBody
|
225
225
|
*/
|
226
|
-
rotation?:
|
226
|
+
rotation?: Object3DProps['rotation'];
|
227
227
|
/**
|
228
228
|
* Automatically generate colliders based on meshes inside this
|
229
229
|
* rigid body.
|
@@ -267,27 +267,38 @@ const Physics = ({
|
|
267
267
|
const [steppingState] = React.useState({
|
268
268
|
accumulator: 0
|
269
269
|
});
|
270
|
+
/* Check if the timestep is supposed to be variable. We'll do this here
|
271
|
+
once so we don't have to string-check every frame. */
|
272
|
+
|
273
|
+
const timeStepVariable = _timeStep === "vary";
|
270
274
|
fiber.useFrame((_, dt) => {
|
271
275
|
const world = worldRef.current;
|
272
276
|
if (!world) return;
|
273
|
-
world.timestep = _timeStep;
|
274
277
|
/**
|
275
278
|
* Fixed timeStep simulation progression
|
276
279
|
* @see https://gafferongames.com/post/fix_your_timestep/
|
277
280
|
*/
|
278
|
-
// don't step time forwards if paused
|
279
|
-
// Increase accumulator
|
280
281
|
|
281
|
-
|
282
|
+
const clampedDelta = MathUtils.clamp(dt, 0, 0.2);
|
283
|
+
|
284
|
+
if (timeStepVariable) {
|
285
|
+
world.timestep = clampedDelta;
|
286
|
+
if (!_paused) world.step(eventQueue);
|
287
|
+
} else {
|
288
|
+
world.timestep = _timeStep; // don't step time forwards if paused
|
289
|
+
// Increase accumulator
|
290
|
+
|
291
|
+
steppingState.accumulator += _paused ? 0 : clampedDelta;
|
282
292
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
293
|
+
if (!_paused) {
|
294
|
+
while (steppingState.accumulator >= _timeStep) {
|
295
|
+
world.step(eventQueue);
|
296
|
+
steppingState.accumulator -= _timeStep;
|
297
|
+
}
|
287
298
|
}
|
288
299
|
}
|
289
300
|
|
290
|
-
const interpolationAlpha = steppingState.accumulator % _timeStep / _timeStep; // Update meshes
|
301
|
+
const interpolationAlpha = timeStepVariable ? 1 : steppingState.accumulator % _timeStep / _timeStep; // Update meshes
|
291
302
|
|
292
303
|
rigidBodyStates.forEach((state, handle) => {
|
293
304
|
const rigidBody = world.getRigidBody(handle);
|
@@ -947,7 +958,7 @@ const useChildColliderProps = (ref, options, ignoreMeshColliders = true) => {
|
|
947
958
|
ignoreMeshColliders
|
948
959
|
}));
|
949
960
|
}
|
950
|
-
}, [options]);
|
961
|
+
}, [options.colliders]);
|
951
962
|
return colliderProps;
|
952
963
|
};
|
953
964
|
const useRigidBody = (options = {}) => {
|
@@ -1209,12 +1220,13 @@ const RigidBody = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1209
1220
|
|
1210
1221
|
const [object, api, childColliderProps] = useRigidBody(props);
|
1211
1222
|
React.useImperativeHandle(ref, () => api);
|
1223
|
+
const contextValue = React.useMemo(() => ({
|
1224
|
+
ref: object,
|
1225
|
+
api,
|
1226
|
+
options: props
|
1227
|
+
}), [object, api, props]);
|
1212
1228
|
return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
|
1213
|
-
value:
|
1214
|
-
ref: object,
|
1215
|
-
api,
|
1216
|
-
options: props
|
1217
|
-
}
|
1229
|
+
value: contextValue
|
1218
1230
|
}, /*#__PURE__*/React__default["default"].createElement("object3D", _extends({
|
1219
1231
|
ref: object
|
1220
1232
|
}, objectProps, {
|
@@ -1449,6 +1461,7 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1449
1461
|
options = _objectWithoutProperties(props, _excluded);
|
1450
1462
|
|
1451
1463
|
const instancesRef = React.useRef([]);
|
1464
|
+
const rigidBodyRefs = React.useRef([]);
|
1452
1465
|
const instancesRefGetter = React.useRef(() => {
|
1453
1466
|
if (!instancesRef.current) {
|
1454
1467
|
instancesRef.current = [];
|
@@ -1462,7 +1475,7 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1462
1475
|
const childColliderProps = useChildColliderProps(object, mergedOptions);
|
1463
1476
|
React.useLayoutEffect(() => {
|
1464
1477
|
object.current.updateWorldMatrix(true, false);
|
1465
|
-
const
|
1478
|
+
const instances = instancesRefGetter.current();
|
1466
1479
|
const invertedWorld = object.current.matrixWorld.clone().invert();
|
1467
1480
|
object.current.traverseVisible(mesh => {
|
1468
1481
|
if (mesh instanceof three.InstancedMesh) {
|
@@ -1474,6 +1487,7 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1474
1487
|
|
1475
1488
|
const desc = rigidBodyDescFromOptions(props);
|
1476
1489
|
const rigidBody = world.createRigidBody(desc);
|
1490
|
+
rigidBodyRefs.current.push(rigidBody);
|
1477
1491
|
const scale = ((_options$scales = options.scales) === null || _options$scales === void 0 ? void 0 : _options$scales[index]) || [1, 1, 1];
|
1478
1492
|
const instanceScale = worldScale.clone().multiply(vectorArrayToVector3(scale));
|
1479
1493
|
rigidBodyStates.set(rigidBody.handle, createRigidBodyState({
|
@@ -1504,7 +1518,7 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1504
1518
|
}
|
1505
1519
|
|
1506
1520
|
});
|
1507
|
-
|
1521
|
+
instances.push({
|
1508
1522
|
rigidBody,
|
1509
1523
|
api
|
1510
1524
|
});
|
@@ -1512,31 +1526,27 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1512
1526
|
}
|
1513
1527
|
});
|
1514
1528
|
return () => {
|
1515
|
-
|
1529
|
+
instances.forEach(rb => {
|
1516
1530
|
world.removeRigidBody(rb.rigidBody);
|
1517
1531
|
rigidBodyStates.delete(rb.rigidBody.handle);
|
1518
1532
|
});
|
1533
|
+
rigidBodyRefs.current = [];
|
1519
1534
|
instancesRef.current = [];
|
1520
1535
|
};
|
1521
1536
|
}, []);
|
1522
1537
|
const api = React.useMemo(() => createInstancedRigidBodiesApi(instancesRefGetter), []);
|
1523
1538
|
React.useImperativeHandle(ref, () => api);
|
1524
|
-
useUpdateRigidBodyOptions(
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
}, mergedOptions, rigidBodyStates, false);
|
1529
|
-
useRigidBodyEvents({
|
1530
|
-
current: instancesRef.current.map(({
|
1531
|
-
rigidBody
|
1532
|
-
}) => rigidBody)
|
1533
|
-
}, mergedOptions, rigidBodyEvents);
|
1534
|
-
return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
|
1535
|
-
value: {
|
1539
|
+
useUpdateRigidBodyOptions(rigidBodyRefs, mergedOptions, rigidBodyStates, false);
|
1540
|
+
useRigidBodyEvents(rigidBodyRefs, mergedOptions, rigidBodyEvents);
|
1541
|
+
const contextValue = React.useMemo(() => {
|
1542
|
+
return {
|
1536
1543
|
ref: object,
|
1537
1544
|
api,
|
1538
|
-
options:
|
1539
|
-
}
|
1545
|
+
options: mergedOptions
|
1546
|
+
};
|
1547
|
+
}, [api, mergedOptions]);
|
1548
|
+
return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
|
1549
|
+
value: contextValue
|
1540
1550
|
}, /*#__PURE__*/React__default["default"].createElement("object3D", {
|
1541
1551
|
ref: object
|
1542
1552
|
}, props.children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({
|
@@ -267,27 +267,38 @@ const Physics = ({
|
|
267
267
|
const [steppingState] = React.useState({
|
268
268
|
accumulator: 0
|
269
269
|
});
|
270
|
+
/* Check if the timestep is supposed to be variable. We'll do this here
|
271
|
+
once so we don't have to string-check every frame. */
|
272
|
+
|
273
|
+
const timeStepVariable = _timeStep === "vary";
|
270
274
|
fiber.useFrame((_, dt) => {
|
271
275
|
const world = worldRef.current;
|
272
276
|
if (!world) return;
|
273
|
-
world.timestep = _timeStep;
|
274
277
|
/**
|
275
278
|
* Fixed timeStep simulation progression
|
276
279
|
* @see https://gafferongames.com/post/fix_your_timestep/
|
277
280
|
*/
|
278
|
-
// don't step time forwards if paused
|
279
|
-
// Increase accumulator
|
280
281
|
|
281
|
-
|
282
|
+
const clampedDelta = MathUtils.clamp(dt, 0, 0.2);
|
283
|
+
|
284
|
+
if (timeStepVariable) {
|
285
|
+
world.timestep = clampedDelta;
|
286
|
+
if (!_paused) world.step(eventQueue);
|
287
|
+
} else {
|
288
|
+
world.timestep = _timeStep; // don't step time forwards if paused
|
289
|
+
// Increase accumulator
|
290
|
+
|
291
|
+
steppingState.accumulator += _paused ? 0 : clampedDelta;
|
282
292
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
293
|
+
if (!_paused) {
|
294
|
+
while (steppingState.accumulator >= _timeStep) {
|
295
|
+
world.step(eventQueue);
|
296
|
+
steppingState.accumulator -= _timeStep;
|
297
|
+
}
|
287
298
|
}
|
288
299
|
}
|
289
300
|
|
290
|
-
const interpolationAlpha = steppingState.accumulator % _timeStep / _timeStep; // Update meshes
|
301
|
+
const interpolationAlpha = timeStepVariable ? 1 : steppingState.accumulator % _timeStep / _timeStep; // Update meshes
|
291
302
|
|
292
303
|
rigidBodyStates.forEach((state, handle) => {
|
293
304
|
const rigidBody = world.getRigidBody(handle);
|
@@ -947,7 +958,7 @@ const useChildColliderProps = (ref, options, ignoreMeshColliders = true) => {
|
|
947
958
|
ignoreMeshColliders
|
948
959
|
}));
|
949
960
|
}
|
950
|
-
}, [options]);
|
961
|
+
}, [options.colliders]);
|
951
962
|
return colliderProps;
|
952
963
|
};
|
953
964
|
const useRigidBody = (options = {}) => {
|
@@ -1209,12 +1220,13 @@ const RigidBody = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1209
1220
|
|
1210
1221
|
const [object, api, childColliderProps] = useRigidBody(props);
|
1211
1222
|
React.useImperativeHandle(ref, () => api);
|
1223
|
+
const contextValue = React.useMemo(() => ({
|
1224
|
+
ref: object,
|
1225
|
+
api,
|
1226
|
+
options: props
|
1227
|
+
}), [object, api, props]);
|
1212
1228
|
return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
|
1213
|
-
value:
|
1214
|
-
ref: object,
|
1215
|
-
api,
|
1216
|
-
options: props
|
1217
|
-
}
|
1229
|
+
value: contextValue
|
1218
1230
|
}, /*#__PURE__*/React__default["default"].createElement("object3D", _extends({
|
1219
1231
|
ref: object
|
1220
1232
|
}, objectProps, {
|
@@ -1449,6 +1461,7 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1449
1461
|
options = _objectWithoutProperties(props, _excluded);
|
1450
1462
|
|
1451
1463
|
const instancesRef = React.useRef([]);
|
1464
|
+
const rigidBodyRefs = React.useRef([]);
|
1452
1465
|
const instancesRefGetter = React.useRef(() => {
|
1453
1466
|
if (!instancesRef.current) {
|
1454
1467
|
instancesRef.current = [];
|
@@ -1462,7 +1475,7 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1462
1475
|
const childColliderProps = useChildColliderProps(object, mergedOptions);
|
1463
1476
|
React.useLayoutEffect(() => {
|
1464
1477
|
object.current.updateWorldMatrix(true, false);
|
1465
|
-
const
|
1478
|
+
const instances = instancesRefGetter.current();
|
1466
1479
|
const invertedWorld = object.current.matrixWorld.clone().invert();
|
1467
1480
|
object.current.traverseVisible(mesh => {
|
1468
1481
|
if (mesh instanceof three.InstancedMesh) {
|
@@ -1474,6 +1487,7 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1474
1487
|
|
1475
1488
|
const desc = rigidBodyDescFromOptions(props);
|
1476
1489
|
const rigidBody = world.createRigidBody(desc);
|
1490
|
+
rigidBodyRefs.current.push(rigidBody);
|
1477
1491
|
const scale = ((_options$scales = options.scales) === null || _options$scales === void 0 ? void 0 : _options$scales[index]) || [1, 1, 1];
|
1478
1492
|
const instanceScale = worldScale.clone().multiply(vectorArrayToVector3(scale));
|
1479
1493
|
rigidBodyStates.set(rigidBody.handle, createRigidBodyState({
|
@@ -1504,7 +1518,7 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1504
1518
|
}
|
1505
1519
|
|
1506
1520
|
});
|
1507
|
-
|
1521
|
+
instances.push({
|
1508
1522
|
rigidBody,
|
1509
1523
|
api
|
1510
1524
|
});
|
@@ -1512,31 +1526,27 @@ const InstancedRigidBodies = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1512
1526
|
}
|
1513
1527
|
});
|
1514
1528
|
return () => {
|
1515
|
-
|
1529
|
+
instances.forEach(rb => {
|
1516
1530
|
world.removeRigidBody(rb.rigidBody);
|
1517
1531
|
rigidBodyStates.delete(rb.rigidBody.handle);
|
1518
1532
|
});
|
1533
|
+
rigidBodyRefs.current = [];
|
1519
1534
|
instancesRef.current = [];
|
1520
1535
|
};
|
1521
1536
|
}, []);
|
1522
1537
|
const api = React.useMemo(() => createInstancedRigidBodiesApi(instancesRefGetter), []);
|
1523
1538
|
React.useImperativeHandle(ref, () => api);
|
1524
|
-
useUpdateRigidBodyOptions(
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
}, mergedOptions, rigidBodyStates, false);
|
1529
|
-
useRigidBodyEvents({
|
1530
|
-
current: instancesRef.current.map(({
|
1531
|
-
rigidBody
|
1532
|
-
}) => rigidBody)
|
1533
|
-
}, mergedOptions, rigidBodyEvents);
|
1534
|
-
return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
|
1535
|
-
value: {
|
1539
|
+
useUpdateRigidBodyOptions(rigidBodyRefs, mergedOptions, rigidBodyStates, false);
|
1540
|
+
useRigidBodyEvents(rigidBodyRefs, mergedOptions, rigidBodyEvents);
|
1541
|
+
const contextValue = React.useMemo(() => {
|
1542
|
+
return {
|
1536
1543
|
ref: object,
|
1537
1544
|
api,
|
1538
|
-
options:
|
1539
|
-
}
|
1545
|
+
options: mergedOptions
|
1546
|
+
};
|
1547
|
+
}, [api, mergedOptions]);
|
1548
|
+
return /*#__PURE__*/React__default["default"].createElement(RigidBodyContext.Provider, {
|
1549
|
+
value: contextValue
|
1540
1550
|
}, /*#__PURE__*/React__default["default"].createElement("object3D", {
|
1541
1551
|
ref: object
|
1542
1552
|
}, props.children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React__default["default"].createElement(AnyCollider, _extends({
|
@@ -242,27 +242,38 @@ const Physics = ({
|
|
242
242
|
const [steppingState] = useState({
|
243
243
|
accumulator: 0
|
244
244
|
});
|
245
|
+
/* Check if the timestep is supposed to be variable. We'll do this here
|
246
|
+
once so we don't have to string-check every frame. */
|
247
|
+
|
248
|
+
const timeStepVariable = _timeStep === "vary";
|
245
249
|
useFrame((_, dt) => {
|
246
250
|
const world = worldRef.current;
|
247
251
|
if (!world) return;
|
248
|
-
world.timestep = _timeStep;
|
249
252
|
/**
|
250
253
|
* Fixed timeStep simulation progression
|
251
254
|
* @see https://gafferongames.com/post/fix_your_timestep/
|
252
255
|
*/
|
253
|
-
// don't step time forwards if paused
|
254
|
-
// Increase accumulator
|
255
256
|
|
256
|
-
|
257
|
+
const clampedDelta = clamp(dt, 0, 0.2);
|
258
|
+
|
259
|
+
if (timeStepVariable) {
|
260
|
+
world.timestep = clampedDelta;
|
261
|
+
if (!_paused) world.step(eventQueue);
|
262
|
+
} else {
|
263
|
+
world.timestep = _timeStep; // don't step time forwards if paused
|
264
|
+
// Increase accumulator
|
265
|
+
|
266
|
+
steppingState.accumulator += _paused ? 0 : clampedDelta;
|
257
267
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
268
|
+
if (!_paused) {
|
269
|
+
while (steppingState.accumulator >= _timeStep) {
|
270
|
+
world.step(eventQueue);
|
271
|
+
steppingState.accumulator -= _timeStep;
|
272
|
+
}
|
262
273
|
}
|
263
274
|
}
|
264
275
|
|
265
|
-
const interpolationAlpha = steppingState.accumulator % _timeStep / _timeStep; // Update meshes
|
276
|
+
const interpolationAlpha = timeStepVariable ? 1 : steppingState.accumulator % _timeStep / _timeStep; // Update meshes
|
266
277
|
|
267
278
|
rigidBodyStates.forEach((state, handle) => {
|
268
279
|
const rigidBody = world.getRigidBody(handle);
|
@@ -922,7 +933,7 @@ const useChildColliderProps = (ref, options, ignoreMeshColliders = true) => {
|
|
922
933
|
ignoreMeshColliders
|
923
934
|
}));
|
924
935
|
}
|
925
|
-
}, [options]);
|
936
|
+
}, [options.colliders]);
|
926
937
|
return colliderProps;
|
927
938
|
};
|
928
939
|
const useRigidBody = (options = {}) => {
|
@@ -1184,12 +1195,13 @@ const RigidBody = /*#__PURE__*/forwardRef((props, ref) => {
|
|
1184
1195
|
|
1185
1196
|
const [object, api, childColliderProps] = useRigidBody(props);
|
1186
1197
|
useImperativeHandle(ref, () => api);
|
1198
|
+
const contextValue = useMemo(() => ({
|
1199
|
+
ref: object,
|
1200
|
+
api,
|
1201
|
+
options: props
|
1202
|
+
}), [object, api, props]);
|
1187
1203
|
return /*#__PURE__*/React.createElement(RigidBodyContext.Provider, {
|
1188
|
-
value:
|
1189
|
-
ref: object,
|
1190
|
-
api,
|
1191
|
-
options: props
|
1192
|
-
}
|
1204
|
+
value: contextValue
|
1193
1205
|
}, /*#__PURE__*/React.createElement("object3D", _extends({
|
1194
1206
|
ref: object
|
1195
1207
|
}, objectProps, {
|
@@ -1424,6 +1436,7 @@ const InstancedRigidBodies = /*#__PURE__*/forwardRef((props, ref) => {
|
|
1424
1436
|
options = _objectWithoutProperties(props, _excluded);
|
1425
1437
|
|
1426
1438
|
const instancesRef = useRef([]);
|
1439
|
+
const rigidBodyRefs = useRef([]);
|
1427
1440
|
const instancesRefGetter = useRef(() => {
|
1428
1441
|
if (!instancesRef.current) {
|
1429
1442
|
instancesRef.current = [];
|
@@ -1437,7 +1450,7 @@ const InstancedRigidBodies = /*#__PURE__*/forwardRef((props, ref) => {
|
|
1437
1450
|
const childColliderProps = useChildColliderProps(object, mergedOptions);
|
1438
1451
|
useLayoutEffect(() => {
|
1439
1452
|
object.current.updateWorldMatrix(true, false);
|
1440
|
-
const
|
1453
|
+
const instances = instancesRefGetter.current();
|
1441
1454
|
const invertedWorld = object.current.matrixWorld.clone().invert();
|
1442
1455
|
object.current.traverseVisible(mesh => {
|
1443
1456
|
if (mesh instanceof InstancedMesh) {
|
@@ -1449,6 +1462,7 @@ const InstancedRigidBodies = /*#__PURE__*/forwardRef((props, ref) => {
|
|
1449
1462
|
|
1450
1463
|
const desc = rigidBodyDescFromOptions(props);
|
1451
1464
|
const rigidBody = world.createRigidBody(desc);
|
1465
|
+
rigidBodyRefs.current.push(rigidBody);
|
1452
1466
|
const scale = ((_options$scales = options.scales) === null || _options$scales === void 0 ? void 0 : _options$scales[index]) || [1, 1, 1];
|
1453
1467
|
const instanceScale = worldScale.clone().multiply(vectorArrayToVector3(scale));
|
1454
1468
|
rigidBodyStates.set(rigidBody.handle, createRigidBodyState({
|
@@ -1479,7 +1493,7 @@ const InstancedRigidBodies = /*#__PURE__*/forwardRef((props, ref) => {
|
|
1479
1493
|
}
|
1480
1494
|
|
1481
1495
|
});
|
1482
|
-
|
1496
|
+
instances.push({
|
1483
1497
|
rigidBody,
|
1484
1498
|
api
|
1485
1499
|
});
|
@@ -1487,31 +1501,27 @@ const InstancedRigidBodies = /*#__PURE__*/forwardRef((props, ref) => {
|
|
1487
1501
|
}
|
1488
1502
|
});
|
1489
1503
|
return () => {
|
1490
|
-
|
1504
|
+
instances.forEach(rb => {
|
1491
1505
|
world.removeRigidBody(rb.rigidBody);
|
1492
1506
|
rigidBodyStates.delete(rb.rigidBody.handle);
|
1493
1507
|
});
|
1508
|
+
rigidBodyRefs.current = [];
|
1494
1509
|
instancesRef.current = [];
|
1495
1510
|
};
|
1496
1511
|
}, []);
|
1497
1512
|
const api = useMemo(() => createInstancedRigidBodiesApi(instancesRefGetter), []);
|
1498
1513
|
useImperativeHandle(ref, () => api);
|
1499
|
-
useUpdateRigidBodyOptions(
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
}, mergedOptions, rigidBodyStates, false);
|
1504
|
-
useRigidBodyEvents({
|
1505
|
-
current: instancesRef.current.map(({
|
1506
|
-
rigidBody
|
1507
|
-
}) => rigidBody)
|
1508
|
-
}, mergedOptions, rigidBodyEvents);
|
1509
|
-
return /*#__PURE__*/React.createElement(RigidBodyContext.Provider, {
|
1510
|
-
value: {
|
1514
|
+
useUpdateRigidBodyOptions(rigidBodyRefs, mergedOptions, rigidBodyStates, false);
|
1515
|
+
useRigidBodyEvents(rigidBodyRefs, mergedOptions, rigidBodyEvents);
|
1516
|
+
const contextValue = useMemo(() => {
|
1517
|
+
return {
|
1511
1518
|
ref: object,
|
1512
1519
|
api,
|
1513
|
-
options:
|
1514
|
-
}
|
1520
|
+
options: mergedOptions
|
1521
|
+
};
|
1522
|
+
}, [api, mergedOptions]);
|
1523
|
+
return /*#__PURE__*/React.createElement(RigidBodyContext.Provider, {
|
1524
|
+
value: contextValue
|
1515
1525
|
}, /*#__PURE__*/React.createElement("object3D", {
|
1516
1526
|
ref: object
|
1517
1527
|
}, props.children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React.createElement(AnyCollider, _extends({
|
package/package.json
CHANGED
package/readme.md
CHANGED
@@ -309,6 +309,22 @@ A Collider can be set to be a sensor, which means that it will not generate any
|
|
309
309
|
|
310
310
|
WIP
|
311
311
|
|
312
|
+
## Configuring Time Step Size
|
313
|
+
|
314
|
+
By default, `<Physics>` will simulate the physics world at a fixed rate of 60 frames per second. This can be changed by setting the `timeStep` prop on `<Physics>`:
|
315
|
+
|
316
|
+
```tsx
|
317
|
+
<Physics timeStep={1 / 30}>{/* ... */}</Physics>
|
318
|
+
```
|
319
|
+
|
320
|
+
The `timeStep` prop may also be set to `"vary"`, which will cause the simulation's time step to adjust to every frame's frame delta:
|
321
|
+
|
322
|
+
```tsx
|
323
|
+
<Physics timeStep="vary">{/* ... */}</Physics>
|
324
|
+
```
|
325
|
+
|
326
|
+
> **Note** This is useful for games that run at variable frame rates, but may cause instability in the simulation. It also prevents the physics simulation from being fully deterministic. Please use with care!
|
327
|
+
|
312
328
|
---
|
313
329
|
|
314
330
|
## Roadmap
|
@@ -326,6 +342,6 @@ In order, but also not necessarily:
|
|
326
342
|
- [x] InstancedMesh support
|
327
343
|
- [x] Timestep improvements for determinism
|
328
344
|
- [x] Normalize and improve collision events (add events to single Colliders)
|
329
|
-
- [
|
345
|
+
- [x] Add collision events to InstancedRigidBodies
|
330
346
|
- [ ] Docs
|
331
347
|
- [ ] CodeSandbox examples
|