@react-three/rapier 0.14.0-rc.0 → 0.14.0-rc.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.
@@ -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
- import { useThree, useFrame } from '@react-three/fiber';
4
- import React, { useRef, useEffect, useMemo, useContext, useState, memo, createContext, useCallback, forwardRef, useImperativeHandle, Fragment } from 'react';
3
+ import { useFrame, useThree } from '@react-three/fiber';
4
+ import React$1, { useRef, useMemo, useEffect, useContext, useState, memo, createContext, useCallback, forwardRef, useImperativeHandle, Fragment } from 'react';
5
5
  import { Quaternion, Euler, Vector3, Object3D, Matrix4, MathUtils, BufferAttribute, DynamicDrawUsage } from 'three';
6
6
  import { useAsset } from 'use-asset';
7
7
  import { mergeVertices, VertexNormalsHelper } from 'three-stdlib';
@@ -153,27 +153,41 @@ function useConst(initialValue) {
153
153
  return ref.current.value;
154
154
  }
155
155
 
156
- const useRaf = callback => {
157
- const cb = useRef(callback);
158
- const raf = useRef(0);
159
- const lastFrame = useRef(0);
160
- useEffect(() => {
161
- cb.current = callback;
162
- }, [callback]);
163
- useEffect(() => {
164
- const loop = () => {
165
- const now = performance.now();
166
- const delta = now - lastFrame.current;
167
- raf.current = requestAnimationFrame(loop);
168
- cb.current(delta / 1000);
169
- lastFrame.current = now;
170
- };
156
+ function _objectWithoutPropertiesLoose(source, excluded) {
157
+ if (source == null) return {};
158
+ var target = {};
159
+ var sourceKeys = Object.keys(source);
160
+ var key, i;
171
161
 
172
- raf.current = requestAnimationFrame(loop);
173
- return () => cancelAnimationFrame(raf.current);
174
- }, []);
175
- };
162
+ for (i = 0; i < sourceKeys.length; i++) {
163
+ key = sourceKeys[i];
164
+ if (excluded.indexOf(key) >= 0) continue;
165
+ target[key] = source[key];
166
+ }
167
+
168
+ return target;
169
+ }
170
+
171
+ function _objectWithoutProperties(source, excluded) {
172
+ if (source == null) return {};
173
+ var target = _objectWithoutPropertiesLoose(source, excluded);
174
+ var key, i;
175
+
176
+ if (Object.getOwnPropertySymbols) {
177
+ var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
178
+
179
+ for (i = 0; i < sourceSymbolKeys.length; i++) {
180
+ key = sourceSymbolKeys[i];
181
+ if (excluded.indexOf(key) >= 0) continue;
182
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
183
+ target[key] = source[key];
184
+ }
185
+ }
176
186
 
187
+ return target;
188
+ }
189
+
190
+ const _excluded$2 = ["mass", "linearDamping", "angularDamping", "type", "onCollisionEnter", "onCollisionExit", "onIntersectionEnter", "onIntersectionExit", "onContactForce", "children", "canSleep", "ccd", "gravityScale"];
177
191
  const scaleColliderArgs = (shape, args, scale) => {
178
192
  const newArgs = args.slice(); // Heightfield uses a vector
179
193
 
@@ -340,7 +354,7 @@ const createColliderPropsFromChildren = ({
340
354
  ignoreMeshColliders: _ignoreMeshColliders = true,
341
355
  options
342
356
  }) => {
343
- const colliderProps = [];
357
+ const childColliderProps = [];
344
358
  object.updateWorldMatrix(true, false);
345
359
  const invertedParentMatrixWorld = object.matrixWorld.clone().invert();
346
360
 
@@ -361,13 +375,16 @@ const createColliderPropsFromChildren = ({
361
375
  args,
362
376
  offset
363
377
  } = getColliderArgsFromGeometry(geometry, options.colliders || "cuboid");
364
- colliderProps.push(_objectSpread2(_objectSpread2({}, options), {}, {
378
+
379
+ const colliderProps = _objectSpread2(_objectSpread2({}, cleanRigidBodyPropsForCollider(options)), {}, {
365
380
  args: args,
366
381
  shape: shape,
367
382
  rotation: [rotationEuler.x, rotationEuler.y, rotationEuler.z],
368
383
  position: [_position.x + offset.x * worldScale.x, _position.y + offset.y * worldScale.y, _position.z + offset.z * worldScale.z],
369
384
  scale: [worldScale.x, worldScale.y, worldScale.z]
370
- }));
385
+ });
386
+
387
+ childColliderProps.push(colliderProps);
371
388
  }
372
389
  };
373
390
 
@@ -377,7 +394,7 @@ const createColliderPropsFromChildren = ({
377
394
  object.traverseVisible(colliderFromChild);
378
395
  }
379
396
 
380
- return colliderProps;
397
+ return childColliderProps;
381
398
  };
382
399
  const getColliderArgsFromGeometry = (geometry, colliders) => {
383
400
  switch (colliders) {
@@ -433,7 +450,17 @@ const getColliderArgsFromGeometry = (geometry, colliders) => {
433
450
  offset: new Vector3()
434
451
  };
435
452
  };
436
- const useColliderEvents = (getCollider, props, events) => {
453
+ const getActiveCollisionEventsFromProps = props => {
454
+ return {
455
+ collision: !!(props !== null && props !== void 0 && props.onCollisionEnter || props !== null && props !== void 0 && props.onCollisionExit || props !== null && props !== void 0 && props.onIntersectionEnter || props !== null && props !== void 0 && props.onIntersectionExit),
456
+ contactForce: !!(props !== null && props !== void 0 && props.onContactForce)
457
+ };
458
+ };
459
+ const useColliderEvents = (getCollider, props, events,
460
+ /**
461
+ * The RigidBody can pass down active events to the collider without attaching the event listners
462
+ */
463
+ activeEvents = {}) => {
437
464
  const {
438
465
  onCollisionEnter,
439
466
  onCollisionExit,
@@ -445,8 +472,12 @@ const useColliderEvents = (getCollider, props, events) => {
445
472
  const collider = getCollider();
446
473
 
447
474
  if (collider) {
448
- const hasCollisionEvent = !!(onCollisionEnter || onCollisionExit || onIntersectionEnter || onIntersectionExit);
449
- const hasContactForceEvent = !!onContactForce;
475
+ const {
476
+ collision: collisionEventsActive,
477
+ contactForce: contactForceEventsActive
478
+ } = getActiveCollisionEventsFromProps(props);
479
+ const hasCollisionEvent = collisionEventsActive || activeEvents.collision;
480
+ const hasContactForceEvent = contactForceEventsActive || activeEvents.contactForce;
450
481
 
451
482
  if (hasCollisionEvent && hasContactForceEvent) {
452
483
  collider.setActiveEvents(ActiveEvents.COLLISION_EVENTS | ActiveEvents.CONTACT_FORCE_EVENTS);
@@ -470,7 +501,12 @@ const useColliderEvents = (getCollider, props, events) => {
470
501
  events.delete(collider.handle);
471
502
  }
472
503
  };
473
- }, [onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit, onContactForce]);
504
+ }, [onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit, onContactForce, activeEvents]);
505
+ };
506
+ const cleanRigidBodyPropsForCollider = (props = {}) => {
507
+ const rest = _objectWithoutProperties(props, _excluded$2);
508
+
509
+ return rest;
474
510
  };
475
511
 
476
512
  const useMutableCallback = fn => {
@@ -624,12 +660,67 @@ const Attractor = /*#__PURE__*/memo(props => {
624
660
  attractorStates.delete(uuid);
625
661
  };
626
662
  }, [props]);
627
- return /*#__PURE__*/React.createElement("object3D", {
663
+ return /*#__PURE__*/React$1.createElement("object3D", {
628
664
  ref: object,
629
665
  position: position
630
666
  });
631
667
  });
632
668
 
669
+ const useRaf = callback => {
670
+ const cb = useRef(callback);
671
+ const raf = useRef(0);
672
+ const lastFrame = useRef(0);
673
+ useEffect(() => {
674
+ cb.current = callback;
675
+ }, [callback]);
676
+ useEffect(() => {
677
+ const loop = () => {
678
+ const now = performance.now();
679
+ const delta = now - lastFrame.current;
680
+ raf.current = requestAnimationFrame(loop);
681
+ cb.current(delta / 1000);
682
+ lastFrame.current = now;
683
+ };
684
+
685
+ raf.current = requestAnimationFrame(loop);
686
+ return () => cancelAnimationFrame(raf.current);
687
+ }, []);
688
+ };
689
+
690
+ const UseFrameStepper = ({
691
+ onStep,
692
+ updatePriority
693
+ }) => {
694
+ useFrame((_, dt) => {
695
+ onStep(dt);
696
+ }, updatePriority);
697
+ return null;
698
+ };
699
+
700
+ const RafStepper = ({
701
+ onStep
702
+ }) => {
703
+ useRaf(dt => {
704
+ onStep(dt);
705
+ });
706
+ return null;
707
+ };
708
+
709
+ const FrameStepper = ({
710
+ onStep,
711
+ type,
712
+ updatePriority
713
+ }) => {
714
+ return type === "independent" ? /*#__PURE__*/React.createElement(RafStepper, {
715
+ onStep: onStep
716
+ }) : /*#__PURE__*/React.createElement(UseFrameStepper, {
717
+ onStep: onStep,
718
+ updatePriority: updatePriority
719
+ });
720
+ };
721
+
722
+ var FrameStepper$1 = /*#__PURE__*/memo(FrameStepper);
723
+
633
724
  const rapierContext = /*#__PURE__*/createContext(undefined);
634
725
 
635
726
  const getCollisionPayloadFromSource = (target, other) => {
@@ -671,7 +762,9 @@ const Physics = ({
671
762
  children,
672
763
  timeStep: _timeStep = 1 / 60,
673
764
  paused: _paused = false,
674
- interpolate: _interpolate = true
765
+ interpolate: _interpolate = true,
766
+ updatePriority,
767
+ updateLoop: _updateLoop = "follow"
675
768
  }) => {
676
769
  const rapier = useAsset(importRapier);
677
770
  const {
@@ -957,13 +1050,10 @@ const Physics = ({
957
1050
  maxForceMagnitude: event.maxForceMagnitude()
958
1051
  }));
959
1052
  });
960
- world.forEachActiveRigidBody(body => {
1053
+ world.forEachActiveRigidBody(() => {
961
1054
  invalidate();
962
1055
  });
963
1056
  }, [_paused, _timeStep, _interpolate]);
964
- useRaf(dt => {
965
- if (!_paused) step(dt);
966
- });
967
1057
  const context = useMemo(() => ({
968
1058
  rapier,
969
1059
  world: api,
@@ -981,9 +1071,18 @@ const Physics = ({
981
1071
  isPaused: _paused,
982
1072
  step
983
1073
  }), [_paused, step]);
984
- return /*#__PURE__*/React.createElement(rapierContext.Provider, {
1074
+ const stepCallback = useCallback(delta => {
1075
+ if (!_paused) {
1076
+ step(delta);
1077
+ }
1078
+ }, [_paused, step]);
1079
+ return /*#__PURE__*/React$1.createElement(rapierContext.Provider, {
985
1080
  value: context
986
- }, children);
1081
+ }, /*#__PURE__*/React$1.createElement(FrameStepper$1, {
1082
+ onStep: stepCallback,
1083
+ type: _updateLoop,
1084
+ updatePriority: updatePriority
1085
+ }), children);
987
1086
  };
988
1087
 
989
1088
  function _extends() {
@@ -1003,40 +1102,6 @@ function _extends() {
1003
1102
  return _extends.apply(this, arguments);
1004
1103
  }
1005
1104
 
1006
- function _objectWithoutPropertiesLoose(source, excluded) {
1007
- if (source == null) return {};
1008
- var target = {};
1009
- var sourceKeys = Object.keys(source);
1010
- var key, i;
1011
-
1012
- for (i = 0; i < sourceKeys.length; i++) {
1013
- key = sourceKeys[i];
1014
- if (excluded.indexOf(key) >= 0) continue;
1015
- target[key] = source[key];
1016
- }
1017
-
1018
- return target;
1019
- }
1020
-
1021
- function _objectWithoutProperties(source, excluded) {
1022
- if (source == null) return {};
1023
- var target = _objectWithoutPropertiesLoose(source, excluded);
1024
- var key, i;
1025
-
1026
- if (Object.getOwnPropertySymbols) {
1027
- var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
1028
-
1029
- for (i = 0; i < sourceSymbolKeys.length; i++) {
1030
- key = sourceSymbolKeys[i];
1031
- if (excluded.indexOf(key) >= 0) continue;
1032
- if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
1033
- target[key] = source[key];
1034
- }
1035
- }
1036
-
1037
- return target;
1038
- }
1039
-
1040
1105
  /**
1041
1106
  * Initiate an instance and return a safe getter
1042
1107
  */
@@ -1149,11 +1214,11 @@ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwarded
1149
1214
  }, []);
1150
1215
  useImperativeHandle(forwardedRef, () => getInstance());
1151
1216
  const mergedProps = useMemo(() => {
1152
- return _objectSpread2(_objectSpread2({}, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options), props);
1217
+ return _objectSpread2(_objectSpread2({}, cleanRigidBodyPropsForCollider(rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options)), props);
1153
1218
  }, [props, rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options]);
1154
1219
  useUpdateColliderOptions(getInstance, mergedProps, colliderStates);
1155
- useColliderEvents(getInstance, mergedProps, colliderEvents);
1156
- return /*#__PURE__*/React.createElement("object3D", {
1220
+ useColliderEvents(getInstance, mergedProps, colliderEvents, getActiveCollisionEventsFromProps(rigidBodyContext === null || rigidBodyContext === void 0 ? void 0 : rigidBodyContext.options));
1221
+ return /*#__PURE__*/React$1.createElement("object3D", {
1157
1222
  position: position,
1158
1223
  rotation: rotation,
1159
1224
  quaternion: quaternion,
@@ -1167,8 +1232,8 @@ const AnyCollider = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwarded
1167
1232
  * A cuboid collider shape
1168
1233
  * @category Colliders
1169
1234
  */
1170
- const CuboidCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1171
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1235
+ const CuboidCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1236
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1172
1237
  shape: "cuboid",
1173
1238
  ref: ref
1174
1239
  }));
@@ -1178,8 +1243,8 @@ const CuboidCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1178
1243
  * @category Colliders
1179
1244
  */
1180
1245
 
1181
- const RoundCuboidCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1182
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1246
+ const RoundCuboidCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1247
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1183
1248
  shape: "roundCuboid",
1184
1249
  ref: ref
1185
1250
  }));
