Implementation:Google deepmind Dm control Viewer Core
| Knowledge Sources | |
|---|---|
| Domains | Visualization, Interactive Simulation, Input Handling |
| Last Updated | 2026-02-15 04:00 GMT |
Overview
This module implements the core viewer component that manages the MuJoCo physics scene viewport, including camera control, object manipulation, and all interactive input bindings for navigating and interacting with the 3D scene.
Description
The Viewer class is the interactive heart of the dm_control viewer. On initialization, it creates render settings, an InputMap, and null perturbation placeholders. The initialize() method sets up a SceneCamera for scene rendering, a ManipulationController for dragging and rotating bodies, a FreeCameraController for orbiting, panning, and zooming, and a CameraSelector for cycling through fixed, tracking, and free cameras. It then binds a comprehensive set of keyboard and mouse actions to these controllers, supporting both mouse and touchpad input modes with different control mappings.
CameraSelector cycles through the model's defined fixed cameras and the free camera using bracket keys. When a fixed camera is selected, the free camera controller is deactivated. The escape key returns to the free camera.
FreeCameraController implements orbit (left mouse drag), pan (right mouse drag in vertical/horizontal planes), zoom (scroll wheel), center-on-object (right double-click via raycasting), and body tracking (Ctrl+right double-click). It uses AtomicAction to ensure only one camera movement can be active at a time.
ManipulationController handles body selection via raycasting on double-click and drag-based perturbation of selected bodies. It supports vertical translation, horizontal translation, and rotation modes, each activated by different mouse button and modifier key combinations.
Usage
Use this module as the scene interaction layer of the dm_control viewer. The Viewer class is instantiated by the viewer application and provides all 3D navigation and object manipulation capabilities. It translates raw user input into camera movements and body perturbations through a comprehensive set of keyboard and mouse bindings.
Code Reference
Source Location
- Repository: Google_deepmind_Dm_control
- File: dm_control/viewer/viewer.py
- Lines: 1-546
Signature
class Viewer:
"""Viewport displaying the contents of a physics world."""
def __init__(self, viewport, mouse, keyboard, camera_settings=None,
zoom_factor=1.5, scene_callback=None): ...
def initialize(self, physics, renderer_instance, touchpad): ...
def deinitialize(self): ...
def render(self): ...
def zoom_to_scene(self): ...
@property
def perturbation(self): ...
@property
def camera(self): ...
@property
def render_settings(self): ...
class CameraSelector:
def __init__(self, model, camera, free_camera, **unused): ...
def select_previous(self): ...
def select_next(self): ...
def escape(self): ...
class FreeCameraController:
def __init__(self, viewport, camera, pointer, selection_service, **unused): ...
def activate(self): ...
def deactivate(self): ...
def set_pan_vertical_mode(self, enable): ...
def set_pan_horizontal_mode(self, enable): ...
def set_rotate_mode(self, enable): ...
def center(self): ...
def on_move(self, position, translation): ...
def zoom(self, zoom_factor): ...
def track(self): ...
def free_look(self): ...
class ManipulationController:
def __init__(self, viewport, camera, pointer, **unused): ...
def select(self): ...
def set_move_vertical_mode(self, enable): ...
def set_move_horizontal_mode(self, enable): ...
def set_rotate_mode(self, enable): ...
def on_move(self, position, translation): ...
@property
def perturbation(self): ...
@property
def selected_body_id(self): ...
Import
from dm_control.viewer import viewer
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| viewport | renderer.Viewport | Yes | Render viewport defining display dimensions |
| mouse | GlfwMouse | Yes | Mouse device handler |
| keyboard | GlfwKeyboard | Yes | Keyboard device handler |
| physics | Physics | Yes (initialize) | MuJoCo physics instance providing model and data |
| renderer_instance | OffScreenRenderer | Yes (initialize) | Renderer for off-screen rendering |
| touchpad | bool | Yes (initialize) | Whether to use touchpad-specific input bindings |
| camera_settings | MjvCamera | No | Saved camera settings to restore across model reloads |
| zoom_factor | float | No | Initial zoom factor for the scene camera (default 1.5) |
| scene_callback | callable | No | Callback applied to every rendered scene: callable(MjModel, MjData, MjvScene) |
Outputs
| Name | Type | Description |
|---|---|---|
| perturbation | Perturbation or NullPerturbation | Currently active body perturbation (if any) |
| camera | SceneCamera | The active scene camera instance |
| render_settings | RenderSettings | Current render settings (visualization flags, render flags, etc.) |
Usage Examples
Basic Usage
from dm_control.viewer import viewer
from dm_control.viewer import renderer
# Create viewer components
viewport = renderer.Viewport(width=640, height=480)
v = viewer.Viewer(viewport, mouse, keyboard)
# Initialize with a physics instance
v.initialize(physics, offscreen_renderer, touchpad=False)
# Render the scene
v.render()
# Access the current camera
camera = v.camera
print(camera.name)
Key Bindings Reference
# Mouse-based controls (non-touchpad mode):
# Left mouse drag: Rotate camera
# Right mouse drag: Pan camera vertically
# Shift + Right mouse drag: Pan camera horizontally
# Ctrl + Left mouse drag: Rotate selected object
# Ctrl + Right mouse drag: Move selected object vertically
# Ctrl + Shift + Right mouse drag: Move selected object horizontally
# Scroll wheel: Zoom in/out
# Double-click left: Select object
# Double-click right: Center camera on object
# Ctrl + Double-click right: Track object
# Keyboard controls:
# Escape: Free camera mode
# [ / ]: Previous / Next camera
# Ctrl + A: Zoom to scene
# F5: Toggle stereo buffering
# F6 / Shift+F6: Next / Previous rendering mode
# F7 / Shift+F7: Next / Previous labeling mode
# F11: Print camera transform
# 0-9: Toggle geom groups
# Shift + 0-9: Toggle site groups