From c033a38334f17044c00e8f41c4ac2aa7b7e44838 Mon Sep 17 00:00:00 2001 From: TATP-233 Date: Sun, 6 Sep 2026 03:01:21 +0800 Subject: [PATCH] feat(issue-1514): wire Newton native ViewerGL playback (auto mode, docs, render extra) --- .../en/1-getting_started/2-installation.md | 5 ++- .../en/2-user_guide/3-backends/7-newton.md | 28 +++++++++++--- .../zh_CN/1-getting_started/2-installation.md | 4 +- .../zh_CN/2-user_guide/3-backends/7-newton.md | 24 +++++++++--- .../zh_CN/5-reference/5-support_matrix.md | 2 +- pyproject.toml | 8 ++++ scripts/tools/support_matrix.py | 11 ++++-- .../conf/ppo/task/g1_walk_flat/newton.yaml | 6 +-- .../conf/sac/task/g1_walk_flat/newton.yaml | 6 +-- .../locomotion/g1/test_g1_owner_contract.py | 3 ++ uv.lock | 37 ++++++++++++++++++- 11 files changed, 109 insertions(+), 25 deletions(-) diff --git a/docs/sphinx/source/en/1-getting_started/2-installation.md b/docs/sphinx/source/en/1-getting_started/2-installation.md index 311bfafb6..ba45c2925 100644 --- a/docs/sphinx/source/en/1-getting_started/2-installation.md +++ b/docs/sphinx/source/en/1-getting_started/2-installation.md @@ -165,10 +165,13 @@ uv sync --extra mujoco --extra motrix --extra mjwarp --extra genesis Newton is the exception: the `newton` extra pins the MuJoCo-Warp 3.11 line, which conflicts with the historical `mjwarp` / `mujoco` extras (declared as uv -`conflicts` in `pyproject.toml`). Keep it in a separate environment: +`conflicts` in `pyproject.toml`). Keep it in a separate environment; native +ViewerGL rendering (offline record + interactive) additionally needs the +`newton-render` extra: ```bash uv sync --extra newton +uv sync --extra newton --extra newton-render # when native rendering is needed ``` | Backend | Install path | Important prerequisites | diff --git a/docs/sphinx/source/en/2-user_guide/3-backends/7-newton.md b/docs/sphinx/source/en/2-user_guide/3-backends/7-newton.md index 689df5b49..b6eab26fd 100644 --- a/docs/sphinx/source/en/2-user_guide/3-backends/7-newton.md +++ b/docs/sphinx/source/en/2-user_guide/3-backends/7-newton.md @@ -16,8 +16,10 @@ registered for the `newton` backend), and the cross-backend contract audit algo trees (verdict TRANSFERABLE). Support levels: SAC is **Tested** — a full 5000-iteration training completed on 2026-09-06 on an RTX 4090 / torch 2.8.0+cu128 / newton 1.5.1 / mujoco-warp 3.11 (reward/mean 6.68 → -242.3, episode length → 983, ~43k steps/s, 4m25s wall), with record -playback validated on `model_5000.pt`; PPO remains **Configured** +242.3, episode length → 983, ~43k steps/s, 4m25s wall), with playback +validated on `model_5000.pt`: native ViewerGL offscreen record (800-frame +1280x720 mp4) and an interactive ViewerGL window smoke on a live X +display; PPO remains **Configured** (evidence limited to the owner configs, compose/contract checks, and fail-closed runtime/import boundaries; no training or playback claim yet). @@ -30,8 +32,12 @@ with the MuJoCo-Warp 3.11 / Warp 1.16 line: # In a source checkout: uv sync --extra newton +# Native ViewerGL rendering (offline record + interactive) additionally: +uv sync --extra newton --extra newton-render + # From PyPI: pip install "unilab[newton]" +pip install "unilab[newton,newton-render]" ``` The extra pins `newton==1.5.1`, `mujoco-warp==3.11.0`, `mujoco==3.11.0`, and @@ -84,9 +90,18 @@ as `env.*` fields in the owner YAML: ## Playback and Rendering -The Newton backend has no native UniLab viewer yet: the owner sets -`training.play_render_mode: record`, so playback takes the record/headless -path, and requesting a native interactive renderer fails closed. +The Newton backend renders natively through the upstream +`newton.viewer.ViewerGL` (unisim `newton-render` extra, `pyglet>=2.1.6,<3` ++ `imgui-bundle>=1.92.0`). The owner inherits the base config's +`training.play_render_mode: auto`: with a display, `auto` resolves to +`interactive` (the ViewerGL window); without one it resolves to `record` +(`ViewerGL(headless=True)` offscreen rendering to mp4). Without the render +dependencies, `record` falls back to the MuJoCo offline snapshot renderer +(the plan diagnostic reports `mujoco-snapshot` vs the native +`newton-viewer-gl`), while `interactive` fails closed when dependencies or +a display are missing. Headless offscreen rendering still needs an OpenGL +context: set `PYOPENGL_PLATFORM=egl` on display-less Linux hosts and +`PYOPENGL_PLATFORM=glx` under Wayland. ```bash uv run eval --algo ppo --task g1_walk_flat --sim newton \ @@ -104,7 +119,8 @@ than silently degrading: - **Runtime PD-gain randomization**: Newton currently rejects it, and the owner keeps `events.pd_gains: null` to stay fail-closed until the adapter adds the capability. -- **Native interactive rendering**: see Playback above. +- **Camera kwargs on the native render path**: the native ViewerGL path + ignores `camera_kwargs` (the MuJoCo snapshot path still honors them). ## Cross-Backend Migration (sim2sim) diff --git a/docs/sphinx/source/zh_CN/1-getting_started/2-installation.md b/docs/sphinx/source/zh_CN/1-getting_started/2-installation.md index 5ef54c0cd..b82b62fe1 100644 --- a/docs/sphinx/source/zh_CN/1-getting_started/2-installation.md +++ b/docs/sphinx/source/zh_CN/1-getting_started/2-installation.md @@ -149,10 +149,12 @@ uv sync --extra mujoco --extra motrix --extra mjwarp --extra genesis Newton 是例外:`newton` extra 钉定的 MuJoCo-Warp 3.11 版本线与历史 `mjwarp` / `mujoco` extra 互斥(`pyproject.toml` 的 uv `conflicts` 声明), -请为它单独建一个环境: +请为它单独建一个环境;原生 ViewerGL 渲染(离线 record + 交互式)另需 +`newton-render` extra: ```bash uv sync --extra newton +uv sync --extra newton --extra newton-render # 需要原生渲染时 ``` | 后端 | 安装路径 | 重要前置条件 | diff --git a/docs/sphinx/source/zh_CN/2-user_guide/3-backends/7-newton.md b/docs/sphinx/source/zh_CN/2-user_guide/3-backends/7-newton.md index e8e66c7a4..42744efa8 100644 --- a/docs/sphinx/source/zh_CN/2-user_guide/3-backends/7-newton.md +++ b/docs/sphinx/source/zh_CN/2-user_guide/3-backends/7-newton.md @@ -16,7 +16,9 @@ mujoco↔newton(结论 TRANSFERABLE)。支持等级:SAC 为 **Tested**— 2026-09-06 在 RTX 4090 / torch 2.8.0+cu128 / newton 1.5.1 / mujoco-warp 3.11 上完成完整 5000-iteration 训练(reward/mean 6.68 → 242.3, episode length → 983,约 43k steps/s,wall 4m25s),并对 -`model_5000.pt` 做了 record 回放验证;PPO 保持 **Configured**(现有 +`model_5000.pt` 完成回放验证:原生 ViewerGL 离屏 record(800 帧 +1280x720 mp4)与交互式 ViewerGL 窗口冒烟(真实 X display);PPO 保持 +**Configured**(现有 证据限于 owner 配置、compose/contract 检查和 fail-closed 的 runtime/import 边界,尚无训练或回放验证结论)。 @@ -29,8 +31,12 @@ MuJoCo-Warp 3.11 / Warp 1.16 系列: # 源码 checkout: uv sync --extra newton +# 原生 ViewerGL 渲染(离线 record + 交互式 interactive)另需: +uv sync --extra newton --extra newton-render + # 从 PyPI 安装: pip install "unilab[newton]" +pip install "unilab[newton,newton-render]" ``` 该 extra 精确钉定 `newton==1.5.1`、`mujoco-warp==3.11.0`、 @@ -79,9 +85,16 @@ Newton/MuJoCo-Warp 3.11 要求显式的设备与存储容量,对应 owner YAML ## Playback 与渲染 -Newton 后端尚无原生 UniLab viewer:owner 设置 -`training.play_render_mode: record`,回放走录制 / 无头路径;请求原生 -交互式渲染器会 fail-closed。 +Newton 后端通过上游 `newton.viewer.ViewerGL` 提供**原生渲染**(unisim +`newton-render` extra,`pyglet>=2.1.6,<3` + `imgui-bundle>=1.92.0`)。 +owner 继承 base 配置的 `training.play_render_mode: auto`:有显示时 +`auto` 解析为 `interactive`(ViewerGL 交互窗口),无显示时解析为 +`record`(`ViewerGL(headless=True)` 离屏渲染写 mp4)。未安装渲染依赖 +时 `record` 回退到 MuJoCo 离线快照渲染(plan 诊断中的 renderer 为 +`mujoco-snapshot`,原生路径为 `newton-viewer-gl`);`interactive` 在 +缺依赖或无显示时 fail-closed。headless 离屏渲染仍需 OpenGL context: +无显示服务器的 Linux 主机设 `PYOPENGL_PLATFORM=egl`,Wayland 设 +`PYOPENGL_PLATFORM=glx`。 ```bash uv run eval --algo ppo --task g1_walk_flat --sim newton \ @@ -97,7 +110,8 @@ uv run eval --algo sac --task g1_walk_flat --sim newton \ - **PD gain 运行时随机化**:Newton 当前拒绝该能力,owner 显式设置 `events.pd_gains: null` 保持 fail-closed,直到适配器补齐。 -- **原生交互式渲染**:见上文 Playback 一节。 +- **原生渲染路径的相机参数**:native ViewerGL 路径忽略 + `camera_kwargs`(MuJoCo 快照路径仍生效)。 ## 跨后端迁移(sim2sim) diff --git a/docs/sphinx/source/zh_CN/5-reference/5-support_matrix.md b/docs/sphinx/source/zh_CN/5-reference/5-support_matrix.md index 7ec5a6dab..621b3ed77 100644 --- a/docs/sphinx/source/zh_CN/5-reference/5-support_matrix.md +++ b/docs/sphinx/source/zh_CN/5-reference/5-support_matrix.md @@ -134,5 +134,5 @@ uv run scripts/generate_support_matrix.py --write - Validated isaacgym entrypoints are explicitly recorded in `_MAINTAINER_VALIDATED_ISAACGYM_ENTRYPOINT_TASKS` (real hardware via the external Python 3.8 worker runtime; not covered by repo CI). - Validated genesis entrypoints are explicitly recorded in `_MAINTAINER_VALIDATED_GENESIS_ENTRYPOINT_TASKS` (real hardware, genesis-world extra + CUDA; not covered by repo CI); near-risk coverage lives in `tests/base/test_genesis_backend.py` (fake runtime), `tests/base/test_genesis_runtime.py` (real-runtime slow lane), and the genesis env smoke in `tests/envs/locomotion/g1/test_g1_owner_contract.py`. - IsaacSim owner scope is intentionally not promoted to `Tested`; `_MAINTAINER_VALIDATED_ISAACSIM_ENTRYPOINT_TASKS` is empty until a maintainer records full training evidence. Rendering protocol coverage lives in `tests/base/test_isaacsim_backend.py`; it is not a substitute for successful real playback. -- `newton` is an isolated optional owner backed by Newton 1.5.1 and the MuJoCo-Warp 3.11 / Warp 1.16 line. Validated newton entrypoints are explicitly recorded in `_MAINTAINER_VALIDATED_NEWTON_ENTRYPOINT_TASKS` (real hardware, newton extra + CUDA; not covered by repo CI); remaining cells rely on the G1 PPO/SAC owner configs, compose/contract checks, and fail-closed runtime/import boundaries. +- `newton` is an isolated optional owner backed by Newton 1.5.1 and the MuJoCo-Warp 3.11 / Warp 1.16 line. Validated newton entrypoints are explicitly recorded in `_MAINTAINER_VALIDATED_NEWTON_ENTRYPOINT_TASKS` (real hardware, newton extra + CUDA; not covered by repo CI); remaining cells rely on the G1 PPO/SAC owner configs, compose/contract checks, and fail-closed runtime/import boundaries. Native ViewerGL playback (offscreen record + interactive) is wired through the unisim `newton-render` extra; without it, record falls back to the MuJoCo snapshot renderer and interactive stays fail-closed. diff --git a/pyproject.toml b/pyproject.toml index 04213d57a..1bfd7a469 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -145,6 +145,14 @@ newton = [ # dependency, so the extra carries it explicitly. "trimesh>=3.21.7", ] +newton-render = [ + # Native ViewerGL rendering for the newton backend (offline record and + # interactive playback). Install together with the newton extra; bounds + # mirror unisim-core's newton-render extra and newton's own examples + # extra. Headless record still needs an OpenGL context (EGL/GLX). + "pyglet>=2.1.6,<3", + "imgui-bundle>=1.92.0", +] motrix = ["motrixsim-core==0.8.2"] genesis = [ # Genesis imports as ``genesis`` and owns the GPU physics implementation; diff --git a/scripts/tools/support_matrix.py b/scripts/tools/support_matrix.py index 7f16aa901..d3a1ca5d7 100644 --- a/scripts/tools/support_matrix.py +++ b/scripts/tools/support_matrix.py @@ -65,9 +65,12 @@ # repo CI). sac_torch g1_walk_flat: full 5000-iteration training completed # on 2026-09-06 (RTX 4090, torch 2.8.0+cu128, newton 1.5.1, mujoco-warp # 3.11; reward/mean 6.68 -> 242.3, episode length -> 983, ~43k steps/s, -# 4m25s wall, run 2026-09-06_01-21-36_newton) plus record playback -# validation on model_5000.pt (800-frame MuJoCo snapshot render, walking -# gait confirmed). PPO remains ``Configured`` without runtime evidence. +# 4m25s wall, run 2026-09-06_01-21-36_newton). Playback validated the same +# day on model_5000.pt: native ViewerGL offscreen record (800-frame +# 1280x720 mp4 via ``newton-viewer-gl``) and an interactive ViewerGL window +# smoke on a live X display; the MuJoCo snapshot record path remains as the +# no-render-deps fallback. PPO remains ``Configured`` without runtime +# evidence. _MAINTAINER_VALIDATED_NEWTON_ENTRYPOINT_TASKS: frozenset[tuple[str, str]] = frozenset( { ("sac_torch", "g1_walk_flat"), @@ -433,7 +436,7 @@ def render_support_matrix(root: Path | None = None) -> str: "- Validated isaacgym entrypoints are explicitly recorded in `_MAINTAINER_VALIDATED_ISAACGYM_ENTRYPOINT_TASKS` (real hardware via the external Python 3.8 worker runtime; not covered by repo CI).", "- Validated genesis entrypoints are explicitly recorded in `_MAINTAINER_VALIDATED_GENESIS_ENTRYPOINT_TASKS` (real hardware, genesis-world extra + CUDA; not covered by repo CI); near-risk coverage lives in `tests/base/test_genesis_backend.py` (fake runtime), `tests/base/test_genesis_runtime.py` (real-runtime slow lane), and the genesis env smoke in `tests/envs/locomotion/g1/test_g1_owner_contract.py`.", "- IsaacSim owner scope is intentionally not promoted to `Tested`; `_MAINTAINER_VALIDATED_ISAACSIM_ENTRYPOINT_TASKS` is empty until a maintainer records full training evidence. Rendering protocol coverage lives in `tests/base/test_isaacsim_backend.py`; it is not a substitute for successful real playback.", - "- `newton` is an isolated optional owner backed by Newton 1.5.1 and the MuJoCo-Warp 3.11 / Warp 1.16 line. Validated newton entrypoints are explicitly recorded in `_MAINTAINER_VALIDATED_NEWTON_ENTRYPOINT_TASKS` (real hardware, newton extra + CUDA; not covered by repo CI); remaining cells rely on the G1 PPO/SAC owner configs, compose/contract checks, and fail-closed runtime/import boundaries.", + "- `newton` is an isolated optional owner backed by Newton 1.5.1 and the MuJoCo-Warp 3.11 / Warp 1.16 line. Validated newton entrypoints are explicitly recorded in `_MAINTAINER_VALIDATED_NEWTON_ENTRYPOINT_TASKS` (real hardware, newton extra + CUDA; not covered by repo CI); remaining cells rely on the G1 PPO/SAC owner configs, compose/contract checks, and fail-closed runtime/import boundaries. Native ViewerGL playback (offscreen record + interactive) is wired through the unisim `newton-render` extra; without it, record falls back to the MuJoCo snapshot renderer and interactive stays fail-closed.", ] ) return "\n".join(lines) diff --git a/src/unilab/conf/ppo/task/g1_walk_flat/newton.yaml b/src/unilab/conf/ppo/task/g1_walk_flat/newton.yaml index 4beacc8a8..c2bc66b86 100644 --- a/src/unilab/conf/ppo/task/g1_walk_flat/newton.yaml +++ b/src/unilab/conf/ppo/task/g1_walk_flat/newton.yaml @@ -10,9 +10,9 @@ defaults: training: task_name: G1WalkFlat sim_backend: newton - # Newton has no native UniLab viewer yet; eval uses the configured record / - # headless path and fails closed if a native renderer is requested. - play_render_mode: record + # Native ViewerGL rendering (offline record + interactive) is provided by + # the backend; playback inherits the base config's auto mode (interactive + # with a display, record otherwise). algo: num_envs: 2048 diff --git a/src/unilab/conf/sac/task/g1_walk_flat/newton.yaml b/src/unilab/conf/sac/task/g1_walk_flat/newton.yaml index 10b1177fa..977d39864 100644 --- a/src/unilab/conf/sac/task/g1_walk_flat/newton.yaml +++ b/src/unilab/conf/sac/task/g1_walk_flat/newton.yaml @@ -6,8 +6,9 @@ # capacities: a null newton_device is intentional — the process device binder # injects the rank-local CUDA device before materialization. Runtime PD gain # randomization is rejected by the backend, so pd_gains stays disabled. -# Newton has no native UniLab viewer yet; eval uses the configured record / -# headless path and fails closed if a native renderer is requested. +# Native ViewerGL rendering (offline record + interactive) is provided by the +# backend; playback inherits the base config's auto mode (interactive with a +# display, record otherwise). defaults: - /task/g1_walk_flat/base - _self_ @@ -15,7 +16,6 @@ defaults: training: task_name: G1WalkFlat sim_backend: newton - play_render_mode: record algo: num_envs: 2048 learning_starts: 10 diff --git a/tests/envs/locomotion/g1/test_g1_owner_contract.py b/tests/envs/locomotion/g1/test_g1_owner_contract.py index 558aadd66..eb0e1568b 100644 --- a/tests/envs/locomotion/g1/test_g1_owner_contract.py +++ b/tests/envs/locomotion/g1/test_g1_owner_contract.py @@ -586,6 +586,9 @@ def test_g1_owner_materializes_complete_plain_manager_cfg( assert env_cfg.newton_nconmax == 320 assert env_cfg.newton_njmax == 512 assert env_cfg.newton_capacity_check_steps == 1 + # Native ViewerGL rendering (interactive viewer + offscreen record) + # is supported; playback stays on the base config's auto mode. + assert hydra_cfg.training.play_render_mode == "auto" if backend == "isaacgym": assert env_cfg.isaacgym_device_id == 0 # Native rendering (viewer + camera-sensor record) is supported; diff --git a/uv.lock b/uv.lock index 6bc78dff3..11b509aad 100644 --- a/uv.lock +++ b/uv.lock @@ -1318,6 +1318,35 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2c/c6/fa760e12a2483469e2bf5058c5faff664acf66cadb4df2ad6205b016a73d/imageio_ffmpeg-0.6.0-py3-none-win_amd64.whl", hash = "sha256:02fa47c83703c37df6bfe4896aab339013f62bf02c5ebf2dce6da56af04ffc0a", size = 31246824, upload-time = "2025-01-16T21:34:28.6Z" }, ] +[[package]] +name = "imgui-bundle" +version = "1.92.900" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/47/ff477f7258baddf0c02bbcf6406099c7ed78ebd63f3b9cebce899e6cf79a/imgui_bundle-1.92.900.tar.gz", hash = "sha256:1476409b76c7f600d0da472aed87e96382444df50695280b3ed9acd5065cb6c2", size = 48942607, upload-time = "2026-08-14T15:03:28.167Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/29/adcc7c20b3b221d8ccb9cdef57c64b8bf65edfa47ca68d0b97d1df073c37/imgui_bundle-1.92.900-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:a48a77015376b92da6f1a8571d0cbedda2c08c04ba6cfb9c1041e63087e1bc0a", size = 10470836, upload-time = "2026-08-14T15:02:20.605Z" }, + { url = "https://files.pythonhosted.org/packages/9e/63/754f39d5883f9672e979d63f38bbd605ffbad6cf54204241112c9de0c24d/imgui_bundle-1.92.900-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:465a27bd3e47652d6775d7b2b82c44f5b5e335c1ebe9748d0f41508334f5bec5", size = 12436149, upload-time = "2026-08-14T15:02:22.988Z" }, + { url = "https://files.pythonhosted.org/packages/0d/2c/08614c47b9c3fcb3a43370eff61e1ee948359bd9ede9a4c52783f6201986/imgui_bundle-1.92.900-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a0a9cc025bf8eef19d8a44dbc9c588fb46a55d5ee83c039c4e09f928f609a710", size = 13566113, upload-time = "2026-08-14T15:02:29.185Z" }, + { url = "https://files.pythonhosted.org/packages/2a/da/2b5f2010262934994d9e856ff47e5d0068a817fa603658b6fc158bbae070/imgui_bundle-1.92.900-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:888648b11a74cdbd933d7937d546c2f69af2515cba1c4d542bcb3c7b435e5e41", size = 13491234, upload-time = "2026-08-14T15:02:31.309Z" }, + { url = "https://files.pythonhosted.org/packages/00/57/f93e27495ac8eb42a537b1f4ae7a1f2febeb0650f9358ee37271e533ddca/imgui_bundle-1.92.900-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:355df4c828705e64fbc6918bc9fae6fe0a2bd5915076187c70f6a98ba090e244", size = 14424930, upload-time = "2026-08-14T15:02:33.38Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c9/6542979fa31be264acfc29c1b327410ab1ad0731be411c002a2e0a865706/imgui_bundle-1.92.900-cp311-cp311-win_amd64.whl", hash = "sha256:d4ce5f75018359c296cda0fca0b7cba81dbec455a7af0efc5052d7a63a2ccaaf", size = 11414926, upload-time = "2026-08-14T15:02:35.834Z" }, + { url = "https://files.pythonhosted.org/packages/93/2c/aaa6fc7f5103d00b4912f8c7cabf9a2a115b2c9b26288a11a886f16e21e0/imgui_bundle-1.92.900-cp311-cp311-win_arm64.whl", hash = "sha256:992a566b9323e5ea56028eefca4573f4341922a436555950d0caa6256da6dd48", size = 11005607, upload-time = "2026-08-14T15:02:37.767Z" }, + { url = "https://files.pythonhosted.org/packages/d5/f5/65afb7315809d547579a0f887564948bffaa1e6dfc76d52225a8a91fa47f/imgui_bundle-1.92.900-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:a9ebef3f6a310e0c30b94bb7893c97727e85c12d829ea23fd39b3e5750fb22be", size = 10466178, upload-time = "2026-08-14T15:02:40.333Z" }, + { url = "https://files.pythonhosted.org/packages/59/87/c4411c33af69a76ea6652fac544974bf70d0f0af1564bdaa999832e27dbe/imgui_bundle-1.92.900-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:41432897d2ed5b7f5641434b644bef1cf81d163453d2ee2716715ca2e7e4f422", size = 12400792, upload-time = "2026-08-14T15:02:42.75Z" }, + { url = "https://files.pythonhosted.org/packages/77/e9/b688ff0c634302519345ee7b71d621bfb9f1ffd77339a40888d064f0456c/imgui_bundle-1.92.900-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:6a0134ee4e4e0f6884d91534cb394c822998ca9d8e79c42afc3b3163a55e2ee4", size = 13551616, upload-time = "2026-08-14T15:02:45.132Z" }, + { url = "https://files.pythonhosted.org/packages/09/fd/b6413aa238d384f9d5545cf52cd8b604b4ecaa4197ef62a8d640cfe27655/imgui_bundle-1.92.900-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a84d8c0efb49cde2e41c77be003b825e9f8145b38dfbbbc3123fe1687de4c780", size = 13454620, upload-time = "2026-08-14T15:02:47.4Z" }, + { url = "https://files.pythonhosted.org/packages/e0/da/64b451dec41d01b9b916e6ef6ccab960c989bef9639f37b12d9406d5d526/imgui_bundle-1.92.900-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:90d07764c532a124379bba32517f0afb18160015065a76ede48825098c5e13f3", size = 14408387, upload-time = "2026-08-14T15:02:49.907Z" }, + { url = "https://files.pythonhosted.org/packages/31/d6/be48072268fa3037ebe950525a637ad86b9b21c5317865933964f9d10c2b/imgui_bundle-1.92.900-cp312-cp312-win_amd64.whl", hash = "sha256:38d7a46fcda76bd221aafae58c1b80b53143304a6bda1d1782f917be3a851b0b", size = 11379834, upload-time = "2026-08-14T15:02:51.988Z" }, + { url = "https://files.pythonhosted.org/packages/35/21/b0f8c8b60fbd6d89f589a486dba70aac66506917b33e8950921ff466c64f/imgui_bundle-1.92.900-cp312-cp312-win_arm64.whl", hash = "sha256:5dd8bf63a2ffd32998021d68cd4249e5da5060d9f3b7e69dbd2ace5398606b59", size = 10986018, upload-time = "2026-08-14T15:02:54.467Z" }, + { url = "https://files.pythonhosted.org/packages/d0/b1/997a598fc0b9e4d7a786493e41d133e1be6bafa6246e344dcc2c5206b2ee/imgui_bundle-1.92.900-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:878ab97e631b06421538940b973ae45157e146787627c27a31c827c52e9dfc45", size = 10465494, upload-time = "2026-08-14T15:02:56.589Z" }, + { url = "https://files.pythonhosted.org/packages/e7/1d/60c31f347a6970399ec8c0ff636cac93778108ae1e800f8fae75465619bb/imgui_bundle-1.92.900-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:85cc0cd481455233670c0a7ab42dc1210a4c48d3c36bb83d4decf38730b964d9", size = 12400575, upload-time = "2026-08-14T15:02:58.465Z" }, + { url = "https://files.pythonhosted.org/packages/f9/65/0b3455db652cc8b85064292d4cd6d2ec828415d18bd709511672655aa978/imgui_bundle-1.92.900-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:04bbf81ff81d9b0fce55cc78522cea16b611642779861e3f42e8daae44d4037f", size = 13551340, upload-time = "2026-08-14T15:03:00.689Z" }, + { url = "https://files.pythonhosted.org/packages/b4/7f/33806aa5280ef05a4a34afc0db9765e88224ca7c0cf41f1dd2facc4e9169/imgui_bundle-1.92.900-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:37a45e09cd105c242497da7d1a37591c1993ab3614ffb9a0b3c74a7d1d5201fe", size = 13454360, upload-time = "2026-08-14T15:03:02.852Z" }, + { url = "https://files.pythonhosted.org/packages/27/ad/2557bde98d7172c99688626ec266912b2bebaa6e81eac79f874fe9a75ef6/imgui_bundle-1.92.900-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f6ebd02420860e0040bbd1f3f9b04c69b5ec1fc2b51704b97e52e4400644b303", size = 14408281, upload-time = "2026-08-14T15:03:04.928Z" }, + { url = "https://files.pythonhosted.org/packages/16/b6/7c274964ed0bb151c6397a82d302e0e5ee44db3501e07f6633d647116e43/imgui_bundle-1.92.900-cp313-cp313-win_amd64.whl", hash = "sha256:914c348555cb3b2f1bf11c1d4d6b94d88a3b7136dc31271edf284e06430ddb3e", size = 11379369, upload-time = "2026-08-14T15:03:07.175Z" }, + { url = "https://files.pythonhosted.org/packages/d2/13/f5004791bebb1b71e13a0b533a12bda4ddca32d3f2397ec4a607e4a0461f/imgui_bundle-1.92.900-cp313-cp313-win_arm64.whl", hash = "sha256:8a83c2d90ea3751f514f5f1a1e7a95c18f0cdbaa453dcb04dfcb63ce15456e77", size = 10985728, upload-time = "2026-08-14T15:03:09.433Z" }, +] + [[package]] name = "importlib-metadata" version = "9.0.0" @@ -5261,6 +5290,10 @@ newton = [ { name = "trimesh" }, { name = "warp-lang" }, ] +newton-render = [ + { name = "imgui-bundle" }, + { name = "pyglet" }, +] viser = [ { name = "trimesh" }, { name = "viser" }, @@ -5285,6 +5318,7 @@ requires-dist = [ { name = "hydra-core", specifier = ">=1.3" }, { name = "imageio" }, { name = "imageio-ffmpeg", specifier = ">=0.6.0" }, + { name = "imgui-bundle", marker = "extra == 'newton-render'", specifier = ">=1.92.0" }, { name = "lark", specifier = ">=1.3.1" }, { name = "mediapy" }, { name = "motrixsim-core", marker = "extra == 'motrix'", specifier = "==0.8.2" }, @@ -5303,6 +5337,7 @@ requires-dist = [ { name = "packaging" }, { name = "prettytable", specifier = ">=3.10" }, { name = "pybind11", marker = "extra == 'mujoco'", specifier = ">=2.12" }, + { name = "pyglet", marker = "extra == 'newton-render'", specifier = ">=2.1.6,<3" }, { name = "rich" }, { name = "rsl-rl-lib", specifier = ">=5.0.0" }, { name = "setuptools" }, @@ -5324,7 +5359,7 @@ requires-dist = [ { name = "warp-lang", marker = "extra == 'newton'", specifier = "==1.16.0" }, { name = "wheel", marker = "extra == 'mujoco'" }, ] -provides-extras = ["drake", "mujoco", "mjwarp", "newton", "motrix", "genesis", "viser"] +provides-extras = ["drake", "mujoco", "mjwarp", "newton", "newton-render", "motrix", "genesis", "viser"] [package.metadata.requires-dev] dev = [