A web-based 3D viewer for robot models — URDF, MJCF (MuJoCo), Xacro, and USD — built on Three.js and Vite. Everything runs in the browser; nothing is uploaded.
This fork ships with a curated set of robots bundled in the page, so it loads a robot on startup with no drag-drop needed, and includes the tooling used to prepare that dataset (xacro flattening + convex-hull "neutralization").
https://vklemm.github.io/generic-robot-viewer/
On load it auto-displays AliengoZ1 (neutralized) and offers A1, AliengoZ1, and R1 in the preset switcher, in both their neutralized (convex-hull) and original-mesh forms.
Note: USD viewing is unavailable on the hosted site — it needs
SharedArrayBuffer(cross-origin isolation / COOP+COEP headers) that GitHub Pages can't set. URDF, MJCF, and Xacro work everywhere. To use USD, run locally (pnpm devsets the headers).
- View URDF / MJCF / Xacro / USD robots with meshes (DAE/STL/OBJ/glTF/PLY) and textures.
- Interactive joint controls, model tree, link/joint inspection, and a measurement tool.
- Robot presets: a curated, editable list with a startup default, stored in
localStorageand exportable/importable as JSON. Built-in presets are seeded on first run. - Auto-load on startup from a bundled asset manifest — no drag-drop required (drag-drop a folder still works for ad-hoc models).
- Multi-robot folders resolve correctly (directory-scoped mesh resolution avoids cross-robot mesh collisions).
- Grid toggle, transparent PNG export, EN / 中文 UI.
Requires Node 18+ and pnpm.
pnpm install
pnpm dev # http://localhost:3000 (auto-loads the bundled robots)
pnpm build # production build into dist/ (runs the manifest step first)
pnpm preview # serve the production build locallygeneric-robot-viewer/
├── src/ # app source (Three.js viewer, loaders, UI)
│ ├── config/defaultPresets.js # built-in presets + startup default
│ ├── controllers/FileHandler.js # drag-drop + loadFromManifest() autoloader
│ └── controllers/PresetManager.js
├── public/assets/ # DEPLOYED bundle (curated subset, shipped to Pages)
│ ├── robots/<pkg>/... # original-mesh versions of the preset robots
│ ├── robots_neutralized/<pkg>/... # convex-hull versions of the preset robots
│ └── manifest.json # generated list the autoloader fetches
├── assets/ # FULL dataset (source of truth, not deployed)
│ ├── robots/ # 24 robot packages (originals)
│ └── robots_neutralized/ # convex-hull "neutralized" output for all of them
└── tools/ # dataset tooling (Python + Node)
├── neutralize_urdf.py # replace visual meshes with convex hulls
├── flatten_xacro.py # flatten a ROS xacro to plain URDF, ROS-free
└── gen_asset_manifest.mjs # regenerate public/assets/manifest.json
Only public/assets/ is bundled into the deployed site (keeping it well under the GitHub
Pages 1 GB limit). The full assets/ dataset is committed as the source of truth but not
served — browse it locally by dragging a folder onto the viewer.
Bundle a robot for autoload: copy its package into public/assets/robots/<pkg> (and, if
neutralized, public/assets/robots_neutralized/<pkg>), then regenerate the manifest:
pnpm manifest # or: node tools/gen_asset_manifest.mjsAdd a preset for it in src/config/defaultPresets.js (path must match the manifest entry).
Neutralize meshes (replace detailed visuals with convex hulls; collision geometry is left intact) for the whole dataset:
python3 tools/neutralize_urdf.py \
--input-root assets/robots \
--output-root assets/robots_neutralized \
--granularity per-mesh # or per-linkRequires pip install trimesh lxml numpy scipy. The script honors COLLADA <unit meter>
so non-metre .dae meshes hull at the correct scale.
Flatten a xacro-only robot to URDF (no ROS install needed) before neutralizing:
python3 tools/flatten_xacro.py path/to/robot.xacro \
-o assets/robots/<pkg>/urdf/<name>.urdf \
--root assets/robots --self-contained --arg DEBUG=falseRequires pip install xacro rospkg. --self-contained copies referenced meshes + textures
into the package and rewrites package:// references to be self-referential.
Pushing to main triggers .github/workflows/deploy-pages.yml, which runs pnpm build and
publishes dist/ to GitHub Pages. The build copies public/assets/ (the curated subset)
into dist/; the full assets/ dataset is not shipped.
Apache-2.0. Forked from fan-ziqi/robot_viewer; see LICENSE.
