@react-three/rapier 0.6.4 → 0.6.7
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/Debug.d.ts +13 -2
- package/dist/declarations/src/InstancedRigidBodies.d.ts +1 -1
- package/dist/declarations/src/Physics.d.ts +8 -6
- package/dist/declarations/src/RigidBody.d.ts +3 -2
- package/dist/declarations/src/types.d.ts +5 -1
- package/dist/declarations/src/utils.d.ts +9 -1
- package/dist/react-three-rapier.cjs.dev.js +163 -58
- package/dist/react-three-rapier.cjs.prod.js +163 -58
- package/dist/react-three-rapier.esm.js +165 -60
- package/package.json +3 -2
- package/readme.md +9 -5
@@ -1,9 +1,11 @@
|
|
1
1
|
import { ColliderDesc, ActiveEvents, RigidBodyDesc, CoefficientCombineRule, EventQueue, ShapeType } from '@dimforge/rapier3d-compat';
|
2
2
|
export { CoefficientCombineRule, Collider as RapierCollider, RigidBody as RapierRigidBody } from '@dimforge/rapier3d-compat';
|
3
|
-
import React, {
|
3
|
+
import React, { useState, useEffect, useRef, useMemo, createContext, useContext, forwardRef, useImperativeHandle, memo, useLayoutEffect } from 'react';
|
4
4
|
import { useAsset } from 'use-asset';
|
5
5
|
import { useFrame } from '@react-three/fiber';
|
6
|
-
import { Quaternion, Euler, Vector3, Object3D, Matrix4, InstancedMesh, CylinderBufferGeometry, BufferGeometry, BufferAttribute, SphereBufferGeometry, BoxBufferGeometry, DynamicDrawUsage } from 'three';
|
6
|
+
import { Quaternion, Euler, Vector3, Object3D, Matrix4, InstancedMesh, MeshBasicMaterial, Color, PlaneGeometry, ConeBufferGeometry, CapsuleBufferGeometry, CylinderBufferGeometry, BufferGeometry, BufferAttribute, SphereBufferGeometry, BoxBufferGeometry, DynamicDrawUsage } from 'three';
|
7
|
+
import { mergeVertices } from 'three/examples/jsm/utils/BufferGeometryUtils';
|
8
|
+
import { RoundedBoxGeometry } from 'three-stdlib';
|
7
9
|
|
8
10
|
const _quaternion = new Quaternion();
|
9
11
|
const _euler = new Euler();
|
@@ -48,11 +50,13 @@ const decomposeMatrix4 = m => {
|
|
48
50
|
};
|
49
51
|
};
|
50
52
|
const scaleColliderArgs = (shape, args, scale) => {
|
51
|
-
// Heightfield
|
52
|
-
const newArgs = args.slice();
|
53
|
+
const newArgs = args.slice(); // Heightfield uses a vector
|
53
54
|
|
54
55
|
if (shape === "heightfield") {
|
55
|
-
newArgs[3]
|
56
|
+
const s = newArgs[3];
|
57
|
+
s.x *= scale.x;
|
58
|
+
s.x *= scale.y;
|
59
|
+
s.x *= scale.z;
|
56
60
|
return newArgs;
|
57
61
|
} // Trimesh and convex scale the vertices
|
58
62
|
|
@@ -60,9 +64,10 @@ const scaleColliderArgs = (shape, args, scale) => {
|
|
60
64
|
if (shape === "trimesh" || shape === "convexHull") {
|
61
65
|
newArgs[0] = scaleVertices(newArgs[0], scale);
|
62
66
|
return newArgs;
|
63
|
-
}
|
67
|
+
} // Prepfill with some extra
|
68
|
+
|
64
69
|
|
65
|
-
const scaleArray = [scale.x, scale.y, scale.z];
|
70
|
+
const scaleArray = [scale.x, scale.y, scale.z, scale.x, scale.x];
|
66
71
|
return newArgs.map((arg, index) => scaleArray[index] * arg);
|
67
72
|
};
|
68
73
|
const createColliderFromOptions = ({
|
@@ -92,6 +97,10 @@ const createColliderFromOptions = ({
|
|
92
97
|
w: qRotation.w
|
93
98
|
}).setRestitution((_options$restitution = options === null || options === void 0 ? void 0 : options.restitution) !== null && _options$restitution !== void 0 ? _options$restitution : 0).setRestitutionCombineRule((_options$restitutionC = options === null || options === void 0 ? void 0 : options.restitutionCombineRule) !== null && _options$restitutionC !== void 0 ? _options$restitutionC : CoefficientCombineRule.Average).setFriction((_options$friction = options === null || options === void 0 ? void 0 : options.friction) !== null && _options$friction !== void 0 ? _options$friction : 0.7).setFrictionCombineRule((_options$frictionComb = options === null || options === void 0 ? void 0 : options.frictionCombineRule) !== null && _options$frictionComb !== void 0 ? _options$frictionComb : CoefficientCombineRule.Average);
|
94
99
|
|
100
|
+
if (colliderShape === "heightfield") {
|
101
|
+
console.log(colliderDesc);
|
102
|
+
}
|
103
|
+
|
95
104
|
if (hasCollisionEvents) {
|
96
105
|
colliderDesc = colliderDesc.setActiveEvents(ActiveEvents.COLLISION_EVENTS);
|
97
106
|
} // If any of the mass properties are specified, add mass properties
|
@@ -219,15 +228,15 @@ const colliderDescFromGeometry = (geometry, colliders, scale, hasCollisionEvents
|
|
219
228
|
{
|
220
229
|
var _g$index;
|
221
230
|
|
222
|
-
const
|
223
|
-
|
224
|
-
desc = ColliderDesc.trimesh(
|
231
|
+
const clonedGeometry = geometry.index ? geometry.clone() : mergeVertices(geometry);
|
232
|
+
const g = clonedGeometry.scale(scale.x, scale.y, scale.z);
|
233
|
+
desc = ColliderDesc.trimesh(g.attributes.position.array, (_g$index = g.index) === null || _g$index === void 0 ? void 0 : _g$index.array);
|
225
234
|
}
|
226
235
|
break;
|
227
236
|
|
228
237
|
case "hull":
|
229
|
-
const g = geometry.clone().scale(scale.x, scale.y, scale.z);
|
230
238
|
{
|
239
|
+
const g = geometry.clone().scale(scale.x, scale.y, scale.z);
|
231
240
|
desc = ColliderDesc.convexHull(g.attributes.position.array);
|
232
241
|
}
|
233
242
|
break;
|
@@ -444,10 +453,15 @@ const Physics = ({
|
|
444
453
|
colliders: _colliders = "cuboid",
|
445
454
|
gravity: _gravity = [0, -9.81, 0],
|
446
455
|
children,
|
447
|
-
timeStep: _timeStep =
|
456
|
+
timeStep: _timeStep = 1 / 60,
|
457
|
+
maxSubSteps: _maxSubSteps = 10,
|
448
458
|
paused: _paused = false
|
449
459
|
}) => {
|
450
460
|
const rapier = useAsset(importRapier);
|
461
|
+
const [isPaused, setIsPaused] = useState(_paused);
|
462
|
+
useEffect(() => {
|
463
|
+
setIsPaused(_paused);
|
464
|
+
}, [_paused]);
|
451
465
|
const worldRef = useRef();
|
452
466
|
const getWorldRef = useRef(() => {
|
453
467
|
if (!worldRef.current) {
|
@@ -467,7 +481,6 @@ const Physics = ({
|
|
467
481
|
return () => {
|
468
482
|
if (world) {
|
469
483
|
world.free();
|
470
|
-
worldRef.current = undefined;
|
471
484
|
}
|
472
485
|
};
|
473
486
|
}, []); // Update gravity
|
@@ -479,22 +492,46 @@ const Physics = ({
|
|
479
492
|
world.gravity = vectorArrayToVector3(_gravity);
|
480
493
|
}
|
481
494
|
}, [_gravity]);
|
482
|
-
const
|
483
|
-
|
495
|
+
const [steppingState] = useState({
|
496
|
+
time: 0,
|
497
|
+
lastTime: 0,
|
498
|
+
accumulator: 0
|
499
|
+
});
|
500
|
+
useFrame((_, delta) => {
|
484
501
|
const world = worldRef.current;
|
485
|
-
if (!world) return;
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
502
|
+
if (!world) return;
|
503
|
+
world.timestep = _timeStep;
|
504
|
+
/**
|
505
|
+
* Fixed timeStep simulation progression
|
506
|
+
* @see https://gafferongames.com/post/fix_your_timestep/
|
507
|
+
*/
|
508
|
+
|
509
|
+
let previousTranslations = {}; // don't step time forwards if paused
|
510
|
+
|
511
|
+
const nowTime = steppingState.time += _paused ? 0 : delta * 1000;
|
512
|
+
const timeStepMs = _timeStep * 1000;
|
513
|
+
const timeSinceLast = nowTime - steppingState.lastTime;
|
514
|
+
steppingState.lastTime = nowTime;
|
515
|
+
steppingState.accumulator += timeSinceLast;
|
516
|
+
|
517
|
+
if (!_paused) {
|
518
|
+
let subSteps = 0;
|
519
|
+
|
520
|
+
while (steppingState.accumulator >= timeStepMs && subSteps < _maxSubSteps) {
|
521
|
+
// Collect previous state
|
522
|
+
world.bodies.forEach(b => {
|
523
|
+
previousTranslations[b.handle] = {
|
524
|
+
rotation: rapierQuaternionToQuaternion(b.rotation()).normalize(),
|
525
|
+
translation: rapierVector3ToVector3(b.translation())
|
526
|
+
};
|
527
|
+
});
|
528
|
+
world.step(eventQueue);
|
529
|
+
subSteps++;
|
530
|
+
steppingState.accumulator -= timeStepMs;
|
531
|
+
}
|
495
532
|
}
|
496
533
|
|
497
|
-
|
534
|
+
const interpolationAlpha = steppingState.accumulator % timeStepMs / timeStepMs; // Update meshes
|
498
535
|
|
499
536
|
rigidBodyStates.forEach((state, handle) => {
|
500
537
|
const rigidBody = world.getRigidBody(handle);
|
@@ -516,11 +553,16 @@ const Physics = ({
|
|
516
553
|
state.isSleeping = rigidBody.isSleeping();
|
517
554
|
}
|
518
555
|
|
519
|
-
if (!rigidBody || rigidBody.isSleeping() ||
|
556
|
+
if (!rigidBody || rigidBody.isSleeping() || !state.setMatrix) {
|
520
557
|
return;
|
521
558
|
}
|
522
559
|
|
523
|
-
|
560
|
+
let oldState = previousTranslations[rigidBody.handle];
|
561
|
+
let newTranslation = rapierVector3ToVector3(rigidBody.translation());
|
562
|
+
let newRotation = rapierQuaternionToQuaternion(rigidBody.rotation());
|
563
|
+
let interpolatedTranslation = oldState ? oldState.translation.lerp(newTranslation, 1) : newTranslation;
|
564
|
+
let interpolatedRotation = oldState ? oldState.rotation.slerp(newRotation, interpolationAlpha) : newRotation;
|
565
|
+
state.setMatrix(_matrix4.compose(interpolatedTranslation, interpolatedRotation, state.worldScale).premultiply(state.invertedMatrixWorld));
|
524
566
|
|
525
567
|
if (state.mesh instanceof InstancedMesh) {
|
526
568
|
state.mesh.instanceMatrix.needsUpdate = true;
|
@@ -570,7 +612,6 @@ const Physics = ({
|
|
570
612
|
});
|
571
613
|
}
|
572
614
|
});
|
573
|
-
time.current = now;
|
574
615
|
});
|
575
616
|
const api = useMemo(() => createWorldApi(getWorldRef), []);
|
576
617
|
const context = useMemo(() => ({
|
@@ -582,13 +623,32 @@ const Physics = ({
|
|
582
623
|
},
|
583
624
|
colliderMeshes,
|
584
625
|
rigidBodyStates,
|
585
|
-
rigidBodyEvents
|
586
|
-
|
626
|
+
rigidBodyEvents,
|
627
|
+
isPaused
|
628
|
+
}), [isPaused]);
|
587
629
|
return /*#__PURE__*/React.createElement(RapierContext.Provider, {
|
588
630
|
value: context
|
589
631
|
}, children);
|
590
632
|
};
|
591
633
|
|
634
|
+
function _extends() {
|
635
|
+
_extends = Object.assign || function (target) {
|
636
|
+
for (var i = 1; i < arguments.length; i++) {
|
637
|
+
var source = arguments[i];
|
638
|
+
|
639
|
+
for (var key in source) {
|
640
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
641
|
+
target[key] = source[key];
|
642
|
+
}
|
643
|
+
}
|
644
|
+
}
|
645
|
+
|
646
|
+
return target;
|
647
|
+
};
|
648
|
+
|
649
|
+
return _extends.apply(this, arguments);
|
650
|
+
}
|
651
|
+
|
592
652
|
function _objectWithoutPropertiesLoose(source, excluded) {
|
593
653
|
if (source == null) return {};
|
594
654
|
var target = {};
|
@@ -855,7 +915,8 @@ const usePrismaticJoint = (body1, body2, [body1Anchor, body2Anchor, axis]) => {
|
|
855
915
|
return useImpulseJoint(body1, body2, rapier.JointData.prismatic(vectorArrayToVector3(body1Anchor), vectorArrayToVector3(body2Anchor), vectorArrayToVector3(axis)));
|
856
916
|
};
|
857
917
|
|
858
|
-
const _excluded$1 = ["children"]
|
918
|
+
const _excluded$1 = ["children"],
|
919
|
+
_excluded2 = ["type", "position", "rotation"];
|
859
920
|
const RigidBodyContext = /*#__PURE__*/createContext(undefined);
|
860
921
|
const useRigidBodyContext = () => useContext(RigidBodyContext); // RigidBody
|
861
922
|
|
@@ -866,6 +927,9 @@ const RigidBody = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
866
927
|
props = _objectWithoutProperties(_ref, _excluded$1);
|
867
928
|
|
868
929
|
const [object, api] = useRigidBody(props);
|
930
|
+
|
931
|
+
const objectProps = _objectWithoutProperties(props, _excluded2);
|
932
|
+
|
869
933
|
useImperativeHandle(ref, () => api);
|
870
934
|
return /*#__PURE__*/React.createElement(RigidBodyContext.Provider, {
|
871
935
|
value: {
|
@@ -874,9 +938,9 @@ const RigidBody = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
874
938
|
hasCollisionEvents: !!(props.onCollisionEnter || props.onCollisionExit),
|
875
939
|
options: props
|
876
940
|
}
|
877
|
-
}, /*#__PURE__*/React.createElement("object3D", {
|
941
|
+
}, /*#__PURE__*/React.createElement("object3D", _extends({
|
878
942
|
ref: object
|
879
|
-
}, children));
|
943
|
+
}, objectProps), children));
|
880
944
|
});
|
881
945
|
|
882
946
|
const MeshCollider = ({
|
@@ -939,6 +1003,17 @@ const geometryFromCollider = collider => {
|
|
939
1003
|
return new BoxBufferGeometry(x * 2 + 0.01, y * 2 + 0.01, z * 2 + 0.01);
|
940
1004
|
}
|
941
1005
|
|
1006
|
+
case ShapeType.RoundCuboid:
|
1007
|
+
{
|
1008
|
+
const {
|
1009
|
+
x,
|
1010
|
+
y,
|
1011
|
+
z
|
1012
|
+
} = collider.shape.halfExtents;
|
1013
|
+
const radius = collider.shape.borderRadius;
|
1014
|
+
return new RoundedBoxGeometry(x * 2 + radius * 2, y * 2 + radius * 2, z * 2 + radius * 2, 8, radius);
|
1015
|
+
}
|
1016
|
+
|
942
1017
|
case ShapeType.Ball:
|
943
1018
|
{
|
944
1019
|
const r = collider.shape.radius;
|
@@ -974,7 +1049,38 @@ const geometryFromCollider = collider => {
|
|
974
1049
|
{
|
975
1050
|
const r = collider.shape.radius;
|
976
1051
|
const h = collider.shape.halfHeight;
|
977
|
-
const g = new CylinderBufferGeometry(r, r, h);
|
1052
|
+
const g = new CylinderBufferGeometry(r, r, h * 2);
|
1053
|
+
return g;
|
1054
|
+
}
|
1055
|
+
|
1056
|
+
case ShapeType.Capsule:
|
1057
|
+
{
|
1058
|
+
const r = collider.shape.radius;
|
1059
|
+
const h = collider.shape.halfHeight;
|
1060
|
+
const g = new CapsuleBufferGeometry(r, h * 2, 4, 8);
|
1061
|
+
return g;
|
1062
|
+
}
|
1063
|
+
|
1064
|
+
case ShapeType.Cone:
|
1065
|
+
{
|
1066
|
+
const r = collider.shape.radius;
|
1067
|
+
const h = collider.shape.halfHeight;
|
1068
|
+
const g = new ConeBufferGeometry(r, h * 2, 16);
|
1069
|
+
return g;
|
1070
|
+
}
|
1071
|
+
|
1072
|
+
case ShapeType.HeightField:
|
1073
|
+
{
|
1074
|
+
const rows = collider.shape.nrows;
|
1075
|
+
const cols = collider.shape.ncols;
|
1076
|
+
const heights = collider.shape.heights;
|
1077
|
+
const scale = collider.shape.scale;
|
1078
|
+
const g = new PlaneGeometry(scale.x, scale.z, cols, rows);
|
1079
|
+
const verts = g.attributes.position.array;
|
1080
|
+
verts.forEach((v, index) => verts[index * 3 + 2] = heights[index] * scale.y);
|
1081
|
+
g.scale(1, -1, 1);
|
1082
|
+
g.rotateX(-Math.PI / 2);
|
1083
|
+
g.rotateY(-Math.PI / 2);
|
978
1084
|
return g;
|
979
1085
|
}
|
980
1086
|
}
|
@@ -983,12 +1089,18 @@ const geometryFromCollider = collider => {
|
|
983
1089
|
};
|
984
1090
|
|
985
1091
|
const DebugShape = /*#__PURE__*/memo(({
|
986
|
-
colliderHandle
|
1092
|
+
colliderHandle,
|
1093
|
+
color,
|
1094
|
+
sleepColor
|
987
1095
|
}) => {
|
988
1096
|
const {
|
989
1097
|
world
|
990
1098
|
} = useRapier();
|
991
1099
|
const ref = useRef(null);
|
1100
|
+
const [material] = useState(new MeshBasicMaterial({
|
1101
|
+
color,
|
1102
|
+
wireframe: true
|
1103
|
+
}));
|
992
1104
|
useFrame(() => {
|
993
1105
|
const collider = world.getCollider(colliderHandle);
|
994
1106
|
|
@@ -1004,6 +1116,14 @@ const DebugShape = /*#__PURE__*/memo(({
|
|
1004
1116
|
y,
|
1005
1117
|
z
|
1006
1118
|
} = collider.translation();
|
1119
|
+
const parent = collider.parent();
|
1120
|
+
|
1121
|
+
if (parent !== null && parent !== void 0 && parent.isSleeping() || parent !== null && parent !== void 0 && parent.isFixed() || parent !== null && parent !== void 0 && parent.isKinematic()) {
|
1122
|
+
material.color = new Color(sleepColor);
|
1123
|
+
} else {
|
1124
|
+
material.color = new Color(color);
|
1125
|
+
}
|
1126
|
+
|
1007
1127
|
ref.current.position.set(x, y, z);
|
1008
1128
|
ref.current.rotation.setFromQuaternion(new Quaternion(rx, ry, rz, rw));
|
1009
1129
|
}
|
@@ -1013,16 +1133,17 @@ const DebugShape = /*#__PURE__*/memo(({
|
|
1013
1133
|
return geometryFromCollider(collider);
|
1014
1134
|
}, [colliderHandle]);
|
1015
1135
|
return /*#__PURE__*/React.createElement("mesh", {
|
1016
|
-
ref: ref
|
1136
|
+
ref: ref,
|
1137
|
+
material: material
|
1017
1138
|
}, /*#__PURE__*/React.createElement("primitive", {
|
1018
1139
|
object: geometry,
|
1019
1140
|
attach: "geometry"
|
1020
|
-
}), /*#__PURE__*/React.createElement("meshBasicMaterial", {
|
1021
|
-
color: "red",
|
1022
|
-
wireframe: true
|
1023
1141
|
}));
|
1024
1142
|
});
|
1025
|
-
const Debug = (
|
1143
|
+
const Debug = ({
|
1144
|
+
color: _color = "red",
|
1145
|
+
sleepColor: _sleepColor = "blue"
|
1146
|
+
}) => {
|
1026
1147
|
const {
|
1027
1148
|
world
|
1028
1149
|
} = useRapier();
|
@@ -1038,7 +1159,9 @@ const Debug = () => {
|
|
1038
1159
|
});
|
1039
1160
|
return /*#__PURE__*/React.createElement("group", null, colliders.map(handle => /*#__PURE__*/React.createElement(DebugShape, {
|
1040
1161
|
key: handle,
|
1041
|
-
colliderHandle: handle
|
1162
|
+
colliderHandle: handle,
|
1163
|
+
color: _color,
|
1164
|
+
sleepColor: _sleepColor
|
1042
1165
|
})));
|
1043
1166
|
};
|
1044
1167
|
|
@@ -1166,24 +1289,6 @@ const InstancedRigidBodies = /*#__PURE__*/forwardRef((props, ref) => {
|
|
1166
1289
|
}, props.children));
|
1167
1290
|
});
|
1168
1291
|
|
1169
|
-
function _extends() {
|
1170
|
-
_extends = Object.assign || function (target) {
|
1171
|
-
for (var i = 1; i < arguments.length; i++) {
|
1172
|
-
var source = arguments[i];
|
1173
|
-
|
1174
|
-
for (var key in source) {
|
1175
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
1176
|
-
target[key] = source[key];
|
1177
|
-
}
|
1178
|
-
}
|
1179
|
-
}
|
1180
|
-
|
1181
|
-
return target;
|
1182
|
-
};
|
1183
|
-
|
1184
|
-
return _extends.apply(this, arguments);
|
1185
|
-
}
|
1186
|
-
|
1187
1292
|
const _excluded = ["children"];
|
1188
1293
|
|
1189
1294
|
const AnyCollider = _ref => {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@react-three/rapier",
|
3
|
-
"version": "0.6.
|
3
|
+
"version": "0.6.7",
|
4
4
|
"source": "src/index.ts",
|
5
5
|
"main": "dist/react-three-rapier.cjs.js",
|
6
6
|
"module": "dist/react-three-rapier.esm.js",
|
@@ -20,7 +20,8 @@
|
|
20
20
|
"peerDependencies": {
|
21
21
|
"@react-three/fiber": "^8.0.12",
|
22
22
|
"react": "^18.0.0",
|
23
|
-
"three": "^0.139.2"
|
23
|
+
"three": "^0.139.2",
|
24
|
+
"three-stdlib": "^2.15.0"
|
24
25
|
},
|
25
26
|
"dependencies": {
|
26
27
|
"@dimforge/rapier3d-compat": "0.9.0",
|
package/readme.md
CHANGED
@@ -80,8 +80,8 @@ const Scene = () => (
|
|
80
80
|
{/* Make a compound shape with two custom BallColliders */}
|
81
81
|
<RigidBody position={[0, 10, 0]}>
|
82
82
|
<Sphere />
|
83
|
-
<BallCollider args={0.5} />
|
84
|
-
<BallCollider args={0.5} position={[1, 0, 0]} />
|
83
|
+
<BallCollider args={[0.5]} />
|
84
|
+
<BallCollider args={[0.5]} position={[1, 0, 0]} />
|
85
85
|
</RigidBody>
|
86
86
|
|
87
87
|
{/* Make a compound shape with two custom BallColliders, an automatic BallCollider,
|
@@ -97,8 +97,8 @@ const Scene = () => (
|
|
97
97
|
|
98
98
|
<Sphere />
|
99
99
|
|
100
|
-
<BallCollider args={0.5} />
|
101
|
-
<BallCollider args={0.5} position={[1, 0, 0]} />
|
100
|
+
<BallCollider args={[0.5]} />
|
101
|
+
<BallCollider args={[0.5]} position={[1, 0, 0]} />
|
102
102
|
</RigidBody>
|
103
103
|
</Physics>
|
104
104
|
);
|
@@ -185,6 +185,9 @@ const Scene = () => {
|
|
185
185
|
|
186
186
|
Use the Debug component to see live representations of all colliders in a scene.
|
187
187
|
|
188
|
+
- The `color` prop sets the color of awake colliders that are affected by forces.
|
189
|
+
- The `sleepColor` prop set the color of a static (fixed, or kinematic) or sleeping collider.
|
190
|
+
|
188
191
|
> Note: Experimental. Not all shapes are supported. Unsupported shapes are always represented by cubes.
|
189
192
|
|
190
193
|
```tsx
|
@@ -194,7 +197,7 @@ import { RigidBody, Debug } from "@react-three/rapier";
|
|
194
197
|
const Scene = () => {
|
195
198
|
return (
|
196
199
|
<Physics>
|
197
|
-
<Debug />
|
200
|
+
<Debug color="red" sleepColor="blue" />
|
198
201
|
|
199
202
|
<RigidBody>
|
200
203
|
<Box />
|
@@ -251,6 +254,7 @@ In order, but also not necessarily:
|
|
251
254
|
- [x] Collision events
|
252
255
|
- [x] Colliders outside RigidBodies
|
253
256
|
- [x] InstancedMesh support
|
257
|
+
- [x] Timestep improvements for determinism
|
254
258
|
- [ ] Normalize and improve collision events (add events to single Colliders, InstancedRigidBodies, etc)
|
255
259
|
- [ ] Docs
|
256
260
|
- [ ] CodeSandbox examples
|