mujoco-react 10.7.0 → 10.8.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,5 +1,5 @@
1
- import { withContacts, getContact, captureCameraFrame, captureCameraFrameBlob, createCameraFrameCaptureSession, CAMERA_FRAME_CAPTURE_PRE_RENDER_USER_DATA_KEY, CAPTURE_EXCLUDE_KEY, createCaptureCamera, prepareCaptureCamera } from './chunk-EN55TTGH.js';
2
- export { CAMERA_FRAME_CAPTURE_PRE_RENDER_USER_DATA_KEY, CAMERA_FRAME_CAPTURE_RENDER_USER_DATA_KEY, CAPTURE_EXCLUDE_KEY, ModelActuators, ModelBodies, ModelCameras, ModelGeoms, ModelJoints, ModelKeyframes, ModelResources, ModelSensors, ModelSites, ScenarioLighting, SplatEnvironment, SplatEnvironmentReadinessStatus, VisualScenarioEffects, captureCameraFrame, captureCameraFrameBlob, captureCameraFrameTensor, createCameraFrameCaptureSession, createPairedSplatEnvironment, createSparkSplatViewerUrl, createSplatEnvironmentUserData, createSplatSceneConfig, createVisualScenarioExecutionContext, dataUrlToPolicyImageTensor, getContact, getScenarioBackground, getScenarioCameraPosition, getSplatEnvironmentReadiness, imageDataToPolicyImageTensor, pixelsToPolicyImageTensor, registerModelResources, renderCameraFrameToCanvas, useSplatEnvironment, useSplatSceneConfig, useVisualScenarioEffects, useVisualScenarioExecutionContext, withSplatEnvironment } from './chunk-EN55TTGH.js';
1
+ import { withContacts, getContact, captureCameraFrame, captureCameraFrameBlob, createCameraFrameCaptureSession, CAMERA_FRAME_CAPTURE_PRE_RENDER_USER_DATA_KEY, CAPTURE_EXCLUDE_KEY, createCaptureCamera, prepareCaptureCamera } from './chunk-5WFYM73E.js';
2
+ export { CAMERA_FRAME_CAPTURE_PRE_RENDER_USER_DATA_KEY, CAMERA_FRAME_CAPTURE_RENDER_USER_DATA_KEY, CAPTURE_EXCLUDE_KEY, ModelActuators, ModelBodies, ModelCameras, ModelGeoms, ModelJoints, ModelKeyframes, ModelResources, ModelSensors, ModelSites, ScenarioLighting, SplatEnvironment, SplatEnvironmentReadinessStatus, VisualScenarioEffects, captureCameraFrame, captureCameraFrameBlob, captureCameraFrameTensor, createCameraFrameCaptureSession, createPairedSplatEnvironment, createSparkSplatViewerUrl, createSplatEnvironmentUserData, createSplatSceneConfig, createVisualScenarioExecutionContext, dataUrlToPolicyImageTensor, getContact, getScenarioBackground, getScenarioCameraPosition, getSplatEnvironmentReadiness, imageDataToPolicyImageTensor, pixelsToPolicyImageTensor, registerModelResources, renderCameraFrameToCanvas, useSplatEnvironment, useSplatSceneConfig, useVisualScenarioEffects, useVisualScenarioExecutionContext, withSplatEnvironment } from './chunk-5WFYM73E.js';
3
3
  import loadMujoco from '@mujoco/mujoco';
4
4
  import defaultMujocoWasmUrl from '@mujoco/mujoco/mujoco.wasm?url';
5
5
  import { createContext, forwardRef, useRef, useEffect, useContext, useState, useCallback, useMemo, useLayoutEffect, useId } from 'react';
