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/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, Fragment } from 'react/jsx-runtime';
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, siteId, gripperId };
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 frameTime = 1 / 60 * speedRef.current;
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 (spec 1.1)
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(Fragment, { children: [
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