> ## Documentation Index
> Fetch the complete documentation index at: https://dadd.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Scene Management

> Runtime model loading and scene configuration

Methods for loading and swapping models at runtime.

## loadScene(newConfig)

Load a new model, replacing the current scene entirely.

```tsx theme={null}
await api.loadScene({
  src: "https://raw.githubusercontent.com/google-deepmind/mujoco_menagerie/main/universal_robots_ur5e/",
  sceneFile: "scene.xml",
  numArmJoints: 6,
  tcpSiteName: "tcp",
});
```

<ParamField body="newConfig" type="SceneConfig" required>
  New scene configuration. See [Loading Models](/loading-models) for all fields.
</ParamField>

**Returns:** `Promise<void>` — resolves when the new model is loaded and ready.

This method:

1. Fetches the new model files
2. Applies XML patches and injects scene objects
3. Compiles the model with `mj_loadXML`
4. Creates new model/data objects
5. Rebuilds the scene graph (SceneRenderer will re-render)
6. Fires the `onReady` callback with the updated API

## loadFromFiles(files, options?)

Load MJCF or URDF from browser-selected files. Folder uploads preserve paths from `webkitRelativePath`; flat uploads fall back to matching mesh/texture assets by basename.

```tsx theme={null}
import { useEffect, useRef } from "react";
import { useMujoco } from "mujoco-react";

function ModelUpload() {
  const sim = useMujoco();
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    inputRef.current?.setAttribute("webkitdirectory", "");
  }, []);

  return (
    <input
      ref={inputRef}
      type="file"
      multiple
      onChange={(event) => {
        if (sim.isReady && event.currentTarget.files) {
          sim.api.loadFromFiles(event.currentTarget.files);
        }
      }}
    />
  );
}
```

<ParamField body="files" type="FileList | File[]" required>
  Browser-selected MJCF/URDF files and referenced assets.
</ParamField>

<ParamField body="options" type="LoadFromFilesOptions">
  Optional `sceneFile`, `environmentFiles`, `homeJoints`, `xmlPatches`, `sceneObjects`, and `onReset` settings.
</ParamField>

## Composable Environments

Use `environmentFiles` when a robot should run inside a reusable MJCF environment. The loader merges the environment XML's assets and physics sections into the entry model before MuJoCo compiles it.

```tsx theme={null}
const config = {
  src: "/models/xlerobot/",
  sceneFile: "xlerobot.xml",
  environmentFiles: ["splats/tabletop/scene.xml"],
};
```

This works well with Gaussian splats: keep the `.spz` as a visual-only layer,
and add a paired `scene.xml` collision/physics layer only when the splat-backed
workflow needs contact geometry.

## addBody(body), removeBody(name), recompile(patches?)

Edit the current scene configuration and recompile through MuJoCo. This is a model reload, not an in-place mutation of compiled `mjModel` memory.

```tsx theme={null}
await api.addBody({
  name: "spawned_cube",
  type: "box",
  size: [0.03, 0.03, 0.03],
  position: [0.4, 0, 0.1],
  rgba: [1, 0, 0, 1],
  mass: 0.1,
  freejoint: true,
});

await api.removeBody("spawned_cube");

await api.recompile([
  {
    target: "scene.xml",
    replace: ['timestep="0.002"', 'timestep="0.001"'],
  },
]);
```

## Example: Model Switcher

```tsx theme={null}
function ModelSelector() {
  const { api } = useMujoco();
  const [loading, setLoading] = useState(false);

  const robots = [
    { src: "https://raw.githubusercontent.com/google-deepmind/mujoco_menagerie/main/franka_emika_panda/", label: "Franka Panda", joints: 7 },
    { src: "https://raw.githubusercontent.com/google-deepmind/mujoco_menagerie/main/universal_robots_ur5e/", label: "UR5e", joints: 6 },
    { src: "https://raw.githubusercontent.com/google-deepmind/mujoco_menagerie/main/kuka_iiwa_14/", label: "KUKA iiwa", joints: 7 },
  ];

  async function switchRobot(robot: typeof robots[0]) {
    setLoading(true);
    await api.loadScene({
      src: robot.src,
      sceneFile: "scene.xml",
      numArmJoints: robot.joints,
      tcpSiteName: "tcp",
    });
    setLoading(false);
  }

  return (
    <div>
      {robots.map(r => (
        <button key={r.label} onClick={() => switchRobot(r)} disabled={loading}>
          {r.label}
        </button>
      ))}
      {loading && <span>Loading...</span>}
    </div>
  );
}
```

## Utility Functions

These standalone functions are exported for advanced use cases (e.g., building custom loaders).

### getName(model, address)

Read a null-terminated C string from the WASM model's name buffer.

```tsx theme={null}
import { getName } from "mujoco-react";
const bodyName = getName(model, model.name_bodyadr[bodyId]);
```

### find\*ByName(model, name)

Look up element indices by name. All return `-1` if not found.

```tsx theme={null}
import {
  findBodyByName,
  findJointByName,
  findGeomByName,
  findSiteByName,
  findActuatorByName,
  findSensorByName,
  findTendonByName,
  findKeyframeByName,
} from "mujoco-react";

const bodyId = findBodyByName(model, "gripper");
const jointId = findJointByName(model, "joint1");
const siteId = findSiteByName(model, "tcp");
const actuatorId = findActuatorByName(model, "gripper");
```

### loadScene(mujoco, config, onProgress?)

The standalone scene loader function (used internally by the provider).

```tsx theme={null}
import { loadScene } from "mujoco-react";

const result = await loadScene(mujoco, config, (msg) => {
  console.log("Loading:", msg);
});
// result: { mjModel, mjData, siteId, gripperId }
```
