mujoco-react 0.3.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +137 -62
- package/dist/index.d.ts +54 -54
- package/dist/index.js +47 -32
- package/dist/index.js.map +1 -1
- package/package.json +6 -4
- package/src/components/ContactMarkers.tsx +9 -5
- package/src/components/Debug.tsx +5 -3
- package/src/components/DragInteraction.tsx +4 -2
- package/src/components/FlexRenderer.tsx +3 -2
- package/src/components/SceneRenderer.tsx +5 -2
- package/src/components/TendonRenderer.tsx +3 -2
- package/src/core/MujocoCanvas.tsx +1 -5
- package/src/core/MujocoPhysics.tsx +79 -0
- package/src/core/MujocoSimProvider.tsx +3 -11
- package/src/core/SceneLoader.ts +2 -8
- package/src/index.ts +2 -0
- package/src/types.ts +0 -10
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import loadMujoco from 'mujoco-js';
|
|
2
2
|
import { createContext, forwardRef, useEffect, useContext, useState, useRef, useCallback, useMemo } from 'react';
|
|
3
|
-
import { jsx, jsxs
|
|
3
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
4
|
import { Canvas, useThree, useFrame } from '@react-three/fiber';
|
|
5
5
|
import * as THREE11 from 'three';
|
|
6
6
|
import { PivotControls } from '@react-three/drei';
|
|
@@ -225,8 +225,6 @@ async function loadScene(mujoco, config, onProgress) {
|
|
|
225
225
|
onProgress?.("Loading model...");
|
|
226
226
|
const mjModel = mujoco.MjModel.loadFromXML(`/working/${config.sceneFile}`);
|
|
227
227
|
const mjData = new mujoco.MjData(mjModel);
|
|
228
|
-
const siteId = findSiteByName(mjModel, config.tcpSiteName ?? "tcp");
|
|
229
|
-
const gripperId = findActuatorByName(mjModel, config.gripperActuatorName ?? "gripper");
|
|
230
228
|
if (config.homeJoints) {
|
|
231
229
|
const homeCount = Math.min(config.homeJoints.length, mjModel.nu);
|
|
232
230
|
for (let i = 0; i < homeCount; i++) {
|
|
@@ -238,7 +236,7 @@ async function loadScene(mujoco, config, onProgress) {
|
|
|
238
236
|
}
|
|
239
237
|
}
|
|
240
238
|
mujoco.mj_forward(mjModel, mjData);
|
|
241
|
-
return { mjModel, mjData
|
|
239
|
+
return { mjModel, mjData };
|
|
242
240
|
}
|
|
243
241
|
function scanDependencies(xmlString, currentFile, parser, downloaded, queue) {
|
|
244
242
|
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
|
|
@@ -372,7 +370,6 @@ function MujocoSimProvider({
|
|
|
372
370
|
substeps,
|
|
373
371
|
paused,
|
|
374
372
|
speed,
|
|
375
|
-
interpolate,
|
|
376
373
|
children
|
|
377
374
|
}) {
|
|
378
375
|
const { gl, camera } = useThree();
|
|
@@ -384,12 +381,8 @@ function MujocoSimProvider({
|
|
|
384
381
|
const pausedRef = useRef(paused ?? false);
|
|
385
382
|
const speedRef = useRef(speed ?? 1);
|
|
386
383
|
const substepsRef = useRef(substeps ?? 1);
|
|
387
|
-
const interpolateRef = useRef(interpolate ?? false);
|
|
388
384
|
const stepsToRunRef = useRef(0);
|
|
389
385
|
const loadGenRef = useRef(0);
|
|
390
|
-
useRef(null);
|
|
391
|
-
useRef(null);
|
|
392
|
-
useRef(0);
|
|
393
386
|
const onSelectionRef = useRef(onSelection);
|
|
394
387
|
onSelectionRef.current = onSelection;
|
|
395
388
|
const onStepRef = useRef(onStep);
|
|
@@ -407,9 +400,6 @@ function MujocoSimProvider({
|
|
|
407
400
|
useEffect(() => {
|
|
408
401
|
substepsRef.current = substeps ?? 1;
|
|
409
402
|
}, [substeps]);
|
|
410
|
-
useEffect(() => {
|
|
411
|
-
interpolateRef.current = interpolate ?? false;
|
|
412
|
-
}, [interpolate]);
|
|
413
403
|
useEffect(() => {
|
|
414
404
|
if (!gravity) return;
|
|
415
405
|
const model = mjModelRef.current;
|
|
@@ -477,7 +467,7 @@ function MujocoSimProvider({
|
|
|
477
467
|
}
|
|
478
468
|
}
|
|
479
469
|
}, [status]);
|
|
480
|
-
useFrame(() => {
|
|
470
|
+
useFrame((_state, delta) => {
|
|
481
471
|
const model = mjModelRef.current;
|
|
482
472
|
const data = mjDataRef.current;
|
|
483
473
|
if (!model || !data) return;
|
|
@@ -497,7 +487,8 @@ function MujocoSimProvider({
|
|
|
497
487
|
stepsToRunRef.current = 0;
|
|
498
488
|
} else {
|
|
499
489
|
const startSimTime = data.time;
|
|
500
|
-
const
|
|
490
|
+
const clampedDelta = Math.min(delta, 1 / 15);
|
|
491
|
+
const frameTime = clampedDelta * speedRef.current;
|
|
501
492
|
while (data.time - startSimTime < frameTime) {
|
|
502
493
|
for (let s = 0; s < numSubsteps; s++) {
|
|
503
494
|
mujoco.mj_step(model, data);
|
|
@@ -1113,15 +1104,12 @@ var MujocoCanvas = forwardRef(
|
|
|
1113
1104
|
onError,
|
|
1114
1105
|
onStep,
|
|
1115
1106
|
onSelection,
|
|
1116
|
-
// Declarative physics config
|
|
1107
|
+
// Declarative physics config
|
|
1117
1108
|
gravity,
|
|
1118
1109
|
timestep,
|
|
1119
1110
|
substeps,
|
|
1120
1111
|
paused,
|
|
1121
1112
|
speed,
|
|
1122
|
-
interpolate,
|
|
1123
|
-
gravityCompensation,
|
|
1124
|
-
mjcfLights,
|
|
1125
1113
|
children,
|
|
1126
1114
|
...canvasProps
|
|
1127
1115
|
}, ref) {
|
|
@@ -1149,12 +1137,34 @@ var MujocoCanvas = forwardRef(
|
|
|
1149
1137
|
substeps,
|
|
1150
1138
|
paused,
|
|
1151
1139
|
speed,
|
|
1152
|
-
interpolate,
|
|
1153
1140
|
children
|
|
1154
1141
|
}
|
|
1155
1142
|
) });
|
|
1156
1143
|
}
|
|
1157
1144
|
);
|
|
1145
|
+
var MujocoPhysics = forwardRef(
|
|
1146
|
+
function MujocoPhysics2({ onError, children, ...props }, ref) {
|
|
1147
|
+
const { mujoco, status: wasmStatus, error: wasmError } = useMujoco();
|
|
1148
|
+
useEffect(() => {
|
|
1149
|
+
if (wasmStatus === "error" && onError) {
|
|
1150
|
+
onError(new Error(wasmError ?? "WASM load failed"));
|
|
1151
|
+
}
|
|
1152
|
+
}, [wasmStatus, wasmError, onError]);
|
|
1153
|
+
if (wasmStatus === "error" || wasmStatus === "loading" || !mujoco) {
|
|
1154
|
+
return null;
|
|
1155
|
+
}
|
|
1156
|
+
return /* @__PURE__ */ jsx(
|
|
1157
|
+
MujocoSimProvider,
|
|
1158
|
+
{
|
|
1159
|
+
mujoco,
|
|
1160
|
+
apiRef: ref,
|
|
1161
|
+
onError,
|
|
1162
|
+
...props,
|
|
1163
|
+
children
|
|
1164
|
+
}
|
|
1165
|
+
);
|
|
1166
|
+
}
|
|
1167
|
+
);
|
|
1158
1168
|
function shallowEqual(a, b) {
|
|
1159
1169
|
const keysA = Object.keys(a);
|
|
1160
1170
|
const keysB = Object.keys(b);
|
|
@@ -1881,7 +1891,7 @@ var GeomBuilder = class {
|
|
|
1881
1891
|
return null;
|
|
1882
1892
|
}
|
|
1883
1893
|
};
|
|
1884
|
-
function SceneRenderer() {
|
|
1894
|
+
function SceneRenderer(props) {
|
|
1885
1895
|
const { mjModelRef, mjDataRef, mujocoRef, onSelectionRef, status } = useMujocoSim();
|
|
1886
1896
|
const groupRef = useRef(null);
|
|
1887
1897
|
const bodyRefs = useRef([]);
|
|
@@ -1938,8 +1948,10 @@ function SceneRenderer() {
|
|
|
1938
1948
|
return /* @__PURE__ */ jsx(
|
|
1939
1949
|
"group",
|
|
1940
1950
|
{
|
|
1951
|
+
...props,
|
|
1941
1952
|
ref: groupRef,
|
|
1942
1953
|
onDoubleClick: (e) => {
|
|
1954
|
+
if (typeof props.onDoubleClick === "function") props.onDoubleClick(e);
|
|
1943
1955
|
e.stopPropagation();
|
|
1944
1956
|
let obj = e.object;
|
|
1945
1957
|
while (obj && obj.userData.bodyID === void 0 && obj.parent) {
|
|
@@ -2057,7 +2069,8 @@ function ContactMarkers({
|
|
|
2057
2069
|
maxContacts = 100,
|
|
2058
2070
|
radius = 8e-3,
|
|
2059
2071
|
color = "#22d3ee",
|
|
2060
|
-
visible = true
|
|
2072
|
+
visible = true,
|
|
2073
|
+
...groupProps
|
|
2061
2074
|
} = {}) {
|
|
2062
2075
|
const { mjDataRef, status } = useMujocoSim();
|
|
2063
2076
|
const meshRef = useRef(null);
|
|
@@ -2085,10 +2098,10 @@ function ContactMarkers({
|
|
|
2085
2098
|
mesh.instanceMatrix.needsUpdate = true;
|
|
2086
2099
|
});
|
|
2087
2100
|
if (status !== "ready") return null;
|
|
2088
|
-
return /* @__PURE__ */ jsxs("instancedMesh", { ref: meshRef, args: [void 0, void 0, maxContacts], frustumCulled: false, renderOrder: 999, children: [
|
|
2101
|
+
return /* @__PURE__ */ jsx("group", { ...groupProps, children: /* @__PURE__ */ jsxs("instancedMesh", { ref: meshRef, args: [void 0, void 0, maxContacts], frustumCulled: false, renderOrder: 999, children: [
|
|
2089
2102
|
/* @__PURE__ */ jsx("sphereGeometry", { args: [radius, 8, 8] }),
|
|
2090
2103
|
/* @__PURE__ */ jsx("meshBasicMaterial", { color, depthTest: false })
|
|
2091
|
-
] });
|
|
2104
|
+
] }) });
|
|
2092
2105
|
}
|
|
2093
2106
|
var _force = new Float64Array(3);
|
|
2094
2107
|
var _torque = new Float64Array(3);
|
|
@@ -2100,7 +2113,8 @@ var _raycaster = new THREE11.Raycaster();
|
|
|
2100
2113
|
var _mouse = new THREE11.Vector2();
|
|
2101
2114
|
function DragInteraction({
|
|
2102
2115
|
stiffness = 250,
|
|
2103
|
-
showArrow = true
|
|
2116
|
+
showArrow = true,
|
|
2117
|
+
...groupProps
|
|
2104
2118
|
}) {
|
|
2105
2119
|
const { mjDataRef, mujocoRef, mjModelRef, status } = useMujocoSim();
|
|
2106
2120
|
const { gl, camera, scene, controls } = useThree();
|
|
@@ -2257,7 +2271,7 @@ function DragInteraction({
|
|
|
2257
2271
|
}
|
|
2258
2272
|
});
|
|
2259
2273
|
if (status !== "ready") return null;
|
|
2260
|
-
return /* @__PURE__ */ jsx("group", { ref: groupRef });
|
|
2274
|
+
return /* @__PURE__ */ jsx("group", { ...groupProps, ref: groupRef });
|
|
2261
2275
|
}
|
|
2262
2276
|
function useSceneLights(intensity = 1) {
|
|
2263
2277
|
const { mjModelRef, status } = useMujocoSim();
|
|
@@ -2378,7 +2392,8 @@ function Debug({
|
|
|
2378
2392
|
showContacts = false,
|
|
2379
2393
|
showCOM = false,
|
|
2380
2394
|
showInertia = false,
|
|
2381
|
-
showTendons = false
|
|
2395
|
+
showTendons = false,
|
|
2396
|
+
...groupProps
|
|
2382
2397
|
}) {
|
|
2383
2398
|
const { mjModelRef, mjDataRef, status } = useMujocoSim();
|
|
2384
2399
|
const { scene } = useThree();
|
|
@@ -2641,7 +2656,7 @@ function Debug({
|
|
|
2641
2656
|
}
|
|
2642
2657
|
});
|
|
2643
2658
|
if (status !== "ready") return null;
|
|
2644
|
-
return /* @__PURE__ */ jsxs(
|
|
2659
|
+
return /* @__PURE__ */ jsxs("group", { ...groupProps, children: [
|
|
2645
2660
|
/* @__PURE__ */ jsx("group", { ref: groupRef }),
|
|
2646
2661
|
showContacts && /* @__PURE__ */ jsx("group", { ref: contactGroupRef })
|
|
2647
2662
|
] });
|
|
@@ -2649,7 +2664,7 @@ function Debug({
|
|
|
2649
2664
|
var DEFAULT_TENDON_COLOR = new THREE11.Color(0.3, 0.3, 0.8);
|
|
2650
2665
|
var DEFAULT_TENDON_WIDTH = 2e-3;
|
|
2651
2666
|
new THREE11.Vector3();
|
|
2652
|
-
function TendonRenderer() {
|
|
2667
|
+
function TendonRenderer(props) {
|
|
2653
2668
|
const { mjModelRef, mjDataRef, status } = useMujocoSim();
|
|
2654
2669
|
const groupRef = useRef(null);
|
|
2655
2670
|
const meshesRef = useRef([]);
|
|
@@ -2751,9 +2766,9 @@ function TendonRenderer() {
|
|
|
2751
2766
|
}
|
|
2752
2767
|
});
|
|
2753
2768
|
if (status !== "ready") return null;
|
|
2754
|
-
return /* @__PURE__ */ jsx("group", { ref: groupRef });
|
|
2769
|
+
return /* @__PURE__ */ jsx("group", { ...props, ref: groupRef });
|
|
2755
2770
|
}
|
|
2756
|
-
function FlexRenderer() {
|
|
2771
|
+
function FlexRenderer(props) {
|
|
2757
2772
|
const { mjModelRef, mjDataRef, status } = useMujocoSim();
|
|
2758
2773
|
const groupRef = useRef(null);
|
|
2759
2774
|
const meshesRef = useRef([]);
|
|
@@ -2817,7 +2832,7 @@ function FlexRenderer() {
|
|
|
2817
2832
|
}
|
|
2818
2833
|
});
|
|
2819
2834
|
if (status !== "ready") return null;
|
|
2820
|
-
return /* @__PURE__ */ jsx("group", { ref: groupRef });
|
|
2835
|
+
return /* @__PURE__ */ jsx("group", { ...props, ref: groupRef });
|
|
2821
2836
|
}
|
|
2822
2837
|
var geomNameCacheByModel = /* @__PURE__ */ new WeakMap();
|
|
2823
2838
|
function getGeomNameCached(model, geomId) {
|
|
@@ -3889,6 +3904,6 @@ function useCameraAnimation() {
|
|
|
3889
3904
|
* useCameraAnimation — composable camera animation hook.
|
|
3890
3905
|
*/
|
|
3891
3906
|
|
|
3892
|
-
export { ContactListener, ContactMarkers, Debug, DragInteraction, FlexRenderer, IkController, IkGizmo, MujocoCanvas, MujocoProvider, MujocoSimProvider, SceneLights, SceneRenderer, SelectionHighlight, TendonRenderer, TrajectoryPlayer, createController, findActuatorByName, findBodyByName, findGeomByName, findJointByName, findKeyframeByName, findSensorByName, findSiteByName, findTendonByName, getContact, getName, loadScene, useActuators, useAfterPhysicsStep, useBeforePhysicsStep, useBodyState, useCameraAnimation, useContactEvents, useContacts, useCtrl, useCtrlNoise, useGamepad, useGravityCompensation, useIk, useJointState, useKeyboardTeleop, useMujoco, useMujocoSim, usePolicy, useSceneLights, useSelectionHighlight, useSensor, useSensors, useSitePosition, useTrajectoryPlayer, useTrajectoryRecorder, useVideoRecorder };
|
|
3907
|
+
export { ContactListener, ContactMarkers, Debug, DragInteraction, FlexRenderer, IkController, IkGizmo, MujocoCanvas, MujocoPhysics, MujocoProvider, MujocoSimProvider, SceneLights, SceneRenderer, SelectionHighlight, TendonRenderer, TrajectoryPlayer, createController, findActuatorByName, findBodyByName, findGeomByName, findJointByName, findKeyframeByName, findSensorByName, findSiteByName, findTendonByName, getContact, getName, loadScene, useActuators, useAfterPhysicsStep, useBeforePhysicsStep, useBodyState, useCameraAnimation, useContactEvents, useContacts, useCtrl, useCtrlNoise, useGamepad, useGravityCompensation, useIk, useJointState, useKeyboardTeleop, useMujoco, useMujocoSim, usePolicy, useSceneLights, useSelectionHighlight, useSensor, useSensors, useSitePosition, useTrajectoryPlayer, useTrajectoryRecorder, useVideoRecorder };
|
|
3893
3908
|
//# sourceMappingURL=index.js.map
|
|
3894
3909
|
//# sourceMappingURL=index.js.map
|