mujoco-react 8.4.2 → 8.6.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 CHANGED
@@ -100,6 +100,58 @@ function ResetButton() {
100
100
  }
101
101
  ```
102
102
 
103
+ ## Map Controls to Joints
104
+
105
+ Use control groups when a robot's actuator order does not match a simple `qpos[0..n]` layout:
106
+
107
+ ```tsx
108
+ import { useRef } from "react";
109
+ import { resolveControlGroup, useBeforePhysicsStep } from "mujoco-react";
110
+ import type { ControlGroupInfo } from "mujoco-react";
111
+
112
+ function HoldTcpPose() {
113
+ const armRef = useRef<ControlGroupInfo | null>(null);
114
+
115
+ useBeforePhysicsStep((model, data) => {
116
+ armRef.current ??= resolveControlGroup(model, { siteName: "tcp" });
117
+ if (!armRef.current) return;
118
+
119
+ armRef.current.writeCtrl(data, armRef.current.readQpos(data));
120
+ });
121
+
122
+ return null;
123
+ }
124
+ ```
125
+
126
+ `resolveControlGroup()` accepts `{ siteName }`, `{ bodyName }`, `{ joints }`, or `{ actuators }`. Selectors can be a name, ordered name array, regex, or predicate.
127
+
128
+ ## Build Observations
129
+
130
+ Build policy-ready observation vectors from common MuJoCo state without hard-coding offsets:
131
+
132
+ ```tsx
133
+ import { buildObservation, useBeforePhysicsStep } from "mujoco-react";
134
+
135
+ function PolicyDriver() {
136
+ useBeforePhysicsStep((model, data) => {
137
+ const obs = buildObservation(model, data, {
138
+ qpos: true,
139
+ qvel: true,
140
+ ctrl: true,
141
+ sensors: ["imu_gyro", "imu_accel"],
142
+ sites: ["tcp"],
143
+ projectedGravity: "torso",
144
+ });
145
+
146
+ runPolicy(obs.values, obs.layout);
147
+ });
148
+
149
+ return null;
150
+ }
151
+ ```
152
+
153
+ Use `output: "float64"` when a downstream model expects double precision. Named resources are skipped when absent, so `obs.layout` is the source of truth for the current model.
154
+
103
155
  ## WebSocket Control
104
156
 
105
157
  Stream actuator commands over a WebSocket and send simulation state back. Use a schema validator such as Zod at this boundary because socket messages are untrusted app input (`npm install zod` for this example):
@@ -254,10 +306,30 @@ const gripperIk = useIkController({
254
306
 
255
307
  ## Type-Safe Resource Names
256
308
 
257
- Use TypeScript module augmentation to get autocomplete and type checking for actuator, sensor, body, joint, site, geom, and keyframe names:
309
+ Use the Vite plugin to generate TanStack-style declaration merging for actuator, sensor, body, joint, site, geom, and keyframe names:
258
310
 
259
311
  ```ts