@@ -1189,8 +1254,8 @@ const RoundCuboidCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1189
1254
  * @category Colliders
1190
1255
  */
1191
1256
 
1192
- const BallCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1193
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1257
+ const BallCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1258
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1194
1259
  shape: "ball",
1195
1260
  ref: ref
1196
1261
  }));
@@ -1200,8 +1265,8 @@ const BallCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1200
1265
  * @category Colliders
1201
1266
  */
1202
1267
 
1203
- const CapsuleCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1204
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1268
+ const CapsuleCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1269
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1205
1270
  shape: "capsule",
1206
1271
  ref: ref
1207
1272
  }));
@@ -1211,8 +1276,8 @@ const CapsuleCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1211
1276
  * @category Colliders
1212
1277
  */
1213
1278
 
1214
- const HeightfieldCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1215
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1279
+ const HeightfieldCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1280
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1216
1281
  shape: "heightfield",
1217
1282
  ref: ref
1218
1283
  }));
@@ -1222,8 +1287,8 @@ const HeightfieldCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1222
1287
  * @category Colliders
1223
1288
  */
1224
1289
 
1225
- const TrimeshCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1226
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1290
+ const TrimeshCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1291
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1227
1292
  shape: "trimesh",
1228
1293
  ref: ref
1229
1294
  }));
