mujoco_rs/wrappers/
mj_rendering.rs1use std::{ffi::CString, mem::{zeroed, MaybeUninit}};
3use crate::mujoco_c::*;
4
5use super::mj_model::MjModel;
6use std::ptr;
7
8pub type MjrRectangle = mjrRect;
12impl MjrRectangle {
13 pub fn new(left: i32, bottom: i32, width: i32, height: i32) -> Self {
14 Self {
15 left,
16 bottom,
17 width,
18 height,
19 }
20 }
21}
22
23impl Default for MjrRectangle {
24 fn default() -> Self {
25 unsafe { zeroed() }
26 }
27}
28
29
30pub type MjtGridPos = mjtGridPos;
33
34pub type MjtFramebuffer = mjtFramebuffer;
36
37pub type MjtDepthMap = mjtDepthMap;
41
42pub type MjtFontScale = mjtFontScale;
45
46pub type MjtFont = mjtFont;
48
49#[derive(Debug)]
53pub struct MjrContext {
54 ffi: mjrContext
55}
56
57impl MjrContext {
58 pub fn new(model: &MjModel) -> Self {
59 unsafe {
60 let mut c = MaybeUninit::uninit();
61 mjr_defaultContext(c.as_mut_ptr());
62 mjr_makeContext(model.ffi(), c.as_mut_ptr(), MjtFontScale::mjFONTSCALE_100 as i32);
63 Self {ffi: c.assume_init()}
64 }
65 }
66
67 pub fn offscreen(&mut self) -> &mut Self {
69 unsafe {
70 mjr_setBuffer(MjtFramebuffer::mjFB_OFFSCREEN as i32, &mut self.ffi);
71 }
72 self
73 }
74
75 pub fn window(&mut self) -> &mut Self {
77 unsafe {
78 mjr_setBuffer(MjtFramebuffer::mjFB_WINDOW as i32, &mut self.ffi);
79 }
80 self
81 }
82
83 pub fn change_font(&mut self, fontscale: MjtFontScale) {
85 unsafe { mjr_changeFont(fontscale as i32, self.ffi_mut()) }
86 }
87
88 pub fn add_aux(&mut self, index: usize, width: u32, height: u32, samples: usize) {
90 unsafe { mjr_addAux(index as i32, width as i32, height as i32, samples as i32, self.ffi_mut()); }
91 }
92
93 pub fn resize_offscreen(&mut self, width: u32, height: u32) {
95 unsafe { mjr_resizeOffscreen(width as i32, height as i32, self.ffi_mut()); }
96 }
97
98 pub fn upload_texture(&mut self, model: &MjModel, texid: u32) {
100 unsafe { mjr_uploadTexture(model.ffi(), self.ffi_mut(), texid as i32); }
101 }
102
103 pub fn restore_buffer(&mut self) {
105 unsafe { mjr_restoreBuffer(self.ffi_mut()); }
106 }
107
108 pub fn mjr_set_buffer(&mut self, framebuffer: i32) {
109 unsafe { mjr_setBuffer(framebuffer, self.ffi_mut()); }
110 }
111
112 pub fn read_pixels(&self, rgb: Option<&mut [u8]>, depth: Option<&mut [f32]>, viewport: &MjrRectangle) {
115 unsafe {
116 mjr_readPixels(
117 rgb.map_or(ptr::null_mut(), |x| x.as_mut_ptr()),
118 depth.map_or(ptr::null_mut(), |x| x.as_mut_ptr()),
119 viewport.clone(), self.ffi()
120 )
121 }
122 }
123
124 pub fn set_aux(&mut self, index: usize) {
126 unsafe { mjr_setAux(index as i32, self.ffi_mut()); }
127 }
128
129 pub fn overlay(&mut self, font: MjtFont, gridpos: MjtGridPos, viewport: MjrRectangle, overlay: &str, overlay2: Option<&str>) {
133 let c_overlay = CString::new(overlay).unwrap();
134 let c_overlay2 = overlay2.map(|x| CString::new(x).unwrap());
135
136 unsafe { mjr_overlay(
137 font as i32, gridpos as i32, viewport,
138 c_overlay.as_ptr(),
139 c_overlay2.as_ref().map_or(std::ptr::null(), |x| x.as_ptr()),
140 self.ffi()
141 ); }
142 }
143
144 pub fn ffi(&self) -> &mjrContext {
145 &self.ffi
146 }
147
148 pub unsafe fn ffi_mut(&mut self) -> &mut mjrContext {
149 &mut self.ffi
150 }
151}
152
153impl Drop for MjrContext {
154 fn drop(&mut self) {
155 unsafe {
156 mjr_freeContext(&mut self.ffi);
157 }
158 }
159}
160