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
impl MjViewer
Sourcepub fn launch_passive<M: Deref<Target = MjModel>>(
model: M,
max_user_geom: usize,
) -> Result<Self, MjViewerError>
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
MjViewerError::EventLoopErrorif the event loop fails to initialize.MjViewerError::GlInitFailedif OpenGL / window initialization fails.MjViewerError::GlutinErrorif a glutin operation fails.MjViewerError::PainterInitErrorif the UI painter fails to initialize (featureviewer-ui).
Sourcepub fn builder() -> MjViewerBuilder
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.
Sourcepub fn state(&self) -> &Arc<Mutex<ViewerSharedState>>
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.
Sourcepub fn with_state_lock<F, R>(
&self,
fun: F,
) -> Result<R, PoisonError<MutexGuard<'_, ViewerSharedState>>>
pub fn with_state_lock<F, R>( &self, fun: F, ) -> Result<R, PoisonError<MutexGuard<'_, ViewerSharedState>>>
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();Sourcepub fn add_ui_callback<F>(&mut self, callback: F)
pub fn add_ui_callback<F>(&mut self, callback: F)
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");
});
});Sourcepub fn add_ui_callback_detached<F>(&mut self, callback: F)
pub fn add_ui_callback_detached<F>(&mut self, callback: F)
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.
Sourcepub fn sync_data_full<M: Deref<Target = MjModel>>(
&mut self,
data: &mut MjData<M>,
)
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).
Sourcepub fn sync_data<M: Deref<Target = MjModel>>(&mut self, data: &mut MjData<M>)
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.
- 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 interfaceSourcepub fn sync_model(&mut self, model: &mut MjModel)
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.
Sourcepub fn sync_model_opt(&mut self, opt: &mut MjOption)
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.
Sourcepub fn sync_model_vis(&mut self, vis: &mut MjVisual)
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.
Sourcepub fn sync_model_stat(&mut self, stat: &mut MjStatistic)
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.
Sourcepub fn update_texture_from(
&mut self,
model: &MjModel,
texture_id: usize,
) -> Result<(), MjViewerError>
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
MjViewerError::SignatureMismatchifmodel’s signature does not match the viewer’s passive model.MjViewerError::IndexOutOfBoundsiftexture_id >= model.ntex().
Sourcepub fn update_textures_from(
&mut self,
model: &MjModel,
) -> Result<(), MjViewerError>
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
MjViewerError::SignatureMismatchifmodel’s signature does not match the viewer’s passive model.
Sourcepub fn update_mesh_from(
&mut self,
model: &MjModel,
mesh_id: usize,
) -> Result<(), MjViewerError>
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
MjViewerError::SignatureMismatchifmodel’s signature does not match the viewer’s passive model.MjViewerError::IndexOutOfBoundsifmesh_id >= model.nmesh().
Sourcepub fn update_meshes_from(
&mut self,
model: &MjModel,
) -> Result<(), MjViewerError>
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
MjViewerError::SignatureMismatchifmodel’s signature does not match the viewer’s passive model.
Sourcepub fn update_hfield_from(
&mut self,
model: &MjModel,
hfield_id: usize,
) -> Result<(), MjViewerError>
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
MjViewerError::SignatureMismatchifmodel’s signature does not match the viewer’s passive model.MjViewerError::IndexOutOfBoundsifhfield_id >= model.nhfield().
Sourcepub fn update_hfields_from(
&mut self,
model: &MjModel,
) -> Result<(), MjViewerError>
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
MjViewerError::SignatureMismatchifmodel’s signature does not match the viewer’s passive model.
Sourcepub fn render(&mut self) -> Result<(), MjViewerError>
pub fn render(&mut self) -> Result<(), MjViewerError>
Processes the UI (when enabled), processes events, draws the scene and swaps buffers in OpenGL.
§Errors
MjViewerError::GlutinErrorif the OpenGL context cannot be made current or the buffer swap fails.MjViewerError::SceneErrorif synchronizing user scene geoms fails (e.g. the scene is full).MjViewerError::ContextErrorif reading pixels for a pending screenshot fails.
Sourcepub fn with_ui_egui_ctx<F>(&mut self, once_fn: F)
pub fn with_ui_egui_ctx<F>(&mut self, once_fn: F)
Gains scoped access to egui::Context, which is part of the UI,
for dealing with custom initialization (e.g., loading in images).
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for MjViewer
impl !RefUnwindSafe for MjViewer
impl !Send for MjViewer
impl !Sync for MjViewer
impl !UnwindSafe for MjViewer
impl Unpin for MjViewer
impl UnsafeUnpin for MjViewer
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
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>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
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)
fn as_any(&self) -> &(dyn Any + 'static)
&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)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.