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 MjtFont = mjtFont;
34
35pub type MjtFontScale = mjtFontScale;
39
40pub type MjtGridPos = mjtGridPos;
44
45pub type MjtFramebuffer = mjtFramebuffer;
49
50#[derive(Debug)]
54pub struct MjrContext {
55 ffi: mjrContext
56}
57
58impl MjrContext {
59 pub fn new(model: &MjModel) -> Self {
60 unsafe {
61 let mut c = MaybeUninit::uninit();
62 mjr_defaultContext(c.as_mut_ptr());
63 mjr_makeContext(model.ffi(), c.as_mut_ptr(), MjtFontScale::mjFONTSCALE_100 as i32);
64 Self {ffi: c.assume_init()}
65 }
66 }
67
68 pub fn offscreen(&mut self) -> &mut Self {
70 unsafe {
71 mjr_setBuffer(MjtFramebuffer::mjFB_OFFSCREEN as i32, &mut self.ffi);
72 }
73 self
74 }
75
76 pub fn window(&mut self) -> &mut Self {
78 unsafe {
79 mjr_setBuffer(MjtFramebuffer::mjFB_WINDOW as i32, &mut self.ffi);
80 }
81 self
82 }
83
84 pub fn change_font(&mut self, fontscale: MjtFontScale) {
86 unsafe { mjr_changeFont(fontscale as i32, self.ffi_mut()) }
87 }
88
89 pub fn add_aux(&mut self, index: usize, width: u32, height: u32, samples: usize) {
91 unsafe { mjr_addAux(index as i32, width as i32, height as i32, samples as i32, self.ffi_mut()); }
92 }
93
94 pub fn resize_offscreen(&mut self, width: u32, height: u32) {
96 unsafe { mjr_resizeOffscreen(width as i32, height as i32, self.ffi_mut()); }
97 }
98
99 pub fn upload_texture(&mut self, model: &MjModel, texid: u32) {
101 unsafe { mjr_uploadTexture(model.ffi(), self.ffi_mut(), texid as i32); }
102 }
103
104 pub fn restore_buffer(&mut self) {
106 unsafe { mjr_restoreBuffer(self.ffi_mut()); }
107 }
108
109 pub fn mjr_set_buffer(&mut self, framebuffer: i32) {
110 unsafe { mjr_setBuffer(framebuffer, self.ffi_mut()); }
111 }
112
113 pub fn read_pixels(&self, rgb: Option<&mut [u8]>, depth: Option<&mut [f32]>, viewport: &MjrRectangle) {
116 unsafe {
117 mjr_readPixels(
118 rgb.map_or(ptr::null_mut(), |x| x.as_mut_ptr()),
119 depth.map_or(ptr::null_mut(), |x| x.as_mut_ptr()),
120 viewport.clone(), self.ffi()
121 )
122 }
123 }
124
125 pub fn set_aux(&mut self, index: usize) {
127 unsafe { mjr_setAux(index as i32, self.ffi_mut()); }
128 }
129
130 pub fn overlay(&mut self, font: MjtFont, gridpos: MjtGridPos, viewport: MjrRectangle, overlay: &str, overlay2: Option<&str>) {
132 let c_overlay = CString::new(overlay).unwrap();
133 let c_overlay2 = overlay2.map(|x| CString::new(x).unwrap());
134
135 unsafe { mjr_overlay(
136 font as i32, gridpos as i32, viewport,
137 c_overlay.as_ptr(),
138 c_overlay2.as_ref().map_or(std::ptr::null(), |x| x.as_ptr()),
139 self.ffi()
140 ); }
141 }
142
143 pub fn ffi(&self) -> &mjrContext {
144 &self.ffi
145 }
146
147 pub unsafe fn ffi_mut(&mut self) -> &mut mjrContext {
148 &mut self.ffi
149 }
150}
151
152impl Drop for MjrContext {
153 fn drop(&mut self) {
154 unsafe {
155 mjr_freeContext(&mut self.ffi);
156 }
157 }
158}
159