@@ -1001,14 +1001,34 @@ var GeomBuilder = class {
1001
1001
  const vNum = mjModel.mesh_vertnum[mId];
1002
1002
  const fAdr = mjModel.mesh_faceadr[mId];
1003
1003
  const fNum = mjModel.mesh_facenum[mId];
1004
- geo = new THREE11.BufferGeometry();
1005
- geo.setAttribute("position", new THREE11.Float32BufferAttribute(mjModel.mesh_vert.subarray(vAdr * 3, (vAdr + vNum) * 3), 3));
1006
- geo.setIndex(Array.from(mjModel.mesh_face.subarray(fAdr * 3, (fAdr + fNum) * 3)));
1007
- const smoothingTolerance = this.getMeshNormalSmoothingTolerance();
1008
- if (smoothingTolerance !== null) {
1009
- geo = mergeVertices(geo, smoothingTolerance);
1004
+ const tAdr = mjModel.mesh_texcoordadr?.[mId] ?? -1;
1005
+ if (map && tAdr >= 0 && mjModel.mesh_texcoord && mjModel.mesh_facetexcoord) {
1006
+ const corners = fNum * 3;
1007
+ const positions = new Float32Array(corners * 3);
1008
+ const uvs = new Float32Array(corners * 2);
1009
+ for (let c = 0; c < corners; c++) {
1010
+ const v = vAdr + mjModel.mesh_face[fAdr * 3 + c];
1011
+ positions[c * 3] = mjModel.mesh_vert[v * 3];
1012
+ positions[c * 3 + 1] = mjModel.mesh_vert[v * 3 + 1];
1013
+ positions[c * 3 + 2] = mjModel.mesh_vert[v * 3 + 2];
1014
+ const t = tAdr + mjModel.mesh_facetexcoord[fAdr * 3 + c];
1015
+ uvs[c * 2] = mjModel.mesh_texcoord[t * 2];
1016
+ uvs[c * 2 + 1] = 1 - mjModel.mesh_texcoord[t * 2 + 1];
1017
+ }
1018
+ geo = new THREE11.BufferGeometry();
1019
+ geo.setAttribute("position", new THREE11.Float32BufferAttribute(positions, 3));
1020
+ geo.setAttribute("uv", new THREE11.Float32BufferAttribute(uvs, 2));
1021
+ geo.computeVertexNormals();
1022
+ } else {
1023
+ geo = new THREE11.BufferGeometry();
1024
+ geo.setAttribute("position", new THREE11.Float32BufferAttribute(mjModel.mesh_vert.subarray(vAdr * 3, (vAdr + vNum) * 3), 3));
1025
+ geo.setIndex(Array.from(mjModel.mesh_face.subarray(fAdr * 3, (fAdr + fNum) * 3)));
1026
+ const smoothingTolerance = this.getMeshNormalSmoothingTolerance();
1027
+ if (smoothingTolerance !== null) {
1028
+ geo = mergeVertices(geo, smoothingTolerance);
1029
+ }
1030
+ geo.computeVertexNormals();
1010
1031
  }
1011
- geo.computeVertexNormals();
1012
1032
  }
1013
1033
  if (geo) {
1014
1034
  const isPlane = type === getVal(MG.mjGEOM_PLANE);
@@ -1051,6 +1071,7 @@ function SceneRenderer({ renderOptions, ...props }) {
1051
1071
  mujocoRef,
1052
1072
  onSelectionRef,
1053
1073
  hiddenBodiesRef,
1074
+ hiddenBodiesVersion,
1054
1075
  interpolateRef,
1055
1076
  interpolationStateRef,
1056
1077
  status
@@ -1059,6 +1080,7 @@ function SceneRenderer({ renderOptions, ...props }) {
1059
1080
  const bodyRefs = useRef([]);
1060
1081
  const prevModelRef = useRef(null);
1061
1082
  const prevRenderOptionsKeyRef = useRef(null);
1083
+ const prevHiddenVersionRef = useRef(null);
1062
1084
  const renderOptionsKey = getRenderOptionsKey(renderOptions);
1063
1085
  const geomBuilder = useMemo(() => {
1064
1086
  if (status !== "ready") return null;
@@ -1069,11 +1091,12 @@ function SceneRenderer({ renderOptions, ...props }) {
1069
1091
  const model = mjModelRef.current;
1070
1092
  const group = groupRef.current;
1071
1093
  if (!model || !group) return;
1072
- if (prevModelRef.current === model && prevRenderOptionsKeyRef.current === renderOptionsKey) {
1094
+ if (prevModelRef.current === model && prevRenderOptionsKeyRef.current === renderOptionsKey && prevHiddenVersionRef.current === hiddenBodiesVersion) {
1073
1095
  return;
1074
1096
  }
1075
1097
  prevModelRef.current = model;
1076
1098
  prevRenderOptionsKeyRef.current = renderOptionsKey;
1099
+ prevHiddenVersionRef.current = hiddenBodiesVersion;
1077
1100
  while (group.children.length > 0) {
1078
1101
  group.remove(group.children[0]);
1079
1102
  }
@@ -1094,7 +1117,7 @@ function SceneRenderer({ renderOptions, ...props }) {
1094
1117
  refs.push(bodyGroup);
1095
1118
  }
1096
1119
  bodyRefs.current = refs;
1097
- }, [status, geomBuilder, mjModelRef, renderOptionsKey]);
1120
+ }, [status, geomBuilder, mjModelRef, renderOptionsKey, hiddenBodiesRef, hiddenBodiesVersion]);
1098
1121
  const syncBodiesToData = useCallback(() => {
1099
1122
  const data = mjDataRef.current;
1100
1123
  if (!data) return;
@@ -2275,6 +2298,7 @@ function MujocoSimProvider({
2275
2298
  speed,
2276
2299
  interpolate,
2277
2300
  renderOptions,
2301
+ hiddenBodies,
2278
2302
  children
2279
2303
  }) {
2280
2304
  const { gl, camera, scene } = useThree();
@@ -2308,6 +2332,8 @@ function MujocoSimProvider({
2308
2332
  const errorRef = useRef(null);
2309
2333
  const bodyRegistryRef = useRef(/* @__PURE__ */ new Map());
2310
2334
  const hiddenBodiesRef = useRef(/* @__PURE__ */ new Set());
2335
+ const providedHiddenBodiesRef = useRef(new Set(hiddenBodies ?? []));
2336
+ const [hiddenBodiesVersion, setHiddenBodiesVersion] = useState(0);
2311
2337
  const bodyReloadTimerRef = useRef(null);
2312
2338
  configRef.current = config;
2313
2339
  mujocoRef.current = mujoco;
@@ -2329,15 +2355,37 @@ function MujocoSimProvider({
2329
2355
  if (!model?.opt) return;
2330
2356
  model.opt.timestep = timestep;
2331
2357
  }, [timestep]);
2358
+ const hiddenBodiesKey = (hiddenBodies ?? []).join("\0");
2359
+ useEffect(() => {
2360
+ const next = new Set(hiddenBodies ?? []);
2361
+ const prev = providedHiddenBodiesRef.current;
2362
+ let unchanged = next.size === prev.size;
2363
+ if (unchanged) {
2364
+ for (const name of next) {
2365
+ if (!prev.has(name)) {
2366
+ unchanged = false;
2367
+ break;
2368
+ }
2369
+ }
2370
+ }
2371
+ if (unchanged) return;
2372
+ providedHiddenBodiesRef.current = next;
2373
+ recomputeHiddenBodies();
2374
+ setHiddenBodiesVersion((v) => v + 1);
2375
+ }, [hiddenBodiesKey]);
2376
+ function recomputeHiddenBodies() {
2377
+ hiddenBodiesRef.current.clear();
2378
+ for (const [name, entry] of bodyRegistryRef.current) {
2379
+ if (entry.hasCustomChildren) hiddenBodiesRef.current.add(name);
2380
+ }
2381
+ for (const name of providedHiddenBodiesRef.current) hiddenBodiesRef.current.add(name);
2382
+ }
2332
2383
  function buildMergedConfig(baseConfig) {
2384
+ recomputeHiddenBodies();
2333
2385
  if (bodyRegistryRef.current.size === 0) return baseConfig;
2334
2386
  const registeredNames = new Set(bodyRegistryRef.current.keys());
2335
2387
  const baseObjects = (baseConfig.sceneObjects ?? []).filter((o) => !registeredNames.has(o.name));
2336
2388
  const registeredBodies = Array.from(bodyRegistryRef.current.values()).map((e) => e.definition);
2337
- hiddenBodiesRef.current.clear();
2338
- for (const [name, entry] of bodyRegistryRef.current) {
2339
- if (entry.hasCustomChildren) hiddenBodiesRef.current.add(name);
2340
- }
2341
2389
  return { ...baseConfig, sceneObjects: [...baseObjects, ...registeredBodies] };
2342
2390
  }
2343
2391
  useEffect(() => {
@@ -3555,10 +3603,11 @@ function MujocoSimProvider({
3555
3603
  errorRef,
3556
3604
  bodyRegistryRef,
3557
3605
  hiddenBodiesRef,
3606
+ hiddenBodiesVersion,
3558
3607
  requestBodyReload,
3559
3608
  status
3560
3609
  }),
3561
- [api, status, requestBodyReload]
3610
+ [api, status, requestBodyReload, hiddenBodiesVersion]
3562
3611
  );
3563
3612
  return /* @__PURE__ */ jsxs(MujocoSimContext.Provider, { value: contextValue, children: [
3564
3613
  /* @__PURE__ */ jsx(SceneRenderer, { renderOptions }),
@@ -3580,6 +3629,7 @@ var MujocoCanvas = forwardRef(
3580
3629
  speed,
3581
3630
  interpolate,
3582
3631
  renderOptions,
3632
+ hiddenBodies,
3583
3633
  loadingFallback,
3584
3634
  children,
3585
3635
  ...canvasProps
@@ -3615,6 +3665,7 @@ var MujocoCanvas = forwardRef(
3615
3665
  speed,
3616
3666
  interpolate,
3617
3667
  renderOptions,
3668
+ hiddenBodies,
3618
3669
  children
3619
3670
  }
3620
3671
  ) });
@@ -4058,7 +4109,16 @@ var useIkController = createControllerHook(
4058
4109
  const ikTargetRef = useRef(new THREE11.Group());
4059
4110
  const siteIdRef = useRef(-1);
4060
4111
  const controlGroupRef = useRef(null);
4061
- const genericIkRef = useRef(new GenericIK(mujocoRef.current));
4112
+ const genericIkRef = useRef(null);
4113
+ const genericIkModuleRef = useRef(null);
4114
+ const getGenericIk = useCallback(() => {
4115
+ const module = mujocoRef.current;
4116
+ if (!genericIkRef.current || genericIkModuleRef.current !== module) {
4117
+ genericIkRef.current = new GenericIK(module);
4118
+ genericIkModuleRef.current = module;
4119
+ }
4120
+ return genericIkRef.current;
4121
+ }, [mujocoRef]);
4062
4122
  const firstIkEnableRef = useRef(true);
4063
4123
  const needsInitialSync = useRef(true);
4064
4124
  const gizmoAnimRef = useRef({
@@ -4109,7 +4169,7 @@ var useIkController = createControllerHook(
4109
4169
  const data = mjDataRef.current;
4110
4170
  const controlGroup2 = controlGroupRef.current;
4111
4171
  if (!model || !data || !controlGroup2 || siteIdRef.current === -1) return null;
4112
- return genericIkRef.current.solve(
4172
+ return getGenericIk().solve(
4113
4173
  model,
4114
4174
  data,
4115
4175
  siteIdRef.current,
@@ -4128,7 +4188,7 @@ var useIkController = createControllerHook(
4128
4188
  }
4129
4189
  );
4130
4190
  },
4131
- [config, mjModelRef, mjDataRef]
4191
+ [config, mjModelRef, mjDataRef, getGenericIk]
4132
4192
  );
4133
4193
  const ikSolveFnRef = useRef(ikSolveFn);
4134
4194
  ikSolveFnRef.current = ikSolveFn;