@@ -1233,8 +1298,8 @@ const TrimeshCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1233
1298
  * @category Colliders
1234
1299
  */
1235
1300
 
1236
- const ConeCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1237
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1301
+ const ConeCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1302
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1238
1303
  shape: "cone",
1239
1304
  ref: ref
1240
1305
  }));
@@ -1244,8 +1309,8 @@ const ConeCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1244
1309
  * @category Colliders
1245
1310
  */
1246
1311
 
1247
- const CylinderCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1248
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1312
+ const CylinderCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1313
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1249
1314
  shape: "cylinder",
1250
1315
  ref: ref
1251
1316
  }));
@@ -1255,8 +1320,8 @@ const CylinderCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1255
1320
  * @category Colliders
1256
1321
  */
1257
1322
 
1258
- const ConvexHullCollider = /*#__PURE__*/React.forwardRef((props, ref) => {
1259
- return /*#__PURE__*/React.createElement(AnyCollider, _extends({}, props, {
1323
+ const ConvexHullCollider = /*#__PURE__*/React$1.forwardRef((props, ref) => {
1324
+ return /*#__PURE__*/React$1.createElement(AnyCollider, _extends({}, props, {
1260
1325
  shape: "convexHull",
1261
1326
  ref: ref
1262
1327
  }));
@@ -1400,7 +1465,8 @@ const useRigidBodyEvents = (getRigidBody, props, events) => {
1400
1465
  onCollisionEnter,
1401
1466
  onCollisionExit,
1402
1467
  onIntersectionEnter,
1403
- onIntersectionExit
1468
+ onIntersectionExit,
1469
+ onContactForce
1404
1470
  } = props;
1405
1471
  const eventHandlers = {
1406
1472
  onWake,
@@ -1408,7 +1474,8 @@ const useRigidBodyEvents = (getRigidBody, props, events) => {
1408
1474
  onCollisionEnter,
1409
1475
  onCollisionExit,
1410
1476
  onIntersectionEnter,
1411
- onIntersectionExit
1477
+ onIntersectionExit,
1478
+ onContactForce
1412
1479
  };
1413
1480
  useEffect(() => {
1414
1481
  const rigidBody = getRigidBody();
@@ -1416,7 +1483,7 @@ const useRigidBodyEvents = (getRigidBody, props, events) => {
1416
1483
  return () => {
1417
1484
  events.delete(rigidBody.handle);
1418
1485
  };
1419
- }, [onWake, onSleep, onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit]);
1486
+ }, [onWake, onSleep, onCollisionEnter, onCollisionExit, onIntersectionEnter, onIntersectionExit, onContactForce]);
1420
1487
  };
1421
1488
 
1422
1489
  const _excluded$1 = ["children", "type", "position", "rotation", "scale", "quaternion", "transformState"];
@@ -1482,16 +1549,16 @@ const RigidBody = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props, forwardedRe
1482
1549
  options: mergedOptions
1483
1550
  };
1484
1551
  }, [mergedOptions]);
1485
- return /*#__PURE__*/React.createElement(RigidBodyContext.Provider, {
1552
+ return /*#__PURE__*/React$1.createElement(RigidBodyContext.Provider, {
1486
1553
  value: contextValue
1487
- }, /*#__PURE__*/React.createElement("object3D", _extends({
1554
+ }, /*#__PURE__*/React$1.createElement("object3D", _extends({
1488
1555
  ref: ref
1489
1556
  }, objectProps, {
1490
1557
  position: position,
1491
1558
  rotation: rotation,
1492
1559
  quaternion: quaternion,
1493
1560
  scale: scale
1494
- }), children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React.createElement(AnyCollider, _extends({
1561
+ }), children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React$1.createElement(AnyCollider, _extends({
1495
1562
  key: index
1496
1563
  }, colliderProps)))));
1497
1564
  }));
@@ -1520,12 +1587,12 @@ const MeshCollider = /*#__PURE__*/memo(props => {
1520
1587
  });
1521
1588
  }, [physicsOptions, options]);
1522
1589
  const childColliderProps = useChildColliderProps(object, mergedOptions, false);
1523
- return /*#__PURE__*/React.createElement("object3D", {
1590
+ return /*#__PURE__*/React$1.createElement("object3D", {
1524
1591
  ref: object,
1525
1592
  userData: {
1526
1593
  r3RapierType: "MeshCollider"
1527
1594
  }
1528
- }, children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React.createElement(AnyCollider, _extends({
1595
+ }, children, childColliderProps.map((colliderProps, index) => /*#__PURE__*/React$1.createElement(AnyCollider, _extends({
1529
1596
  key: index
1530
1597
  }, colliderProps))));
1531
1598
  });
@@ -1578,13 +1645,13 @@ const AttractorHelper = props => {
1578
1645
  (_normalsHelper$curren = normalsHelper.current) === null || _normalsHelper$curren === void 0 ? void 0 : _normalsHelper$curren.update();
1579
1646
  }
1580
1647
  });
1581
- return /*#__PURE__*/React.createElement("mesh", {
1648
+ return /*#__PURE__*/React$1.createElement("mesh", {
1582
1649
  ref: ref,
1583
1650
  position: props.object.position,
1584
1651
  frustumCulled: false
1585
- }, /*#__PURE__*/React.createElement("sphereGeometry", {
1652
+ }, /*#__PURE__*/React$1.createElement("sphereGeometry", {
1586
1653
  args: [0.2, 6, 6]
1587
- }), /*#__PURE__*/React.createElement("meshBasicMaterial", {
1654
+ }), /*#__PURE__*/React$1.createElement("meshBasicMaterial", {
1588
1655
  color: color,
1589
1656
  wireframe: true
1590
1657
  }));
@@ -1610,13 +1677,13 @@ const Debug = /*#__PURE__*/memo(() => {
1610
1677
  currMap.current = new Map(attractorStates);
1611
1678
  }
1612
1679
  });
1613
- return /*#__PURE__*/React.createElement("group", null, /*#__PURE__*/React.createElement("lineSegments", {
1680
+ return /*#__PURE__*/React$1.createElement("group", null, /*#__PURE__*/React$1.createElement("lineSegments", {
1614
1681
  ref: ref,
1615
1682
  frustumCulled: false
1616
- }, /*#__PURE__*/React.createElement("lineBasicMaterial", {
1683
+ }, /*#__PURE__*/React$1.createElement("lineBasicMaterial", {
1617
1684
  color: 0xffffff,
1618
1685
  vertexColors: true
1619
- }), /*#__PURE__*/React.createElement("bufferGeometry", null)), attractors.map((attractor, i) => /*#__PURE__*/React.createElement(AttractorHelper, _extends({
1686
+ }), /*#__PURE__*/React$1.createElement("bufferGeometry", null)), attractors.map((attractor, i) => /*#__PURE__*/React$1.createElement(AttractorHelper, _extends({
1620
1687
  key: attractor.object.uuid
1621
1688
  }, attractor))));
1622
1689
  });
@@ -1685,21 +1752,21 @@ const InstancedRigidBodies = /*#__PURE__*/memo( /*#__PURE__*/forwardRef((props,
1685
1752
  return state;
1686
1753
  };
1687
1754
 
1688
- return /*#__PURE__*/React.createElement("object3D", _extends({
1755
+ return /*#__PURE__*/React$1.createElement("object3D", _extends({
1689
1756
  ref: object
1690
1757
  }, rigidBodyProps, {
1691
1758
  position: position,
1692
1759
  rotation: rotation,
1693
1760
  quaternion: quaternion,
1694
1761
  scale: scale
1695
- }), /*#__PURE__*/React.createElement("object3D", {
1762
+ }), /*#__PURE__*/React$1.createElement("object3D", {
1696
1763
  ref: instancedWrapper
1697
- }, children), instances === null || instances === void 0 ? void 0 : instances.map((instance, index) => /*#__PURE__*/React.createElement(RigidBody, _extends({}, rigidBodyProps, instance, {
1764
+ }, children), instances === null || instances === void 0 ? void 0 : instances.map((instance, index) => /*#__PURE__*/React$1.createElement(RigidBody, _extends({}, rigidBodyProps, instance, {
1698
1765
  ref: body => rigidBodyApis.current[index] = body,
1699
1766
  transformState: state => applyInstancedState(state, index)
1700
- }), /*#__PURE__*/React.createElement(React.Fragment, null, colliderNodes.map((node, index) => /*#__PURE__*/React.createElement(Fragment, {
1767
+ }), /*#__PURE__*/React$1.createElement(React$1.Fragment, null, colliderNodes.map((node, index) => /*#__PURE__*/React$1.createElement(Fragment, {
1701
1768
  key: index
1702
- }, node)), childColliderProps.map((colliderProps, colliderIndex) => /*#__PURE__*/React.createElement(AnyCollider, _extends({
1769
+ }, node)), childColliderProps.map((colliderProps, colliderIndex) => /*#__PURE__*/React$1.createElement(AnyCollider, _extends({
1703
1770
  key: colliderIndex
1704
1771
  }, colliderProps)))))));
1705
1772
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-three/rapier",
3
- "version": "0.14.0-rc.0",
3
+ "version": "0.14.0-rc.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",
package/readme.md CHANGED
@@ -838,4 +838,14 @@ step(1 / 60);
838
838
  ```
839
839
 
840
840
  ### On-demand rendering
841
- `@react-three/rapier` runs the physics simulation independently from the render loop, and will tell `@react-three/fiber` to render if the scene has active (non-sleeping) RigidBodies. This allows you to use the `<Canvas frameloop="demand" />` (https://docs.pmnd.rs/react-three-fiber/advanced/scaling-performance#on-demand-rendering) strategy to only render the scene when needed.
841
+ By default `@react-three/rapier` will update the physics simulation when a frame renders. This is fine for most cases, but if you want to only render the scene when things have changed, you need to run the physics simulation independently from the render loop.
842
+
843
+ - See https://docs.pmnd.rs/react-three-fiber/advanced/scaling-performance#on-demand-rendering, for info on on-demand rendering in `@react-tree/fiber`.
844
+
845
+ Setting `<Physics updateLoop="independent" />` will make the physics simulation run in it's own `requestAnimationFrame` loop, and call `invalidate` on the canvas only when there are active (moving) bodies.
846
+
847
+ ```tsx
848
+ <Canvas frameloop="demand">
849
+ <Physics updateLoop="independent">...</Physics>
850
+ </Canvas>
851
+ ```