Skip to main content

MjViewer

Struct MjViewer 

Source
pub struct MjViewer { /* private fields */ }
Expand description

A Rust-native implementation of the MuJoCo viewer. To conform to Rust’s safety rules, the viewer doesn’t store a mutable reference to the MjData struct, but it instead accepts it as a parameter in its methods.

The MjViewer::sync_data method must be called to sync the state of MjViewer and MjData.

§Shortcuts

Main keyboard and mouse shortcuts can be viewed by pressing F1. Additionally, some visualization toggles are included, but not displayed in the F1 help menu:

  • C: camera,
  • U: actuator,
  • J: joint,
  • M: center of mass,
  • H: convex hull,
  • Z: light,
  • T: transparent,
  • I: inertia,
  • E: constraint.

§Safety

Due to the nature of OpenGL, this should only be run in the main thread.

Implementations§

Source§

impl MjViewer

Source

pub fn launch_passive<M: Deref<Target = MjModel>>( model: M, max_user_geom: usize, ) -> Result<Self, MjViewerError>

Launches the MuJoCo viewer. A Result struct is returned that either contains MjViewer or a MjViewerError. The max_user_geom parameter defines how much space will be allocated for additional, user-defined visual-only geoms. It can thus be set to 0 if no additional geoms will be drawn by the user.

Note that the use of MjViewerBuilder is preferred, because it is more flexible. Call MjViewer::builder to create a MjViewerBuilder instance.

§Returns

On success, returns Ok variant containing the MjViewer.

§Errors
Source

pub fn builder() -> MjViewerBuilder

A shortcut for creating an instance of MjViewerBuilder. The builder can be used to build the viewer after configuring it. It allows better configuration than MjViewer::launch_passive, which is fixed to achieve backward compatibility.

Source

pub fn running(&self) -> bool

Checks whether the viewer is still running.

Source

pub fn state(&self) -> &Arc<Mutex<ViewerSharedState>>

Returns a reference to the shared state ViewerSharedState. This struct can be used to sync the state of the viewer with the simulation, possibly running in another thread.

Source

