@react-three/rapier 0.6.6 → 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/types.d.ts +5 -1
- package/dist/declarations/src/utils.d.ts +9 -1
- package/dist/react-three-rapier.cjs.dev.js +84 -19
- package/dist/react-three-rapier.cjs.prod.js +84 -19
- package/dist/react-three-rapier.esm.js +85 -20
- package/package.json +3 -2
- package/readme.md +8 -5
@@ -1,2 +1,13 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
import { FC } from "react";
|
2
|
+
interface DebugProps {
|
3
|
+
/**
|
4
|
+
* The color of the wireframe representing an active collider that is affected by forces and not sleeping.
|
5
|
+
*/
|
6
|
+
color?: string;
|
7
|
+
/**
|
8
|
+
* The color of the wireframe representing a static (fixed or kinematic) or sleeping collider.
|
9
|
+
*/
|
10
|
+
sleepColor?: string;
|
11
|
+
}
|
12
|
+
export declare const Debug: FC<DebugProps>;
|
13
|
+
export {};
|
@@ -21,7 +21,11 @@ export declare type HeightfieldArgs = [
|
|
21
21
|
width: number,
|
22
22
|
height: number,
|
23
23
|
heights: number[],
|
24
|
-
scale:
|
24
|
+
scale: {
|
25
|
+
x: number;
|
26
|
+
y: number;
|
27
|
+
z: number;
|
28
|
+
}
|
25
29
|
];
|
26
30
|
export declare type TrimeshArgs = [
|
27
31
|
vertices: ArrayLike<number>,
|
@@ -11,7 +11,15 @@ export declare const decomposeMatrix4: (m: Matrix4) => {
|
|
11
11
|
rotation: Quaternion;
|
12
12
|
scale: Vector3;
|
13
13
|
};
|
14
|
-
export declare const scaleColliderArgs: (shape: RigidBodyShape, args: (number | ArrayLike<number>
|
14
|
+
export declare const scaleColliderArgs: (shape: RigidBodyShape, args: (number | ArrayLike<number> | {
|
15
|
+
x: number;
|
16
|
+
y: number;
|
17
|
+
z: number;
|
18
|
+
})[], scale: Vector3) => (number | ArrayLike<number> | {
|
19
|
+
x: number;
|
20
|
+
y: number;
|
21
|
+
z: number;
|
22
|
+
})[];
|
15
23
|
interface CreateColliderFromOptions {
|
16
24
|
<ColliderArgs>(options: {
|
17
25
|
options: UseColliderOptions<ColliderArgs>;
|
@@ -8,6 +8,7 @@ var useAsset = require('use-asset');
|
|
8
8
|
var fiber = require('@react-three/fiber');
|
9
9
|
var three = require('three');
|
10
10
|
var BufferGeometryUtils = require('three/examples/jsm/utils/BufferGeometryUtils');
|
11
|
+
var threeStdlib = require('three-stdlib');
|
11
12
|
|
12
13
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
13
14
|
|
@@ -74,11 +75,13 @@ const decomposeMatrix4 = m => {
|
|
74
75
|
};
|
75
76
|
};
|
76
77
|
const scaleColliderArgs = (shape, args, scale) => {
|
77
|
-
// Heightfield
|
78
|
-
const newArgs = args.slice();
|
78
|
+
const newArgs = args.slice(); // Heightfield uses a vector
|
79
79
|
|
80
80
|
if (shape === "heightfield") {
|
81
|
-
newArgs[3]
|
81
|
+
const s = newArgs[3];
|
82
|
+
s.x *= scale.x;
|
83
|
+
s.x *= scale.y;
|
84
|
+
s.x *= scale.z;
|
82
85
|
return newArgs;
|
83
86
|
} // Trimesh and convex scale the vertices
|
84
87
|
|
@@ -86,9 +89,10 @@ const scaleColliderArgs = (shape, args, scale) => {
|
|
86
89
|
if (shape === "trimesh" || shape === "convexHull") {
|
87
90
|
newArgs[0] = scaleVertices(newArgs[0], scale);
|
88
91
|
return newArgs;
|
89
|
-
}
|
92
|
+
} // Prepfill with some extra
|
93
|
+
|
90
94
|
|
91
|
-
const scaleArray = [scale.x, scale.y, scale.z];
|
95
|
+
const scaleArray = [scale.x, scale.y, scale.z, scale.x, scale.x];
|
92
96
|
return newArgs.map((arg, index) => scaleArray[index] * arg);
|
93
97
|
};
|
94
98
|
const createColliderFromOptions = ({
|
@@ -118,6 +122,10 @@ const createColliderFromOptions = ({
|
|
118
122
|
w: qRotation.w
|
119
123
|
}).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 : rapier3dCompat.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 : rapier3dCompat.CoefficientCombineRule.Average);
|
120
124
|
|
125
|
+
if (colliderShape === "heightfield") {
|
126
|
+
console.log(colliderDesc);
|
127
|
+
}
|
128
|
+
|
121
129
|
if (hasCollisionEvents) {
|
122
130
|
colliderDesc = colliderDesc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
|
123
131
|
} // If any of the mass properties are specified, add mass properties
|
@@ -246,16 +254,14 @@ const colliderDescFromGeometry = (geometry, colliders, scale, hasCollisionEvents
|
|
246
254
|
var _g$index;
|
247
255
|
|
248
256
|
const clonedGeometry = geometry.index ? geometry.clone() : BufferGeometryUtils.mergeVertices(geometry);
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
desc = rapier3dCompat.ColliderDesc.trimesh(_g.attributes.position.array, (_g$index = _g.index) === null || _g$index === void 0 ? void 0 : _g$index.array);
|
257
|
+
const g = clonedGeometry.scale(scale.x, scale.y, scale.z);
|
258
|
+
desc = rapier3dCompat.ColliderDesc.trimesh(g.attributes.position.array, (_g$index = g.index) === null || _g$index === void 0 ? void 0 : _g$index.array);
|
253
259
|
}
|
254
260
|
break;
|
255
261
|
|
256
262
|
case "hull":
|
257
|
-
const g = geometry.clone().scale(scale.x, scale.y, scale.z);
|
258
263
|
{
|
264
|
+
const g = geometry.clone().scale(scale.x, scale.y, scale.z);
|
259
265
|
desc = rapier3dCompat.ColliderDesc.convexHull(g.attributes.position.array);
|
260
266
|
}
|
261
267
|
break;
|
@@ -572,7 +578,7 @@ const Physics = ({
|
|
572
578
|
state.isSleeping = rigidBody.isSleeping();
|
573
579
|
}
|
574
580
|
|
575
|
-
if (!rigidBody || rigidBody.isSleeping() ||
|
581
|
+
if (!rigidBody || rigidBody.isSleeping() || !state.setMatrix) {
|
576
582
|
return;
|
577
583
|
}
|
578
584
|
|
@@ -1022,6 +1028,17 @@ const geometryFromCollider = collider => {
|
|
1022
1028
|
return new three.BoxBufferGeometry(x * 2 + 0.01, y * 2 + 0.01, z * 2 + 0.01);
|
1023
1029
|
}
|
1024
1030
|
|
1031
|
+
case rapier3dCompat.ShapeType.RoundCuboid:
|
1032
|
+
{
|
1033
|
+
const {
|
1034
|
+
x,
|
1035
|
+
y,
|
1036
|
+
z
|
1037
|
+
} = collider.shape.halfExtents;
|
1038
|
+
const radius = collider.shape.borderRadius;
|
1039
|
+
return new threeStdlib.RoundedBoxGeometry(x * 2 + radius * 2, y * 2 + radius * 2, z * 2 + radius * 2, 8, radius);
|
1040
|
+
}
|
1041
|
+
|
1025
1042
|
case rapier3dCompat.ShapeType.Ball:
|
1026
1043
|
{
|
1027
1044
|
const r = collider.shape.radius;
|
@@ -1057,7 +1074,38 @@ const geometryFromCollider = collider => {
|
|
1057
1074
|
{
|
1058
1075
|
const r = collider.shape.radius;
|
1059
1076
|
const h = collider.shape.halfHeight;
|
1060
|
-
const g = new three.CylinderBufferGeometry(r, r, h);
|
1077
|
+
const g = new three.CylinderBufferGeometry(r, r, h * 2);
|
1078
|
+
return g;
|
1079
|
+
}
|
1080
|
+
|
1081
|
+
case rapier3dCompat.ShapeType.Capsule:
|
1082
|
+
{
|
1083
|
+
const r = collider.shape.radius;
|
1084
|
+
const h = collider.shape.halfHeight;
|
1085
|
+
const g = new three.CapsuleBufferGeometry(r, h * 2, 4, 8);
|
1086
|
+
return g;
|
1087
|
+
}
|
1088
|
+
|
1089
|
+
case rapier3dCompat.ShapeType.Cone:
|
1090
|
+
{
|
1091
|
+
const r = collider.shape.radius;
|
1092
|
+
const h = collider.shape.halfHeight;
|
1093
|
+
const g = new three.ConeBufferGeometry(r, h * 2, 16);
|
1094
|
+
return g;
|
1095
|
+
}
|
1096
|
+
|
1097
|
+
case rapier3dCompat.ShapeType.HeightField:
|
1098
|
+
{
|
1099
|
+
const rows = collider.shape.nrows;
|
1100
|
+
const cols = collider.shape.ncols;
|
1101
|
+
const heights = collider.shape.heights;
|
1102
|
+
const scale = collider.shape.scale;
|
1103
|
+
const g = new three.PlaneGeometry(scale.x, scale.z, cols, rows);
|
1104
|
+
const verts = g.attributes.position.array;
|
1105
|
+
verts.forEach((v, index) => verts[index * 3 + 2] = heights[index] * scale.y);
|
1106
|
+
g.scale(1, -1, 1);
|
1107
|
+
g.rotateX(-Math.PI / 2);
|
1108
|
+
g.rotateY(-Math.PI / 2);
|
1061
1109
|
return g;
|
1062
1110
|
}
|
1063
1111
|
}
|
@@ -1066,12 +1114,18 @@ const geometryFromCollider = collider => {
|
|
1066
1114
|
};
|
1067
1115
|
|
1068
1116
|
const DebugShape = /*#__PURE__*/React.memo(({
|
1069
|
-
colliderHandle
|
1117
|
+
colliderHandle,
|
1118
|
+
color,
|
1119
|
+
sleepColor
|
1070
1120
|
}) => {
|
1071
1121
|
const {
|
1072
1122
|
world
|
1073
1123
|
} = useRapier();
|
1074
1124
|
const ref = React.useRef(null);
|
1125
|
+
const [material] = React.useState(new three.MeshBasicMaterial({
|
1126
|
+
color,
|
1127
|
+
wireframe: true
|
1128
|
+
}));
|
1075
1129
|
fiber.useFrame(() => {
|
1076
1130
|
const collider = world.getCollider(colliderHandle);
|
1077
1131
|
|
@@ -1087,6 +1141,14 @@ const DebugShape = /*#__PURE__*/React.memo(({
|
|
1087
1141
|
y,
|
1088
1142
|
z
|
1089
1143
|
} = collider.translation();
|
1144
|
+
const parent = collider.parent();
|
1145
|
+
|
1146
|
+
if (parent !== null && parent !== void 0 && parent.isSleeping() || parent !== null && parent !== void 0 && parent.isFixed() || parent !== null && parent !== void 0 && parent.isKinematic()) {
|
1147
|
+
material.color = new three.Color(sleepColor);
|
1148
|
+
} else {
|
1149
|
+
material.color = new three.Color(color);
|
1150
|
+
}
|
1151
|
+
|
1090
1152
|
ref.current.position.set(x, y, z);
|
1091
1153
|
ref.current.rotation.setFromQuaternion(new three.Quaternion(rx, ry, rz, rw));
|
1092
1154
|
}
|
@@ -1096,16 +1158,17 @@ const DebugShape = /*#__PURE__*/React.memo(({
|
|
1096
1158
|
return geometryFromCollider(collider);
|
1097
1159
|
}, [colliderHandle]);
|
1098
1160
|
return /*#__PURE__*/React__default["default"].createElement("mesh", {
|
1099
|
-
ref: ref
|
1161
|
+
ref: ref,
|
1162
|
+
material: material
|
1100
1163
|
}, /*#__PURE__*/React__default["default"].createElement("primitive", {
|
1101
1164
|
object: geometry,
|
1102
1165
|
attach: "geometry"
|
1103
|
-
}), /*#__PURE__*/React__default["default"].createElement("meshBasicMaterial", {
|
1104
|
-
color: "red",
|
1105
|
-
wireframe: true
|
1106
1166
|
}));
|
1107
1167
|
});
|
1108
|
-
const Debug = (
|
1168
|
+
const Debug = ({
|
1169
|
+
color: _color = "red",
|
1170
|
+
sleepColor: _sleepColor = "blue"
|
1171
|
+
}) => {
|
1109
1172
|
const {
|
1110
1173
|
world
|
1111
1174
|
} = useRapier();
|
@@ -1121,7 +1184,9 @@ const Debug = () => {
|
|
1121
1184
|
});
|
1122
1185
|
return /*#__PURE__*/React__default["default"].createElement("group", null, colliders.map(handle => /*#__PURE__*/React__default["default"].createElement(DebugShape, {
|
1123
1186
|
key: handle,
|
1124
|
-
colliderHandle: handle
|
1187
|
+
colliderHandle: handle,
|
1188
|
+
color: _color,
|
1189
|
+
sleepColor: _sleepColor
|
1125
1190
|
})));
|
1126
1191
|
};
|
1127
1192
|
|
@@ -8,6 +8,7 @@ var useAsset = require('use-asset');
|
|
8
8
|
var fiber = require('@react-three/fiber');
|
9
9
|
var three = require('three');
|
10
10
|
var BufferGeometryUtils = require('three/examples/jsm/utils/BufferGeometryUtils');
|
11
|
+
var threeStdlib = require('three-stdlib');
|
11
12
|
|
12
13
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
13
14
|
|
@@ -74,11 +75,13 @@ const decomposeMatrix4 = m => {
|
|
74
75
|
};
|
75
76
|
};
|
76
77
|
const scaleColliderArgs = (shape, args, scale) => {
|
77
|
-
// Heightfield
|
78
|
-
const newArgs = args.slice();
|
78
|
+
const newArgs = args.slice(); // Heightfield uses a vector
|
79
79
|
|
80
80
|
if (shape === "heightfield") {
|
81
|
-
newArgs[3]
|
81
|
+
const s = newArgs[3];
|
82
|
+
s.x *= scale.x;
|
83
|
+
s.x *= scale.y;
|
84
|
+
s.x *= scale.z;
|
82
85
|
return newArgs;
|
83
86
|
} // Trimesh and convex scale the vertices
|
84
87
|
|
@@ -86,9 +89,10 @@ const scaleColliderArgs = (shape, args, scale) => {
|
|
86
89
|
if (shape === "trimesh" || shape === "convexHull") {
|
87
90
|
newArgs[0] = scaleVertices(newArgs[0], scale);
|
88
91
|
return newArgs;
|
89
|
-
}
|
92
|
+
} // Prepfill with some extra
|
93
|
+
|
90
94
|
|
91
|
-
const scaleArray = [scale.x, scale.y, scale.z];
|
95
|
+
const scaleArray = [scale.x, scale.y, scale.z, scale.x, scale.x];
|
92
96
|
return newArgs.map((arg, index) => scaleArray[index] * arg);
|
93
97
|
};
|
94
98
|
const createColliderFromOptions = ({
|
@@ -118,6 +122,10 @@ const createColliderFromOptions = ({
|
|
118
122
|
w: qRotation.w
|
119
123
|
}).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 : rapier3dCompat.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 : rapier3dCompat.CoefficientCombineRule.Average);
|
120
124
|
|
125
|
+
if (colliderShape === "heightfield") {
|
126
|
+
console.log(colliderDesc);
|
127
|
+
}
|
128
|
+
|
121
129
|
if (hasCollisionEvents) {
|
122
130
|
colliderDesc = colliderDesc.setActiveEvents(rapier3dCompat.ActiveEvents.COLLISION_EVENTS);
|
123
131
|
} // If any of the mass properties are specified, add mass properties
|
@@ -246,16 +254,14 @@ const colliderDescFromGeometry = (geometry, colliders, scale, hasCollisionEvents
|
|
246
254
|
var _g$index;
|
247
255
|
|
248
256
|
const clonedGeometry = geometry.index ? geometry.clone() : BufferGeometryUtils.mergeVertices(geometry);
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
desc = rapier3dCompat.ColliderDesc.trimesh(_g.attributes.position.array, (_g$index = _g.index) === null || _g$index === void 0 ? void 0 : _g$index.array);
|
257
|
+
const g = clonedGeometry.scale(scale.x, scale.y, scale.z);
|
258
|
+
desc = rapier3dCompat.ColliderDesc.trimesh(g.attributes.position.array, (_g$index = g.index) === null || _g$index === void 0 ? void 0 : _g$index.array);
|
253
259
|
}
|
254
260
|
break;
|
255
261
|
|
256
262
|
case "hull":
|
257
|
-
const g = geometry.clone().scale(scale.x, scale.y, scale.z);
|
258
263
|
{
|
264
|
+
const g = geometry.clone().scale(scale.x, scale.y, scale.z);
|
259
265
|
desc = rapier3dCompat.ColliderDesc.convexHull(g.attributes.position.array);
|
260
266
|
}
|
261
267
|
break;
|
@@ -572,7 +578,7 @@ const Physics = ({
|
|
572
578
|
state.isSleeping = rigidBody.isSleeping();
|
573
579
|
}
|
574
580
|
|
575
|
-
if (!rigidBody || rigidBody.isSleeping() ||
|
581
|
+
if (!rigidBody || rigidBody.isSleeping() || !state.setMatrix) {
|
576
582
|
return;
|
577
583
|
}
|
578
584
|
|
@@ -1022,6 +1028,17 @@ const geometryFromCollider = collider => {
|
|
1022
1028
|
return new three.BoxBufferGeometry(x * 2 + 0.01, y * 2 + 0.01, z * 2 + 0.01);
|
1023
1029
|
}
|
1024
1030
|
|
1031
|
+
case rapier3dCompat.ShapeType.RoundCuboid:
|
1032
|
+
{
|
1033
|
+
const {
|
1034
|
+
x,
|
1035
|
+
y,
|
1036
|
+
z
|
1037
|
+
} = collider.shape.halfExtents;
|
1038
|
+
const radius = collider.shape.borderRadius;
|
1039
|
+
return new threeStdlib.RoundedBoxGeometry(x * 2 + radius * 2, y * 2 + radius * 2, z * 2 + radius * 2, 8, radius);
|
1040
|
+
}
|
1041
|
+
|
1025
1042
|
case rapier3dCompat.ShapeType.Ball:
|
1026
1043
|
{
|
1027
1044
|
const r = collider.shape.radius;
|
@@ -1057,7 +1074,38 @@ const geometryFromCollider = collider => {
|
|
1057
1074
|
{
|
1058
1075
|
const r = collider.shape.radius;
|
1059
1076
|
const h = collider.shape.halfHeight;
|
1060
|
-
const g = new three.CylinderBufferGeometry(r, r, h);
|
1077
|
+
const g = new three.CylinderBufferGeometry(r, r, h * 2);
|
1078
|
+
return g;
|
1079
|
+
}
|
1080
|
+
|
1081
|
+
case rapier3dCompat.ShapeType.Capsule:
|
1082
|
+
{
|
1083
|
+
const r = collider.shape.radius;
|
1084
|
+
const h = collider.shape.halfHeight;
|
1085
|
+
const g = new three.CapsuleBufferGeometry(r, h * 2, 4, 8);
|
1086
|
+
return g;
|
1087
|
+
}
|
1088
|
+
|
1089
|
+
case rapier3dCompat.ShapeType.Cone:
|
1090
|
+
{
|
1091
|
+
const r = collider.shape.radius;
|
1092
|
+
const h = collider.shape.halfHeight;
|
1093
|
+
const g = new three.ConeBufferGeometry(r, h * 2, 16);
|
1094
|
+
return g;
|
1095
|
+
}
|
1096
|
+
|
1097
|
+
case rapier3dCompat.ShapeType.HeightField:
|
1098
|
+
{
|
1099
|
+
const rows = collider.shape.nrows;
|
1100
|
+
const cols = collider.shape.ncols;
|
1101
|
+
const heights = collider.shape.heights;
|
1102
|
+
const scale = collider.shape.scale;
|
1103
|
+
const g = new three.PlaneGeometry(scale.x, scale.z, cols, rows);
|
1104
|
+
const verts = g.attributes.position.array;
|
1105
|
+
verts.forEach((v, index) => verts[index * 3 + 2] = heights[index] * scale.y);
|
1106
|
+
g.scale(1, -1, 1);
|
1107
|
+
g.rotateX(-Math.PI / 2);
|
1108
|
+
g.rotateY(-Math.PI / 2);
|
1061
1109
|
return g;
|
1062
1110
|
}
|
1063
1111
|
}
|
@@ -1066,12 +1114,18 @@ const geometryFromCollider = collider => {
|
|
1066
1114
|
};
|
1067
1115
|
|
1068
1116
|
const DebugShape = /*#__PURE__*/React.memo(({
|
1069
|
-
colliderHandle
|
1117
|
+
colliderHandle,
|
1118
|
+
color,
|
1119
|
+
sleepColor
|
1070
1120
|
}) => {
|
1071
1121
|
const {
|
1072
1122
|
world
|
1073
1123
|
} = useRapier();
|
1074
1124
|
const ref = React.useRef(null);
|
1125
|
+
const [material] = React.useState(new three.MeshBasicMaterial({
|
1126
|
+
color,
|
1127
|
+
wireframe: true
|
1128
|
+
}));
|
1075
1129
|
fiber.useFrame(() => {
|
1076
1130
|
const collider = world.getCollider(colliderHandle);
|
1077
1131
|
|
@@ -1087,6 +1141,14 @@ const DebugShape = /*#__PURE__*/React.memo(({
|
|
1087
1141
|
y,
|
1088
1142
|
z
|
1089
1143
|
} = collider.translation();
|
1144
|
+
const parent = collider.parent();
|
1145
|
+
|
1146
|
+
if (parent !== null && parent !== void 0 && parent.isSleeping() || parent !== null && parent !== void 0 && parent.isFixed() || parent !== null && parent !== void 0 && parent.isKinematic()) {
|
1147
|
+
material.color = new three.Color(sleepColor);
|
1148
|
+
} else {
|
1149
|
+
material.color = new three.Color(color);
|
1150
|
+
}
|
1151
|
+
|
1090
1152
|
ref.current.position.set(x, y, z);
|
1091
1153
|
ref.current.rotation.setFromQuaternion(new three.Quaternion(rx, ry, rz, rw));
|
1092
1154
|
}
|
@@ -1096,16 +1158,17 @@ const DebugShape = /*#__PURE__*/React.memo(({
|
|
1096
1158
|
return geometryFromCollider(collider);
|
1097
1159
|
}, [colliderHandle]);
|
1098
1160
|
return /*#__PURE__*/React__default["default"].createElement("mesh", {
|
1099
|
-
ref: ref
|
1161
|
+
ref: ref,
|
1162
|
+
material: material
|
1100
1163
|
}, /*#__PURE__*/React__default["default"].createElement("primitive", {
|
1101
1164
|
object: geometry,
|
1102
1165
|
attach: "geometry"
|
1103
|
-
}), /*#__PURE__*/React__default["default"].createElement("meshBasicMaterial", {
|
1104
|
-
color: "red",
|
1105
|
-
wireframe: true
|
1106
1166
|
}));
|
1107
1167
|
});
|
1108
|
-
const Debug = (
|
1168
|
+
const Debug = ({
|
1169
|
+
color: _color = "red",
|
1170
|
+
sleepColor: _sleepColor = "blue"
|
1171
|
+
}) => {
|
1109
1172
|
const {
|
1110
1173
|
world
|
1111
1174
|
} = useRapier();
|
@@ -1121,7 +1184,9 @@ const Debug = () => {
|
|
1121
1184
|
});
|
1122
1185
|
return /*#__PURE__*/React__default["default"].createElement("group", null, colliders.map(handle => /*#__PURE__*/React__default["default"].createElement(DebugShape, {
|
1123
1186
|
key: handle,
|
1124
|
-
colliderHandle: handle
|
1187
|
+
colliderHandle: handle,
|
1188
|
+
color: _color,
|
1189
|
+
sleepColor: _sleepColor
|
1125
1190
|
})));
|
1126
1191
|
};
|
1127
1192
|
|
@@ -3,8 +3,9 @@ export { CoefficientCombineRule, Collider as RapierCollider, RigidBody as Rapier
|
|
3
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
7
|
import { mergeVertices } from 'three/examples/jsm/utils/BufferGeometryUtils';
|
8
|
+
import { RoundedBoxGeometry } from 'three-stdlib';
|
8
9
|
|
9
10
|
const _quaternion = new Quaternion();
|
10
11
|
const _euler = new Euler();
|
@@ -49,11 +50,13 @@ const decomposeMatrix4 = m => {
|
|
49
50
|
};
|
50
51
|
};
|
51
52
|
const scaleColliderArgs = (shape, args, scale) => {
|
52
|
-
// Heightfield
|
53
|
-
const newArgs = args.slice();
|
53
|
+
const newArgs = args.slice(); // Heightfield uses a vector
|
54
54
|
|
55
55
|
if (shape === "heightfield") {
|
56
|
-
newArgs[3]
|
56
|
+
const s = newArgs[3];
|
57
|
+
s.x *= scale.x;
|
58
|
+
s.x *= scale.y;
|
59
|
+
s.x *= scale.z;
|
57
60
|
return newArgs;
|
58
61
|
} // Trimesh and convex scale the vertices
|
59
62
|
|
@@ -61,9 +64,10 @@ const scaleColliderArgs = (shape, args, scale) => {
|
|
61
64
|
if (shape === "trimesh" || shape === "convexHull") {
|
62
65
|
newArgs[0] = scaleVertices(newArgs[0], scale);
|
63
66
|
return newArgs;
|
64
|
-
}
|
67
|
+
} // Prepfill with some extra
|
68
|
+
|
65
69
|
|
66
|
-
const scaleArray = [scale.x, scale.y, scale.z];
|
70
|
+
const scaleArray = [scale.x, scale.y, scale.z, scale.x, scale.x];
|
67
71
|
return newArgs.map((arg, index) => scaleArray[index] * arg);
|
68
72
|
};
|
69
73
|
const createColliderFromOptions = ({
|
@@ -93,6 +97,10 @@ const createColliderFromOptions = ({
|
|
93
97
|
w: qRotation.w
|
94
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);
|
95
99
|
|
100
|
+
if (colliderShape === "heightfield") {
|
101
|
+
console.log(colliderDesc);
|
102
|
+
}
|
103
|
+
|
96
104
|
if (hasCollisionEvents) {
|
97
105
|
colliderDesc = colliderDesc.setActiveEvents(ActiveEvents.COLLISION_EVENTS);
|
98
106
|
} // If any of the mass properties are specified, add mass properties
|
@@ -221,16 +229,14 @@ const colliderDescFromGeometry = (geometry, colliders, scale, hasCollisionEvents
|
|
221
229
|
var _g$index;
|
222
230
|
|
223
231
|
const clonedGeometry = geometry.index ? geometry.clone() : mergeVertices(geometry);
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
desc = ColliderDesc.trimesh(_g.attributes.position.array, (_g$index = _g.index) === null || _g$index === void 0 ? void 0 : _g$index.array);
|
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);
|
228
234
|
}
|
229
235
|
break;
|
230
236
|
|
231
237
|
case "hull":
|
232
|
-
const g = geometry.clone().scale(scale.x, scale.y, scale.z);
|
233
238
|
{
|
239
|
+
const g = geometry.clone().scale(scale.x, scale.y, scale.z);
|
234
240
|
desc = ColliderDesc.convexHull(g.attributes.position.array);
|
235
241
|
}
|
236
242
|
break;
|
@@ -547,7 +553,7 @@ const Physics = ({
|
|
547
553
|
state.isSleeping = rigidBody.isSleeping();
|
548
554
|
}
|
549
555
|
|
550
|
-
if (!rigidBody || rigidBody.isSleeping() ||
|
556
|
+
if (!rigidBody || rigidBody.isSleeping() || !state.setMatrix) {
|
551
557
|
return;
|
552
558
|
}
|
553
559
|
|
@@ -997,6 +1003,17 @@ const geometryFromCollider = collider => {
|
|
997
1003
|
return new BoxBufferGeometry(x * 2 + 0.01, y * 2 + 0.01, z * 2 + 0.01);
|
998
1004
|
}
|
999
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
|
+
|
1000
1017
|
case ShapeType.Ball:
|
1001
1018
|
{
|
1002
1019
|
const r = collider.shape.radius;
|
@@ -1032,7 +1049,38 @@ const geometryFromCollider = collider => {
|
|
1032
1049
|
{
|
1033
1050
|
const r = collider.shape.radius;
|
1034
1051
|
const h = collider.shape.halfHeight;
|
1035
|
-
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);
|
1036
1084
|
return g;
|
1037
1085
|
}
|
1038
1086
|
}
|
@@ -1041,12 +1089,18 @@ const geometryFromCollider = collider => {
|
|
1041
1089
|
};
|
1042
1090
|
|
1043
1091
|
const DebugShape = /*#__PURE__*/memo(({
|
1044
|
-
colliderHandle
|
1092
|
+
colliderHandle,
|
1093
|
+
color,
|
1094
|
+
sleepColor
|
1045
1095
|
}) => {
|
1046
1096
|
const {
|
1047
1097
|
world
|
1048
1098
|
} = useRapier();
|
1049
1099
|
const ref = useRef(null);
|
1100
|
+
const [material] = useState(new MeshBasicMaterial({
|
1101
|
+
color,
|
1102
|
+
wireframe: true
|
1103
|
+
}));
|
1050
1104
|
useFrame(() => {
|
1051
1105
|
const collider = world.getCollider(colliderHandle);
|
1052
1106
|
|
@@ -1062,6 +1116,14 @@ const DebugShape = /*#__PURE__*/memo(({
|
|
1062
1116
|
y,
|
1063
1117
|
z
|
1064
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
|
+
|
1065
1127
|
ref.current.position.set(x, y, z);
|
1066
1128
|
ref.current.rotation.setFromQuaternion(new Quaternion(rx, ry, rz, rw));
|
1067
1129
|
}
|
@@ -1071,16 +1133,17 @@ const DebugShape = /*#__PURE__*/memo(({
|
|
1071
1133
|
return geometryFromCollider(collider);
|
1072
1134
|
}, [colliderHandle]);
|
1073
1135
|
return /*#__PURE__*/React.createElement("mesh", {
|
1074
|
-
ref: ref
|
1136
|
+
ref: ref,
|
1137
|
+
material: material
|
1075
1138
|
}, /*#__PURE__*/React.createElement("primitive", {
|
1076
1139
|
object: geometry,
|
1077
1140
|
attach: "geometry"
|
1078
|
-
}), /*#__PURE__*/React.createElement("meshBasicMaterial", {
|
1079
|
-
color: "red",
|
1080
|
-
wireframe: true
|
1081
1141
|
}));
|
1082
1142
|
});
|
1083
|
-
const Debug = (
|
1143
|
+
const Debug = ({
|
1144
|
+
color: _color = "red",
|
1145
|
+
sleepColor: _sleepColor = "blue"
|
1146
|
+
}) => {
|
1084
1147
|
const {
|
1085
1148
|
world
|
1086
1149
|
} = useRapier();
|
@@ -1096,7 +1159,9 @@ const Debug = () => {
|
|
1096
1159
|
});
|
1097
1160
|
return /*#__PURE__*/React.createElement("group", null, colliders.map(handle => /*#__PURE__*/React.createElement(DebugShape, {
|
1098
1161
|
key: handle,
|
1099
|
-
colliderHandle: handle
|
1162
|
+
colliderHandle: handle,
|
1163
|
+
color: _color,
|
1164
|
+
sleepColor: _sleepColor
|
1100
1165
|
})));
|
1101
1166
|
};
|
1102
1167
|
|
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 />
|