260
- // e.g. in src/mujoco-register.d.ts
312
+ // vite.config.ts
313
+ import { defineConfig } from "vite";
314
+ import { mujocoReact } from "mujoco-react/vite";
315
+
316
+ export default defineConfig({
317
+ plugins: [
318
+ mujocoReact({
319
+ models: "models/panda/scene.xml",
320
+ }),
321
+ ],
322
+ });
323
+ ```
324
+
325
+ The plugin writes `src/mujoco-register.gen.d.ts` during dev and build. Commit that generated file:
326
+
327
+ ```ts
328
+ // src/mujoco-register.gen.d.ts
329
+ // Auto-generated by mujoco-react. Do not edit.
330
+
331
+ import "mujoco-react";
332
+
261
333
  declare module "mujoco-react" {
262
334
  interface Register {
263
335
  actuators: "joint1" | "joint2" | "joint3" | "gripper";
@@ -267,7 +339,13 @@ declare module "mujoco-react" {
267
339
  }
268
340
  ```
269
341
 
270
- Once declared, hooks like `useCtrl`, `useSensor`, `useBodyState`, and API methods like `setCtrl`, `applyForce`, `getSensorData` will only accept the declared names. When no `Register` augmentation is provided, all names fall back to `string`.
342
+ Once generated, hooks like `useCtrl`, `useSensor`, `useBodyState`, and API methods like `setCtrl`, `applyForce`, `getSensorData` will only accept the declared names. When no `Register` augmentation is present, names fall back to `string`.
343
+
344
+ Non-Vite projects can generate the same file with:
345
+
346
+ ```bash
347
+ npx mujoco-react codegen models/panda/scene.xml
348
+ ```
271
349
 
272
350
  ## Loading Models
273
351
 
@@ -292,7 +370,8 @@ const custom: SceneConfig = {
292
370
  ```ts
293
371
  interface SceneConfig {
294
372
  src: string; // Base URL for model files
295
- sceneFile: string; // Entry XML file, e.g. "scene.xml"
373
+ sceneFile: string; // Entry XML/URDF file, e.g. "scene.xml"
374
+ files?: File[]; // Local files for browser upload workflows
296
375
  sceneObjects?: SceneObject[]; // Objects injected into scene XML at load time
297
376
  homeJoints?: number[]; // Initial joint positions
298
377
  xmlPatches?: XmlPatch[]; // Patches applied to XML files during loading
@@ -300,6 +379,30 @@ interface SceneConfig {
300
379
  }
301
380
  ```
302
381
 
382
+ ### Local Files and URDF
383
+
384
+ Load browser-selected MJCF or URDF files directly. Folder uploads preserve `webkitRelativePath`, and flat uploads fall back to matching referenced mesh/texture assets by basename:
385
+
386
+ ```tsx
387
+ function ModelUpload() {
388
+ const sim = useMujoco();
389
+
390
+ return (
391
+ <input
392
+ type="file"
393
+ multiple
394
+ // @ts-expect-error Chromium/WebKit folder uploads
395
+ webkitdirectory=""
396
+ onChange={(event) => {
397
+ if (sim.isReady && event.currentTarget.files) {
398
+ sim.api.loadFromFiles(event.currentTarget.files);
399
+ }
400
+ }}
401
+ />
402
+ );
403
+ }
404
+ ```
405
+
303
406
  ### Adding Objects to Any Scene
304
407
 
305
408
  ```tsx
@@ -500,6 +603,10 @@ Renders tendons as tube geometry from wrap paths.
500
603
 
501
604
  Renders deformable flex bodies from `flexvert_xpos`.
502
605
 
606
+ ### `<InstancedGeomRenderer />`
607
+
608
+ Opt-in renderer for repeated compatible geoms. It batches matching geom shape/material signatures into Three.js `InstancedMesh` objects and syncs instance transforms from `data.geom_xpos` / `data.geom_xmat`.
609
+
503
610
  ### `<ContactListener />`
504
611
 
505
612
  Component wrapper for contact events:
@@ -655,13 +762,19 @@ useGamepad({
655
762
  Framework-agnostic decimation loop for RL policies:
656
763
 
657
764
  ```tsx
658
- const { step, isRunning } = usePolicy({
765
+ const obs = useObservation({ qpos: true, qvel: true, projectedGravity: "torso" });
766
+
767
+ const policy = usePolicy({
659
768
  frequency: 50,
660
- onObservation: (model, data) => buildObs(model, data),
769
+ onObservation: () => obs.readValues(),
661
770
  onAction: (action, model, data) => applyAction(action, data),
662
771
  });
663
772
  ```
664
773
 
774
+ ### `buildObservation(model, data, config)` / `useObservation(config)`
775
+
776
+ Build a flat `Float32Array` or `Float64Array` plus a layout map from qpos, qvel, ctrl, actuator activations, sensordata, named sensors, named site positions, and projected gravity.
777
+
665
778
  ### `useTrajectoryRecorder(config)` / `useTrajectoryPlayer(trajectory, config)`
666
779
 
667
780
  Record and play back simulation trajectories:
@@ -766,7 +879,11 @@ The full API object available via `ref` or `useMujoco()` (when `isReady`):
766
879
  | `setQpos(values)` / `getQpos()` | Direct qpos access |
767
880
  | `setQvel(values)` / `getQvel()` | Direct qvel access |
768
881
  | `setCtrl(nameOrValues, value?)` | Set control by name or batch |
769
- | `getCtrl(name?)` | Get control values |
882
+ | `getCtrl()` | Get all control values |
883
+ | `getControlMap()` | Map directly actuated scalar joints to qpos/dof/ctrl addresses |
884
+ | `getActuatedJoints()` | List scalar hinge/slide joints with matching actuators |
885
+ | `resolveControlGroup(selector)` | Resolve qpos/ctrl mapping from a site, body, joint selector, or actuator selector |
886
+ | `buildObservation(model, data, config)` | Build policy-ready observation vectors with layout metadata |
770
887
  | `applyKeyframe(nameOrIndex)` | Apply a keyframe |
771
888
  | `getKeyframeNames()` / `getKeyframeCount()` | Keyframe introspection |
772
889
 
@@ -799,6 +916,9 @@ The full API object available via `ref` or `useMujoco()` (when `isReady`):
799
916
  |--------|-------------|
800
917
  | `setGravity(g)` | Set gravity vector |
801
918
  | `setTimestep(dt)` | Set timestep |
919
+ | `addBody(body)` | Add a `SceneObject` and recompile the scene |
920
+ | `removeBody(name)` | Remove a generated `SceneObject` and recompile |
921
+ | `recompile(patches?)` | Recompile current scene, optionally appending XML patches |
802
922
  | `setBodyMass(name, mass)` | Domain randomization |
803
923
  | `setGeomFriction(name, friction)` | Domain randomization |
804
924
  | `setGeomSize(name, size)` | Domain randomization |
@@ -816,6 +936,7 @@ The full API object available via `ref` or `useMujoco()` (when `isReady`):
816
936
  | Method | Description |
817
937
  |--------|-------------|
818
938
  | `loadScene(newConfig)` | Runtime model swap |
939
+ | `loadFromFiles(files, options?)` | Load MJCF/URDF from a browser `FileList` |
819
940
 
820
941
  ## Guides
821
942
 
@@ -854,14 +975,7 @@ Features planned but not yet implemented:
854
975
 
855
976
  | Feature | Priority | Description |
856
977
  |---------|----------|-------------|
857
- | **User-uploaded model loading** | P2 | `loadFromFiles(FileList)` -- detect meshdir, write to VFS |
858
- | **URDF loading** | P2 | Load URDF models via MuJoCo's built-in URDF compiler |
859
- | **XML mutation / recompile** | P1 | `addBody()`, `removeBody()`, `recompile()` for runtime XML editing |
860
- | **Observation builder utilities** | P2 | Helpers for projected gravity, joint positions/velocities for RL |
861
- | **Physics interpolation** | P1 | Smooth rendering between physics ticks for very high refresh displays |
862
- | **Instanced geom rendering** | P2 | `<InstancedGeomRenderer />` for particle/granular sims |
863
978
  | **Web Worker physics** | P2 | Run `mj_step` off main thread via SharedArrayBuffer |
864
- | **Register codegen** | P2 | CLI to auto-generate `Register` type augmentation from MJCF XML |
865
979
 
866
980
  ### WASM Limitations (@mujoco/mujoco)
867
981
 
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ process.argv.splice(2, 0, 'codegen');
3
+ await import('./mujoco-react.mjs');
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env node
2
+ import { watch } from 'node:fs';
3
+ import path from 'node:path';
4
+ import { generateMujocoRegister } from '../dist/vite.js';
5
+
6
+ const usage = `
7
+ Usage:
8
+ mujoco-react codegen <scene.xml> [...more.xml] [--out src/mujoco-register.gen.d.ts] [--watch]
9
+
10
+ Vite users usually do not need this command. Prefer:
11
+
12
+ import { mujocoReact } from "mujoco-react/vite";
13
+
14
+ export default defineConfig({
15
+ plugins: [mujocoReact({ models: "models/panda/scene.xml" })],
16
+ });
17
+ `;
18
+
19
+ const args = process.argv.slice(2);
20
+ const command = args[0];
21
+
22
+ if (!command || command === '--help' || command === '-h') {
23
+ console.log(usage.trim());
24
+ process.exit(command ? 0 : 1);
25
+ }
26
+
27
+ if (command !== 'codegen') {
28
+ console.error(`Unknown command: ${command}`);
29
+ console.error(usage.trim());
30
+ process.exit(1);
31
+ }
32
+
33
+ const commandArgs = args.slice(1);
34
+ const out = valueAfter(commandArgs, '--out') ?? 'src/mujoco-register.gen.d.ts';
35
+ const moduleName = valueAfter(commandArgs, '--module') ?? 'mujoco-react';
36
+ const shouldWatch = commandArgs.includes('--watch');
37
+ const models = commandArgs.filter((arg, index) => {
38
+ if (arg.startsWith('--')) return false;
39
+ const previous = commandArgs[index - 1];
40
+ return previous !== '--out' && previous !== '--module';
41
+ });
42
+
43
+ if (!models.length) {
44
+ console.error(usage.trim());
45
+ process.exit(1);
46
+ }
47
+
48
+ let watchedFiles = [];
49
+ await generate();
50
+
51
+ if (shouldWatch) {
52
+ console.log('[mujoco-react] watching model files...');
53
+ let timer;
54
+ const refreshWatchers = () => {
55
+ for (const file of watchedFiles) {
56
+ watch(file, { persistent: true }, () => {
57
+ clearTimeout(timer);
58
+ timer = setTimeout(() => {
59
+ generate().catch((error) => {
60
+ console.error('[mujoco-react] register generation failed');
61
+ console.error(error);
62
+ });
63
+ }, 50);
64
+ });
65
+ }
66
+ };
67
+ refreshWatchers();
68
+ }
69
+
70
+ async function generate() {
71
+ const result = await generateMujocoRegister({
72
+ models,
73
+ out,
74
+ moduleName,
75
+ root: process.cwd(),
76
+ });
77
+ watchedFiles = result.files;
78
+ const total = Object.values(result.counts).reduce((sum, count) => sum + count, 0);
79
+ console.log(`[mujoco-react] generated ${path.relative(process.cwd(), result.out)} (${total} names)`);
80
+ }
81
+
82
+ function valueAfter(values, flag) {
83
+ const index = values.indexOf(flag);
84
+ if (index === -1) return undefined;
85
+ return values[index + 1];
86
+ }
package/dist/index.d.ts CHANGED
@@ -275,11 +275,22 @@ interface XmlPatch {
275
275
  injectAfter?: string;
276
276
  replace?: [string, string];
277
277
  }
278
+ type LocalMujocoFile = File;
279
+ interface LoadFromFilesOptions {
280
+ /** Entry MJCF/URDF file. Inferred from scene.xml, model.xml, robot.xml, or the first XML/URDF file when omitted. */
281
+ sceneFile?: string;
282
+ homeJoints?: number[];
283
+ xmlPatches?: XmlPatch[];
284
+ sceneObjects?: SceneObject[];
285
+ onReset?: (model: MujocoModel, data: MujocoData) => void;
286
+ }
278
287
  interface SceneConfig {
279
288
  /** Base URL for fetching model files. The loader fetches `src + sceneFile` and follows dependencies. */
280
289
  src: string;
281
- /** Entry MJCF XML file name, e.g. 'scene.xml'. */
290
+ /** Entry MJCF XML or URDF file name, e.g. 'scene.xml' or 'robot.urdf'. */
282
291
  sceneFile: string;
292
+ /** Browser-selected files for local MJCF/URDF loading. Preserves webkitRelativePath when available. */
293
+ files?: readonly LocalMujocoFile[];
283
294
  sceneObjects?: SceneObject[];
284
295
  homeJoints?: number[];
285
296
  xmlPatches?: XmlPatch[];
@@ -477,6 +488,44 @@ interface PolicyConfig {
477
488
  onObservation: (model: MujocoModel, data: MujocoData) => Float32Array | Float64Array | number[];
478
489
  onAction: (action: Float32Array | Float64Array | number[], model: MujocoModel, data: MujocoData) => void;
479
490
  }
491
+ type ObservationOutput = 'float32' | 'float64';
492
+ interface ObservationConfig {
493
+ /** Include scalar simulation time. */
494
+ time?: boolean;
495
+ /** Include all qpos values. */
496
+ qpos?: boolean;
497
+ /** Include all qvel values. */
498
+ qvel?: boolean;
499
+ /** Include all ctrl values. */
500
+ ctrl?: boolean;
501
+ /** Include all actuator activation values. */
502
+ act?: boolean;
503
+ /** Include all raw sensordata values. */
504
+ sensordata?: boolean;
505
+ /** Include named sensor values in the configured order. */
506
+ sensors?: readonly Sensors[];
507
+ /** Include named site world positions in the configured order. */
508
+ sites?: readonly Sites[];
509
+ /** Include world gravity projected into each named body's local frame. */
510
+ projectedGravity?: Bodies | readonly Bodies[];
511
+ /** Output array type. Defaults to Float32Array. */
512
+ output?: ObservationOutput;
513
+ }
514
+ interface ObservationLayoutItem {
515
+ name: string;
516
+ start: number;
517
+ size: number;
518
+ }
519
+ interface ObservationResult {
520
+ values: Float32Array | Float64Array;
521
+ layout: ObservationLayoutItem[];
522
+ }
523
+ interface ObservationHandle {
524
+ /** Read a fresh observation from the current live MuJoCo model/data refs. */
525
+ read(): ObservationResult;
526
+ /** Read just the vector values for policy inference. */
527
+ readValues(): Float32Array | Float64Array;
528
+ }
480
529
  interface DebugProps {
481
530
  showGeoms?: boolean;
482
531
  showSites?: boolean;
@@ -572,6 +621,10 @@ interface MujocoSimAPI {
572
621
  getKeyframeNames(): string[];
573
622
  getKeyframeCount(): number;
574
623
  loadScene(newConfig: SceneConfig): Promise<void>;
624
+ loadFromFiles(files: FileList | readonly LocalMujocoFile[], options?: LoadFromFilesOptions): Promise<void>;
625
+ addBody(body: SceneObject): Promise<void>;
626
+ removeBody(name: Bodies): Promise<void>;
627
+ recompile(patches?: XmlPatch[]): Promise<void>;
575
628
  getCanvasSnapshot(width?: number, height?: number, mimeType?: string): string;
576
629
  project2DTo3D(x: number, y: number, cameraPos: THREE.Vector3, lookAt: THREE.Vector3): {
577
630
  point: THREE.Vector3;
@@ -595,6 +648,7 @@ type MujocoCanvasProps = Omit<CanvasProps, 'onError'> & {
595
648
  substeps?: number;
596
649
  paused?: boolean;
597
650
  speed?: number;
651
+ interpolate?: boolean;
598
652
  };
599
653
  interface SitePositionResult {
600
654
  position: React__default.RefObject<THREE.Vector3>;
@@ -706,6 +760,8 @@ interface MujocoPhysicsProps {
706
760
  paused?: boolean;
707
761
  /** Simulation speed multiplier. */
708
762
  speed?: number;
763
+ /** Interpolate rendered body poses between fixed physics steps. */
764
+ interpolate?: boolean;
709
765
  children: React.ReactNode;
710
766
  }
711
767
  /**
@@ -773,9 +829,10 @@ interface MujocoSimProviderProps {
773
829
  substeps?: number;
774
830
  paused?: boolean;
775
831
  speed?: number;
832
+ interpolate?: boolean;
776
833
  children: React.ReactNode;
777
834
  }
778
- declare function MujocoSimProvider({ mujoco, config, apiRef: externalApiRef, onReady, onError, onStep, onSelection, gravity, timestep, substeps, paused, speed, children, }: MujocoSimProviderProps): react_jsx_runtime.JSX.Element;
835
+ declare function MujocoSimProvider({ mujoco, config, apiRef: externalApiRef, onReady, onError, onStep, onSelection, gravity, timestep, substeps, paused, speed, interpolate, children, }: MujocoSimProviderProps): react_jsx_runtime.JSX.Element;
779
836
 
780
837
  /**
781
838
  * @license
@@ -831,6 +888,19 @@ interface LoadResult {
831
888
  */
832
889
  declare function loadScene(mujoco: MujocoModule, config: SceneConfig, onProgress?: (msg: string) => void): Promise<LoadResult>;
833
890
 
891
+ /**
892
+ * @license
893
+ * SPDX-License-Identifier: Apache-2.0
894
+ */
895
+
896
+ /**
897
+ * Build a flat observation vector plus a layout map from live MuJoCo state.
898
+ *
899
+ * Missing named resources are skipped. The returned layout is the source of
900
+ * truth for the vector produced from the current model.
901
+ */
902
+ declare function buildObservation(model: MujocoModel, data: MujocoData, config: ObservationConfig): ObservationResult;
903
+
834
904
  /**
835
905
  * @license
836
906
  * SPDX-License-Identifier: Apache-2.0
@@ -992,6 +1062,20 @@ declare function TendonRenderer(props: Omit<ThreeElements['group'], 'ref'>): rea
992
1062
  */
993
1063
  declare function FlexRenderer(props: Omit<ThreeElements['group'], 'ref'>): react_jsx_runtime.JSX.Element | null;
994
1064
 
1065
+ interface InstancedGeomRendererProps extends Omit<ThreeElements['group'], 'ref'> {
1066
+ /** Only render geoms from this MuJoCo geom group. */
1067
+ geomGroup?: number;
1068
+ /** Predicate for selecting geoms. */
1069
+ filter?: (geom: GeomInfo) => boolean;
1070
+ /** Optional material override for every instanced batch. */
1071
+ material?: THREE.Material;
1072
+ /** Hide or show the instanced batches. */
1073
+ visible?: boolean;
1074
+ castShadow?: boolean;
1075
+ receiveShadow?: boolean;
1076
+ }
1077
+ declare function InstancedGeomRenderer({ geomGroup, filter, material, visible, castShadow, receiveShadow, ...groupProps }?: InstancedGeomRendererProps): react_jsx_runtime.JSX.Element | null;
1078
+
995
1079
  /**
996
1080
  * @license
997
1081
  * SPDX-License-Identifier: Apache-2.0
@@ -1182,6 +1266,19 @@ declare function usePolicy(config: PolicyConfig): {
1182
1266
  readonly lastObservation: Float64Array<ArrayBufferLike> | Float32Array<ArrayBufferLike> | number[] | null;
1183
1267
  };
1184
1268
 
1269
+ /**
1270
+ * @license
1271
+ * SPDX-License-Identifier: Apache-2.0
1272
+ */
1273
+
1274
+ /**
1275
+ * Live observation reader for policy loops and telemetry.
1276
+ *
1277
+ * The handle is stable; call `read()` inside callbacks to sample the latest
1278
+ * MuJoCo model/data state without forcing React renders.
1279
+ */
1280
+ declare function useObservation(config: ObservationConfig): ObservationHandle;
1281
+
1185
1282
  /**
1186
1283
  * @license
1187
1284
  * SPDX-License-Identifier: Apache-2.0
@@ -1386,4 +1483,4 @@ interface CameraAnimationAPI {
1386
1483
  */
1387
1484
  declare function useCameraAnimation(): CameraAnimationAPI;
1388
1485
 
1389
- export { type ActuatedJointInfo, type ActuatorInfo, type Actuators, type Bodies, Body, type BodyInfo, type BodyProps, type BodyStateResult, type CameraAnimationAPI, type ContactInfo, ContactListener, type ContactListenerProps, ContactMarkers, type ControlGroupInfo, type ControlGroupSelector, type ControlJointInfo, type ControllerComponent, type ControllerOptions, type CtrlHandle, Debug, type DebugProps, DragInteraction, type DragInteractionProps, FlexRenderer, type GeomInfo, type Geoms, type IKSolveFn, type IkConfig, type IkContextValue, IkGizmo, type IkGizmoProps, type JointInfo, type JointStateResult, type Joints, type KeyBinding, type KeyboardTeleopConfig, type Keyframes, type ModelOptions, MujocoCanvas, type MujocoCanvasProps, type MujocoContact, type MujocoContactArray, type MujocoContextValue, type MujocoData, type MujocoLoader, type MujocoLoaderOptions, type MujocoModel, type MujocoModule, MujocoPhysics, type MujocoPhysicsProps, MujocoProvider, type MujocoProviderProps, type MujocoSimAPI, MujocoSimProvider, type MujocoWasmVariant, type PhysicsConfig, type PhysicsStepCallback, type PlaybackState, type PolicyConfig, type RayHit, type Register, type ResourceSelector, type SceneConfig, SceneLights, type SceneLightsProps, type SceneMarker, type SceneObject, type SensorHandle, type SensorInfo, type SensorResult, type Sensors, type SiteInfo, type SitePositionResult, type Sites, type StateSnapshot, TendonRenderer, type TrajectoryData, type TrajectoryFrame, type TrajectoryInput, TrajectoryPlayer, type TrajectoryPlayerProps, type XmlPatch, createContiguousControlGroup, createController, createControllerHook, findActuatorByName, findBodyByName, findGeomByName, findJointByName, findKeyframeByName, findSensorByName, findSiteByName, findTendonByName, getActuatedJoints, getContact, getControlMap, getName, loadScene, resolveControlGroup, useActuators, useAfterPhysicsStep, useBeforePhysicsStep, useBodyMeshes, useBodyState, useCameraAnimation, useContactEvents, useContacts, useCtrl, useCtrlNoise, useGamepad, useGravityCompensation, useIkController, useJointState, useKeyboardTeleop, useMujoco, useMujocoWasm, usePolicy, useSceneLights, useSelectionHighlight, useSensor, useSensors, useSitePosition, useTrajectoryPlayer, useTrajectoryRecorder, useVideoRecorder };
1486
+ export { type ActuatedJointInfo, type ActuatorInfo, type Actuators, type Bodies, Body, type BodyInfo, type BodyProps, type BodyStateResult, type CameraAnimationAPI, type ContactInfo, ContactListener, type ContactListenerProps, ContactMarkers, type ControlGroupInfo, type ControlGroupSelector, type ControlJointInfo, type ControllerComponent, type ControllerOptions, type CtrlHandle, Debug, type DebugProps, DragInteraction, type DragInteractionProps, FlexRenderer, type GeomInfo, type Geoms, type IKSolveFn, type IkConfig, type IkContextValue, IkGizmo, type IkGizmoProps, InstancedGeomRenderer, type JointInfo, type JointStateResult, type Joints, type KeyBinding, type KeyboardTeleopConfig, type Keyframes, type ModelOptions, MujocoCanvas, type MujocoCanvasProps, type MujocoContact, type MujocoContactArray, type MujocoContextValue, type MujocoData, type MujocoLoader, type MujocoLoaderOptions, type MujocoModel, type MujocoModule, MujocoPhysics, type MujocoPhysicsProps, MujocoProvider, type MujocoProviderProps, type MujocoSimAPI, MujocoSimProvider, type MujocoWasmVariant, type ObservationConfig, type ObservationHandle, type ObservationLayoutItem, type ObservationOutput, type ObservationResult, type PhysicsConfig, type PhysicsStepCallback, type PlaybackState, type PolicyConfig, type RayHit, type Register, type ResourceSelector, type SceneConfig, SceneLights, type SceneLightsProps, type SceneMarker, type SceneObject, type SensorHandle, type SensorInfo, type SensorResult, type Sensors, type SiteInfo, type SitePositionResult, type Sites, type StateSnapshot, TendonRenderer, type TrajectoryData, type TrajectoryFrame, type TrajectoryInput, TrajectoryPlayer, type TrajectoryPlayerProps, type XmlPatch, buildObservation, createContiguousControlGroup, createController, createControllerHook, findActuatorByName, findBodyByName, findGeomByName, findJointByName, findKeyframeByName, findSensorByName, findSiteByName, findTendonByName, getActuatedJoints, getContact, getControlMap, getName, loadScene, resolveControlGroup, useActuators, useAfterPhysicsStep, useBeforePhysicsStep, useBodyMeshes, useBodyState, useCameraAnimation, useContactEvents, useContacts, useCtrl, useCtrlNoise, useGamepad, useGravityCompensation, useIkController, useJointState, useKeyboardTeleop, useMujoco, useMujocoWasm, useObservation, usePolicy, useSceneLights, useSelectionHighlight, useSensor, useSensors, useSitePosition, useTrajectoryPlayer, useTrajectoryRecorder, useVideoRecorder };