pub fn with_state_lock<F, R>( &self, fun: F, ) -> Result<R, PoisonError<MutexGuard<'_, ViewerSharedState>>>
where F: FnOnce(MutexGuard<'_, ViewerSharedState>) -> R,

Acquires a Mutex lock on the MjViewer’s shared state (MjViewer::state). The acquired lock is passed to the function/closure fun.

§Errors

Returns PoisonError if the mutex holding the shared state has panicked, thus poisoning the lock.

§Example
let mut viewer = MjViewer::builder().max_user_geoms(1)
    .build_passive(&model).unwrap();
viewer.with_state_lock(|mut lock| {
    let scene = lock.user_scene_mut();
    scene.create_geom(MjtGeom::mjGEOM_BOX, Some([1.0, 1.0, 1.0]), Some([0.0, 0.0, 0.0]), None, None);
}).unwrap();
Source

pub fn add_ui_callback<F>(&mut self, callback: F)
where F: FnMut(&Context, &mut MjData<Box<MjModel>>) + 'static,

Adds a user-defined UI callback for custom widgets in the viewer’s UI. The callback receives an egui::Context reference and can be used to create custom windows, panels, or other UI elements. It also receives a mutable reference to MjData, which can be used to read and modify simulation state. Note that the model can be accessed through MjData::model.

§Note

The viewer’s internal shared-state Mutex is held for the entire duration of the callback (because data is a live borrow of the guarded data_passive field). Do not attempt to lock the shared state again from within the callback as that will deadlock the viewer thread.

§Example
viewer.add_ui_callback(|ctx, data| {
    use mujoco_rs::viewer::egui;
    egui::Window::new("Custom controls")
        .scroll(true)
        .show(ctx, |ui| {
            ui.label("Custom UI element");
        });
});
Source

pub fn add_ui_callback_detached<F>(&mut self, callback: F)
where F: FnMut(&Context) + 'static,

Same as MjViewer::add_ui_callback, except the callback does not receive the passive MjData instance of the viewer. Consequently, the mutex of the viewer’s shared state doesn’t need to be locked, yielding better performance.

Source

pub fn sync_data_full<M: Deref<Target = MjModel>>( &mut self, data: &mut MjData<M>, )

Same as MjViewer::sync_data, except it copies the entire MjData struct (including large Jacobian and other arrays), not just the state needed for visualization. This is a proxy to ViewerSharedState::sync_data_full.

§Panics

Panics if the internal data copy fails due to an inconsistent model state (indicates a bug).

Source

pub fn sync_data<M: Deref<Target = MjModel>>(&mut self, data: &mut MjData<M>)

Syncs the state of viewer’s internal MjData with data. This is a proxy to ViewerSharedState::sync_data.

Any changes made to the internal MjData in between syncs get selectively merged back into data before the copy. Perturbations are applied to data after the sync, which unconditionally zeroes xfrc_applied (see ViewerSharedState::sync_data for details).

Note that users must afterward call MjViewer::render for the scene to be rendered and the UI to be processed.

The user's data is copied into the viewer's internal passive copy via ``mjv_copyData``, which skips large computed arrays not required for visualization. The viewer's passive copy will therefore **not** contain:
  • mass matrices (qM, qLD, qLDiagInv, qLU);
  • constraint arrays (efc_*, iefc_*, including constraint Jacobians).

In UI callbacks these fields will be absent unless MjViewer::sync_data_full is used or they are recomputed explicitly (e.g. via data.forward()).

Additionally, because the viewer may write integration state (e.g. ctrl) back to the user’s data, any Jacobians or other derived quantities in data may be stale after this call and should be recomputed if needed.

§Panics

Panics if the internal data copy or state merge fails due to an inconsistent model state (indicates a bug).

§Example
viewer.sync_data(&mut data);  // sync the data
viewer.render().unwrap();  // render the scene and process the user interface
Source

pub fn sync_model(&mut self, model: &mut MjModel)

Performs a bidirectional three-way merge of model parameters between the viewer’s passive model and the incoming model. This is a proxy to ViewerSharedState::sync_model.

Detects model changes via signature comparison and reloads internal state if needed. After a reload, the passive model mirrors the incoming model’s defaults, so the first merge is effectively a no-op. On subsequent calls, viewer UI changes and simulation-side changes are merged bidirectionally.

Source

pub fn sync_model_opt(&mut self, opt: &mut MjOption)

Performs a bidirectional three-way merge of MjModel::opt between the viewer’s passive model and the provided option struct. This is a proxy to ViewerSharedState::sync_model_opt.

This allows updating physics options without requiring unsafe access via MjData::model_mut or manipulating the viewer’s shared state directly.

Source

pub fn sync_model_vis(&mut self, vis: &mut MjVisual)

Performs a bidirectional three-way merge of MjModel::vis between the viewer’s passive model and the provided visual struct. This is a proxy to ViewerSharedState::sync_model_vis.

This allows updating visualization options without requiring unsafe access via MjData::model_mut or manipulating the viewer’s shared state directly.

Source

pub fn sync_model_stat(&mut self, stat: &mut MjStatistic)

Performs a bidirectional three-way merge of MjModel::stat between the viewer’s passive model and the provided statistic struct. This is a proxy to ViewerSharedState::sync_model_stat.

This allows updating model statistics without requiring unsafe access via MjData::model_mut or manipulating the viewer’s shared state directly.

Source

pub fn update_texture_from( &mut self, model: &MjModel, texture_id: usize, ) -> Result<(), MjViewerError>

Copies the texture with texture_id from model into the viewer’s internal passive model and schedules a GPU re-upload for the next render call.

This is a proxy to ViewerSharedState::update_texture_from.

§Errors
Source

pub fn update_textures_from( &mut self, model: &MjModel, ) -> Result<(), MjViewerError>

Copies all textures from model into the viewer’s internal passive model and schedules a GPU re-upload for the next render call.

This is a proxy to ViewerSharedState::update_textures_from.

§Errors
Source

pub fn update_mesh_from( &mut self, model: &MjModel, mesh_id: usize, ) -> Result<(), MjViewerError>

Copies the mesh with mesh_id from model into the viewer’s internal passive model and schedules a GPU re-upload for the next render call.

This is a proxy to ViewerSharedState::update_mesh_from.

§Errors
Source

pub fn update_meshes_from( &mut self, model: &MjModel, ) -> Result<(), MjViewerError>

Copies all meshes from model into the viewer’s internal passive model and schedules a GPU re-upload for the next render call.

This is a proxy to ViewerSharedState::update_meshes_from.

§Errors
Source

pub fn update_hfield_from( &mut self, model: &MjModel, hfield_id: usize, ) -> Result<(), MjViewerError>

Copies the heightfield with hfield_id from model into the viewer’s internal passive model and schedules a GPU re-upload for the next render call.

This is a proxy to ViewerSharedState::update_hfield_from.

§Errors
Source

pub fn update_hfields_from( &mut self, model: &MjModel, ) -> Result<(), MjViewerError>

Copies all heightfields from model into the viewer’s internal passive model and schedules a GPU re-upload for the next render call.

This is a proxy to ViewerSharedState::update_hfields_from.

§Errors
Source

pub fn render(&mut self) -> Result<(), MjViewerError>

Processes the UI (when enabled), processes events, draws the scene and swaps buffers in OpenGL.

§Errors
Source

pub fn with_ui_egui_ctx<F>(&mut self, once_fn: F)
where F: FnOnce(&Context),

Gains scoped access to egui::Context, which is part of the UI, for dealing with custom initialization (e.g., loading in images).

Trait Implementations§

Source§

impl Debug for MjViewer

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for MjViewer

Releases OpenGL resources (rendering context and egui painter) while the GL context is still current.

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more