1
2pub use crate::errors::VROverlayError;
3use crate::pose::Matrix3x4;
4use crate::Overlay;
5use crate::TextureBounds;
6use crate::TrackingUniverseOrigin;
7use crate::{sys, ColorTint, TrackedDeviceIndex};
8
9
10
11impl Overlay {
12
13 pub fn create_overlay(
14 &mut self,
15 key: &str,
16 friendly_name: &str,
17 ) -> Result<OverlayHandle, VROverlayError> {
18 let mut handle = sys::VROverlayHandle_t::default();
19 let err = unsafe {
20 self.0.CreateOverlay.unwrap()(key.as_ptr().cast_mut().cast(),friendly_name.as_ptr().cast_mut().cast(),&mut handle)
21 };
22
23 VROverlayError::new(err)?;
24 Ok(OverlayHandle(handle))
25 }
26
27 pub fn set_visibility(
28 &mut self,
29 overlay: OverlayHandle,
30 is_visible: bool,
31 ) -> Result<(), VROverlayError> {
32 let err = if is_visible {
33 unsafe { self.0.ShowOverlay.unwrap()(overlay.0) }
34 } else {
35 unsafe { self.0.HideOverlay.unwrap()(overlay.0) }
36 };
37 VROverlayError::new(err)
38 }
39
40 pub fn is_visible(&mut self, overlay: OverlayHandle) -> bool {
41 unsafe { self.0.IsOverlayVisible.unwrap()(overlay.0) }
42 }
43
44 pub fn set_curvature(
48 &mut self,
49 overlay: OverlayHandle,
50 curvature: f32,
51 ) -> Result<(), VROverlayError> {
52 let err = unsafe {
56 self.0
57 .SetOverlayCurvature.unwrap()(overlay.0, curvature)
58 };
59 VROverlayError::new(err)
60 }
61
62 pub fn curvature(&mut self, overlay: OverlayHandle) -> Result<f32, VROverlayError> {
63 let mut curvature = 0.0;
64 let err = unsafe {
65 self.0
66 .GetOverlayCurvature.unwrap()(overlay.0, &mut curvature)
67 };
68 VROverlayError::new(err)?;
69 Ok(curvature)
70 }
71
72 pub fn set_opacity(
76 &mut self,
77 overlay: OverlayHandle,
78 alpha: f32,
79 ) -> Result<(), VROverlayError> {
80 if !(0.0..=1.0).contains(&alpha) {
81 panic!("`alpha` must be in range [0,1]");
82 }
83 let err = unsafe { self.0.SetOverlayAlpha.unwrap()(overlay.0, alpha) };
84 VROverlayError::new(err)
85 }
86
87 pub fn opacity(&mut self, overlay: OverlayHandle) -> Result<f32, VROverlayError> {
88 let mut alpha = 0.0;
89 let err = unsafe { self.0.GetOverlayAlpha.unwrap()(overlay.0, &mut alpha) };
90 VROverlayError::new(err)?;
91 Ok(alpha)
92 }
93
94 pub fn width(&mut self, overlay: OverlayHandle) -> Result<f32, VROverlayError> {
95 let mut width = 0.0;
96 let err = unsafe {
97 self.0
98 .GetOverlayWidthInMeters.unwrap()(overlay.0, &mut width)
99 };
100 VROverlayError::new(err)?;
101 Ok(width)
102 }
103
104 pub fn set_width(
105 &mut self,
106 overlay: OverlayHandle,
107 width_in_meters: f32,
108 ) -> Result<(), VROverlayError> {
109 let err = unsafe {
110 self.0
111 .SetOverlayWidthInMeters.unwrap()(overlay.0, width_in_meters)
112 };
113 VROverlayError::new(err)
114 }
115
116 pub fn sort_order(&mut self, overlay: OverlayHandle) -> Result<u32, VROverlayError> {
117 let mut sort_order: u32 = 0;
118 let err = unsafe {
119 self.0
120 .GetOverlaySortOrder.unwrap()(overlay.0, &mut sort_order)
121 };
122 VROverlayError::new(err)?;
123 Ok(sort_order)
124 }
125
126 pub fn set_sort_order(
127 &mut self,
128 overlay: OverlayHandle,
129 sort_order: u32,
130 ) -> Result<(), VROverlayError> {
131 let err = unsafe {
132 self.0
133 .SetOverlaySortOrder.unwrap()(overlay.0, sort_order)
134 };
135 VROverlayError::new(err)
136 }
137
138 pub fn tint(&mut self, overlay: OverlayHandle) -> Result<ColorTint, VROverlayError> {
139 let mut tint = ColorTint::default();
140 unsafe {
141 let err = self.0.GetOverlayColor.unwrap()(
142 overlay.0,
143 &mut tint.r,
144 &mut tint.g,
145 &mut tint.b,
146 );
147 VROverlayError::new(err)?;
148 let err = self.0.GetOverlayAlpha.unwrap()(overlay.0, &mut tint.a);
149 VROverlayError::new(err)?
150 };
151 Ok(tint)
152 }
153
154 pub fn set_tint(
155 &mut self,
156 overlay: OverlayHandle,
157 tint: ColorTint,
158 ) -> Result<(), VROverlayError> {
159 unsafe {
160 let err = self.0
161 .SetOverlayColor.unwrap()(overlay.0, tint.r, tint.g, tint.b);
162 VROverlayError::new(err)?;
163 let err = self.0.SetOverlayAlpha.unwrap()(overlay.0, tint.a);
164 VROverlayError::new(err)?;
165 }
166 Ok(())
167 }
168
169 pub fn set_image(
170 &mut self,
171 overlay: OverlayHandle,
172 img_path: &std::ffi::CStr,
173 ) -> Result<(), VROverlayError> {
174 let err = unsafe {
175 self.0
176 .SetOverlayFromFile.unwrap()(overlay.0, img_path.as_ptr().cast_mut())
177 };
178 VROverlayError::new(err)
179 }
180
181 pub fn set_raw_data(
182 &mut self,
183 overlay: OverlayHandle,
184 data: &[u8],
185 width: usize,
186 height: usize,
187 bytes_per_pixel: usize,
188 ) -> Result<(), VROverlayError> {
189 let err = unsafe {
190 let ptr: *const std::ffi::c_void = data.as_ptr().cast();
191 let ptr = ptr as *mut std::ffi::c_void;
194
195 self.0.SetOverlayRaw.unwrap()(
196 overlay.0,
197 ptr.cast(),
198 width as u32,
199 height as u32,
200 bytes_per_pixel as u32,
201 )
202 };
203 VROverlayError::new(err)
204 }
205
206 pub fn texel_aspect(&mut self, overlay: OverlayHandle) -> Result<f32, VROverlayError> {
208 let mut aspect = 0.0;
209 let err = unsafe {
210 self.0
211 .GetOverlayTexelAspect.unwrap()(overlay.0, &mut aspect)
212 };
213 VROverlayError::new(err)?;
214 Ok(aspect)
215 }
216
217 pub fn set_texel_aspect(
221 &mut self,
222 overlay: OverlayHandle,
223 aspect: f32,
224 ) -> Result<(), VROverlayError> {
225 let err = unsafe { self.0.SetOverlayTexelAspect.unwrap()(overlay.0, aspect) };
226 VROverlayError::new(err)
227 }
228
229 pub fn set_transform_absolute(
233 &mut self,
234 overlay: OverlayHandle,
235 origin: TrackingUniverseOrigin,
236 origin_to_overlay: &Matrix3x4,
237 ) -> Result<(), VROverlayError> {
238 let origin_to_overlay: &sys::HmdMatrix34_t = origin_to_overlay.into();
239
240 let err = unsafe {
241 self.0
242 .SetOverlayTransformAbsolute.unwrap()(overlay.0, origin.into(), (&raw const *origin_to_overlay).cast_mut())
243 };
244 VROverlayError::new(err)
245 }
246
247 pub fn get_transform_absolute(
251 &mut self,
252 overlay: OverlayHandle,
253 origin_to_overlay: &mut Matrix3x4,
254 ) -> Result<TrackingUniverseOrigin, VROverlayError> {
255 let mut origin = TrackingUniverseOrigin::Standing;
257 let origin_to_overlay: &mut sys::HmdMatrix34_t = origin_to_overlay.into();
258 let err = unsafe {
259 self.0.GetOverlayTransformAbsolute.unwrap()(
260 overlay.0,
261 (&raw mut origin).cast(),
262 origin_to_overlay,
263 )
264 };
265 VROverlayError::new(err).map(|_| origin)
266 }
267
268 pub fn set_transform_tracked_device_relative(
272 &mut self,
273 overlay: OverlayHandle,
274 index: TrackedDeviceIndex,
275 device_to_overlay: &Matrix3x4,
276 ) -> Result<(), VROverlayError> {
277 let device_to_overlay: &sys::HmdMatrix34_t = device_to_overlay.into();
278 let err = unsafe {
279 self.0
280 .SetOverlayTransformTrackedDeviceRelative.unwrap()(overlay.0, index.0, (&raw const *device_to_overlay).cast_mut())
281 };
282 VROverlayError::new(err)
283 }
284
285 pub fn get_transform_tracked_device_relative(
289 &mut self,
290 overlay: OverlayHandle,
291 device_to_overlay: &mut Matrix3x4,
292 ) -> Result<TrackedDeviceIndex, VROverlayError> {
293 let mut index = sys::TrackedDeviceIndex_t::default();
294 let device_to_overlay: &mut sys::HmdMatrix34_t = device_to_overlay.into();
295 let err = unsafe {
296 self.0
297 .GetOverlayTransformTrackedDeviceRelative.unwrap()(overlay.0, &mut index, device_to_overlay)
298 };
299 VROverlayError::new(err)?;
300 if index==sys::k_unTrackedDeviceIndexInvalid as u32{
302 return Err(VROverlayError::RequestFailed);
303 }
304 Ok(crate::tracking::TrackedDeviceIndex(index))
305 }
306
307 pub fn set_texture_bounds(
308 &mut self,
309 overlay: OverlayHandle,
310 bounds: &TextureBounds,
311 ) -> Result<(), VROverlayError> {
312 let err = unsafe {
313 self.0
314 .SetOverlayTextureBounds.unwrap()(overlay.0, (&raw const bounds.0).cast_mut())
315 };
316 VROverlayError::new(err)
317 }
318
319 pub fn is_dashboard_visible(&mut self) -> bool {
320 unsafe { self.0.IsDashboardVisible.unwrap()() }
321 }
322}
323unsafe impl Send for Overlay {}
324unsafe impl Sync for Overlay {}
325
326#[derive(Debug, PartialEq, Eq, Clone, Copy)]
327pub struct OverlayHandle(pub sys::VROverlayHandle_t);