Skip to content

Commit 21a2e7c

Browse files
matthewtrepteisaaclab-bot[bot]
authored andcommitted
Fix Newton GL Pause Rendering desync and document Rerun Play/Pause limitation (#7506)
## Summary - Fixed the Newton GL visualizer's "Pause Rendering" button not reflecting the paused state after pressing `Space`. Both controls now read/write the same underlying `_paused` flag, so the button label and `is_rendering_paused()` stay in sync regardless of whether rendering was paused via the button or the keyboard shortcut. Also clarified the on-screen control hint from "Space - Pause/Resume" to "Space - Pause/Resume Rendering". - Documented that the Rerun visualizer's native Play/Pause timeline controls do not work while visualizing a live simulation/training run (they only scrub already-logged `.rrd` recordings). Isaac Lab's own **Pause Rendering** / **Reset Episode** ImGui controls should be used instead for the live view. ## Release backport - [x] <!-- backport-active-release --> Backport this pull request to the active release branch after it merges into `develop` ## Test plan - [x] `uv run isaaclab -f` (ruff, ruff format, rst checks, changelog fragment check) — all passed - [x] `uv run python tools/changelog/cli.py check develop` — passed - [x] `uv run --extra test python -m pytest source/isaaclab_visualizers/test/test_newton_adapter.py -v` — 51/51 passed, including new regression test `test_newton_gl_viewer_rendering_pause_state_stays_in_sync_with_space_key` (verified it fails without the fix, passes with it) - [x] Manually verified live in the Newton GL visualizer window: Space now flips the Pause/Resume Rendering button label immediately, matching a direct click (cherry picked from commit c96b25f)
1 parent 7cba60f commit 21a2e7c

4 files changed

Lines changed: 78 additions & 7 deletions

File tree

docs/source/overview/core-concepts/visualization.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,15 @@ the num of environments can be overwritten and decreased using ``--num_envs``:
758758
The FPS control in the Rerun visualizer UI may not affect the visualization frame rate in all configurations.
759759

760760

761+
**Rerun Visualizer Play/Pause Timeline Controls**
762+
763+
The native Play/Pause timeline controls in the Rerun visualizer UI do not work while visualizing a live
764+
simulation or training run. They are hidden by default, but Rerun's dock panel UI can still be used to reveal
765+
them; when revealed, clicking them has no effect. Use Isaac Lab's own **Pause Rendering** / **Reset Episode**
766+
controls (ImGui sidebar, under **IsaacLab Controls**) to control the live view instead. The timeline controls
767+
are only meaningful when replaying a saved ``.rrd`` recording (see above).
768+
769+
761770
**Newton Contact Visualization**
762771

763772
Newton's native ``Show Contacts`` view can show all contacts from the Newton physics contact buffer. When running
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Fixed
2+
^^^^^
3+
4+
* Fixed the Newton GL visualizer's "Pause Rendering" button not reflecting the paused
5+
state after pressing :kbd:`Space`. Both controls now toggle the same underlying flag, so
6+
the button label and :meth:`~isaaclab_visualizers.newton.newton_visualizer.NewtonViewerGL.is_rendering_paused`
7+
stay in sync regardless of whether rendering was paused via the button or the keyboard shortcut.
8+
Also clarified the on-screen control hint from "Space - Pause/Resume" to "Space - Pause/Resume
9+
Rendering".

source/isaaclab_visualizers/isaaclab_visualizers/newton/newton_visualizer.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ def _render_left_panel(_g=gui):
467467
imgui.text("Ctrl + Middle Click - Dolly")
468468
imgui.text("Scroll - Dolly")
469469
imgui.text("Ctrl + Scroll - FOV zoom")
470-
imgui.text("Space - Pause/Resume")
470+
imgui.text("Space - Pause/Resume Rendering")
471471
imgui.text(". - Step one frame (when paused)")
472472
imgui.text("H - Toggle UI")
473473
imgui.text("F - Frame camera around model")
@@ -487,11 +487,13 @@ def _render_training_controls(self, imgui):
487487

488488
# Pause/Resume Rendering is not exposed on RTX: stopping end_frame() would
489489
# freeze the imgui, and OVRTX naturally converges when the scene is paused.
490+
# ``self._paused`` (not a separately tracked flag) is the single source of truth here
491+
# because the Newton viewer's own Space key handler toggles it directly, bypassing this
492+
# button; mirroring a separate flag would let the button state drift out of sync with Space.
490493
if not isinstance(self, NewtonViewerRTX):
491-
rendering_label = "Resume Rendering" if self._paused_rendering else "Pause Rendering"
494+
rendering_label = "Resume Rendering" if self._paused else "Pause Rendering"
492495
if imgui.button(rendering_label):
493-
self._paused_rendering = not self._paused_rendering
494-
self._paused = self._paused_rendering
496+
self._paused = not self._paused
495497

496498
if imgui.button("Reset Episode"):
497499
self._reset_requested = True
@@ -733,7 +735,6 @@ def __init__(self, *args, metadata: dict | None = None, update_frequency: int =
733735
"""
734736
super().__init__(*args, **kwargs)
735737
self._paused_training = False
736-
self._paused_rendering = False
737738
self._reset_requested = False
738739
self._metadata = metadata or {}
739740
self._update_frequency = update_frequency
@@ -763,8 +764,12 @@ def is_training_paused(self) -> bool:
763764
return self._paused_training
764765

765766
def is_rendering_paused(self) -> bool:
766-
"""Return whether rendering is paused by viewer controls."""
767-
return self._paused_rendering
767+
"""Return whether rendering is paused by viewer controls.
768+
769+
Mirrors ``self._paused`` directly since the Newton viewer's Space key handler toggles it
770+
in-place, outside the Isaac Lab "Pause Rendering" button.
771+
"""
772+
return self._paused
768773

769774
def on_key_press(self, symbol, modifiers):
770775
"""Forward key presses unless UI is currently capturing input."""

source/isaaclab_visualizers/test/test_newton_adapter.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,54 @@ def test_newton_viewer_camera_speed_setter_validates(monkeypatch):
292292
viewer.camera_speed = -1.0
293293

294294

295+
class _FakeTrainingControlsImgui:
296+
"""Minimal imgui double that drives ``_render_training_controls`` by label."""
297+
298+
def __init__(self, clicked_label: str | None = None):
299+
self._clicked_label = clicked_label
300+
301+
def button(self, label):
302+
return label == self._clicked_label
303+
304+
def text(self, _text):
305+
pass
306+
307+
def slider_int(self, _label, value, _min_value, _max_value, _format):
308+
return False, value
309+
310+
def is_item_hovered(self):
311+
return False
312+
313+
def set_tooltip(self, _text):
314+
pass
315+
316+
317+
def test_newton_gl_viewer_rendering_pause_state_stays_in_sync_with_space_key():
318+
"""Space toggles ``_paused`` directly (Newton's own key handler); the "Pause Rendering"
319+
button and ``is_rendering_paused()`` must reflect that instead of a separately tracked flag,
320+
or the UI desyncs from the actual paused state that gates rendering.
321+
"""
322+
viewer = NewtonViewerGL.__new__(NewtonViewerGL)
323+
viewer._paused = False
324+
viewer._paused_training = False
325+
viewer._reset_requested = False
326+
viewer._update_frequency = 1
327+
328+
assert viewer.is_rendering_paused() is False
329+
330+
# Simulate Newton's own Space key handler (newton/_src/viewer/viewer_gui.py), which
331+
# toggles ``_paused`` directly and bypasses the Isaac Lab "Pause Rendering" button.
332+
viewer._paused = not viewer._paused
333+
334+
assert viewer.is_rendering_paused() is True
335+
viewer._render_training_controls(_FakeTrainingControlsImgui()) # must not raise: no click
336+
337+
# The button must read the post-Space state and toggle it back correctly.
338+
resume_click = _FakeTrainingControlsImgui(clicked_label="Resume Rendering")
339+
viewer._render_training_controls(resume_click)
340+
assert viewer.is_rendering_paused() is False
341+
342+
295343
def test_newton_viewer_particle_color_override(monkeypatch):
296344
from newton.viewer import ViewerGL
297345

0 commit comments

Comments
 (0)