1use crate::bindings::{
2 CameraIntrinsics, CameraSpacePoint, ColorSpacePoint, DepthSpacePoint, ICoordinateMapper,
3 ICoordinateMappingChangedEventArgs, PointF, UINT, UINT16, WAITABLE_HANDLE,
4};
5use std::ptr;
6use windows::{
7 Win32::Foundation::{E_FAIL, E_POINTER},
8 core::Error,
9};
10
11pub struct CoordinateMapper {
12 ptr: *mut ICoordinateMapper,
13}
14
15impl CoordinateMapper {
16 pub(crate) fn new(ptr: *mut ICoordinateMapper) -> Self {
17 assert!(!ptr.is_null());
18 Self { ptr }
19 }
20
21 pub fn subscribe_coordinate_mapping_changed(&self) -> Result<WAITABLE_HANDLE, Error> {
22 if self.ptr.is_null() {
23 return Err(Error::from_hresult(E_POINTER));
24 }
25 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
26 let subscribe_fn = vtbl.SubscribeCoordinateMappingChanged.ok_or(E_FAIL)?;
27 let mut waitable_handle: WAITABLE_HANDLE = windows::Win32::Foundation::HANDLE::default();
28 let hr = unsafe { subscribe_fn(self.ptr, &mut waitable_handle) };
29 if hr.is_ok() {
30 Ok(waitable_handle)
31 } else {
32 Err(Error::from_hresult(hr))
33 }
34 }
35
36 pub fn unsubscribe_coordinate_mapping_changed(
37 &self,
38 waitable_handle: WAITABLE_HANDLE,
39 ) -> Result<(), Error> {
40 if self.ptr.is_null() {
41 return Err(Error::from_hresult(E_POINTER));
42 }
43 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
44 let unsubscribe_fn = vtbl.UnsubscribeCoordinateMappingChanged.ok_or(E_FAIL)?;
45 let hr = unsafe { unsubscribe_fn(self.ptr, waitable_handle) };
46 if hr.is_ok() {
47 Ok(())
48 } else {
49 Err(Error::from_hresult(hr))
50 }
51 }
52
53 pub fn get_coordinate_mapping_changed_event_data(
54 &self,
55 waitable_handle: WAITABLE_HANDLE,
56 ) -> Result<CoordinateMappingChangedEventArgs, Error> {
57 if self.ptr.is_null() {
58 return Err(Error::from_hresult(E_POINTER));
59 }
60 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
61 let get_fn = vtbl.GetCoordinateMappingChangedEventData.ok_or(E_FAIL)?;
62 let mut event_data: *mut ICoordinateMappingChangedEventArgs = ptr::null_mut();
63 let hr = unsafe { get_fn(self.ptr, waitable_handle, &mut event_data) };
64 if hr.is_ok() {
65 Ok(CoordinateMappingChangedEventArgs::new(event_data))
66 } else {
67 Err(Error::from_hresult(hr))
68 }
69 }
70
71 pub fn map_camera_point_to_depth_space(
72 &self,
73 camera_point: CameraSpacePoint,
74 ) -> Result<DepthSpacePoint, Error> {
75 if self.ptr.is_null() {
76 return Err(Error::from_hresult(E_POINTER));
77 }
78 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
79 let map_fn = vtbl.MapCameraPointToDepthSpace.ok_or(E_FAIL)?;
80 let mut depth_point = DepthSpacePoint { X: 0.0, Y: 0.0 };
81 let hr = unsafe { map_fn(self.ptr, camera_point, &mut depth_point) };
82 if hr.is_ok() {
83 Ok(depth_point)
84 } else {
85 Err(Error::from_hresult(hr))
86 }
87 }
88
89 pub fn map_camera_point_to_color_space(
90 &self,
91 camera_point: CameraSpacePoint,
92 ) -> Result<ColorSpacePoint, Error> {
93 if self.ptr.is_null() {
94 return Err(Error::from_hresult(E_POINTER));
95 }
96 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
97 let map_fn = vtbl.MapCameraPointToColorSpace.ok_or(E_FAIL)?;
98 let mut color_point = ColorSpacePoint { X: 0.0, Y: 0.0 };
99 let hr = unsafe { map_fn(self.ptr, camera_point, &mut color_point) };
100 if hr.is_ok() {
101 Ok(color_point)
102 } else {
103 Err(Error::from_hresult(hr))
104 }
105 }
106
107 pub fn map_depth_point_to_camera_space(
108 &self,
109 depth_point: DepthSpacePoint,
110 depth: UINT16,
111 ) -> Result<CameraSpacePoint, Error> {
112 if self.ptr.is_null() {
113 return Err(Error::from_hresult(E_POINTER));
114 }
115 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
116 let map_fn = vtbl.MapDepthPointToCameraSpace.ok_or(E_FAIL)?;
117 let mut camera_point = CameraSpacePoint {
118 X: 0.0,
119 Y: 0.0,
120 Z: 0.0,
121 };
122 let hr = unsafe { map_fn(self.ptr, depth_point, depth, &mut camera_point) };
123 if hr.is_ok() {
124 Ok(camera_point)
125 } else {
126 Err(Error::from_hresult(hr))
127 }
128 }
129
130 pub fn map_depth_point_to_color_space(
131 &self,
132 depth_point: DepthSpacePoint,
133 depth: UINT16,
134 ) -> Result<ColorSpacePoint, Error> {
135 if self.ptr.is_null() {
136 return Err(Error::from_hresult(E_POINTER));
137 }
138 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
139 let map_fn = vtbl.MapDepthPointToColorSpace.ok_or(E_FAIL)?;
140 let mut color_point = ColorSpacePoint { X: 0.0, Y: 0.0 };
141 let hr = unsafe { map_fn(self.ptr, depth_point, depth, &mut color_point) };
142 if hr.is_ok() {
143 Ok(color_point)
144 } else {
145 Err(Error::from_hresult(hr))
146 }
147 }
148
149 pub fn map_camera_points_to_depth_space(
150 &self,
151 camera_points: &[CameraSpacePoint],
152 depth_points: &mut [DepthSpacePoint],
153 ) -> Result<(), Error> {
154 if self.ptr.is_null() {
155 return Err(Error::from_hresult(E_POINTER));
156 }
157 if camera_points.len() != depth_points.len() {
158 return Err(Error::from_hresult(E_FAIL));
159 }
160 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
161 let map_fn = vtbl.MapCameraPointsToDepthSpace.ok_or(E_FAIL)?;
162 let hr = unsafe {
163 map_fn(
164 self.ptr,
165 camera_points.len() as UINT,
166 camera_points.as_ptr(),
167 depth_points.len() as UINT,
168 depth_points.as_mut_ptr(),
169 )
170 };
171 if hr.is_ok() {
172 Ok(())
173 } else {
174 Err(Error::from_hresult(hr))
175 }
176 }
177
178 pub fn map_camera_points_to_color_space(
179 &self,
180 camera_points: &[CameraSpacePoint],
181 color_points: &mut [ColorSpacePoint],
182 ) -> Result<(), Error> {
183 if self.ptr.is_null() {
184 return Err(Error::from_hresult(E_POINTER));
185 }
186 if camera_points.len() != color_points.len() {
187 return Err(Error::from_hresult(E_FAIL));
188 }
189 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
190 let map_fn = vtbl.MapCameraPointsToColorSpace.ok_or(E_FAIL)?;
191 let hr = unsafe {
192 map_fn(
193 self.ptr,
194 camera_points.len() as UINT,
195 camera_points.as_ptr(),
196 color_points.len() as UINT,
197 color_points.as_mut_ptr(),
198 )
199 };
200 if hr.is_ok() {
201 Ok(())
202 } else {
203 Err(Error::from_hresult(hr))
204 }
205 }
206
207 pub fn map_depth_points_to_camera_space(
208 &self,
209 depth_points: &[DepthSpacePoint],
210 depths: &[UINT16],
211 camera_points: &mut [CameraSpacePoint],
212 ) -> Result<(), Error> {
213 if self.ptr.is_null() {
214 return Err(Error::from_hresult(E_POINTER));
215 }
216 if depth_points.len() != depths.len() || depth_points.len() != camera_points.len() {
217 return Err(Error::from_hresult(E_FAIL));
218 }
219 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
220 let map_fn = vtbl.MapDepthPointsToCameraSpace.ok_or(E_FAIL)?;
221 let hr = unsafe {
222 map_fn(
223 self.ptr,
224 depth_points.len() as UINT,
225 depth_points.as_ptr(),
226 depths.len() as UINT,
227 depths.as_ptr(),
228 camera_points.len() as UINT,
229 camera_points.as_mut_ptr(),
230 )
231 };
232 if hr.is_ok() {
233 Ok(())
234 } else {
235 Err(Error::from_hresult(hr))
236 }
237 }
238
239 pub fn map_depth_points_to_color_space(
240 &self,
241 depth_points: &[DepthSpacePoint],
242 depths: &[UINT16],
243 color_points: &mut [ColorSpacePoint],
244 ) -> Result<(), Error> {
245 if self.ptr.is_null() {
246 return Err(Error::from_hresult(E_POINTER));
247 }
248 if depth_points.len() != depths.len() || depth_points.len() != color_points.len() {
249 return Err(Error::from_hresult(E_FAIL));
250 }
251 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
252 let map_fn = vtbl.MapDepthPointsToColorSpace.ok_or(E_FAIL)?;
253 let hr = unsafe {
254 map_fn(
255 self.ptr,
256 depth_points.len() as UINT,
257 depth_points.as_ptr(),
258 depths.len() as UINT,
259 depths.as_ptr(),
260 color_points.len() as UINT,
261 color_points.as_mut_ptr(),
262 )
263 };
264 if hr.is_ok() {
265 Ok(())
266 } else {
267 Err(Error::from_hresult(hr))
268 }
269 }
270
271 pub fn map_depth_frame_to_camera_space(
272 &self,
273 depth_frame_data: &[UINT16],
274 camera_space_points: &mut [CameraSpacePoint],
275 ) -> Result<(), Error> {
276 if self.ptr.is_null() {
277 return Err(Error::from_hresult(E_POINTER));
278 }
279 if depth_frame_data.len() != camera_space_points.len() {
280 return Err(Error::from_hresult(E_FAIL));
281 }
282 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
283 let map_fn = vtbl.MapDepthFrameToCameraSpace.ok_or(E_FAIL)?;
284 let hr = unsafe {
285 map_fn(
286 self.ptr,
287 depth_frame_data.len() as UINT,
288 depth_frame_data.as_ptr(),
289 camera_space_points.len() as UINT,
290 camera_space_points.as_mut_ptr(),
291 )
292 };
293 if hr.is_ok() {
294 Ok(())
295 } else {
296 Err(Error::from_hresult(hr))
297 }
298 }
299
300 pub fn map_depth_frame_to_color_space(
301 &self,
302 depth_frame_data: &[UINT16],
303 color_space_points: &mut [ColorSpacePoint],
304 ) -> Result<(), Error> {
305 if self.ptr.is_null() {
306 return Err(Error::from_hresult(E_POINTER));
307 }
308 if depth_frame_data.len() != color_space_points.len() {
309 return Err(Error::from_hresult(E_FAIL));
310 }
311 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
312 let map_fn = vtbl.MapDepthFrameToColorSpace.ok_or(E_FAIL)?;
313 let hr = unsafe {
314 map_fn(
315 self.ptr,
316 depth_frame_data.len() as UINT,
317 depth_frame_data.as_ptr(),
318 color_space_points.len() as UINT,
319 color_space_points.as_mut_ptr(),
320 )
321 };
322 if hr.is_ok() {
323 Ok(())
324 } else {
325 Err(Error::from_hresult(hr))
326 }
327 }
328
329 pub fn map_color_frame_to_depth_space(
330 &self,
331 depth_frame_data: &[UINT16],
332 depth_space_points: &mut [DepthSpacePoint],
333 ) -> Result<(), Error> {
334 if self.ptr.is_null() {
335 return Err(Error::from_hresult(E_POINTER));
336 }
337 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
338 let map_fn = vtbl.MapColorFrameToDepthSpace.ok_or(E_FAIL)?;
339 let hr = unsafe {
340 map_fn(
341 self.ptr,
342 depth_frame_data.len() as UINT,
343 depth_frame_data.as_ptr(),
344 depth_space_points.len() as UINT,
345 depth_space_points.as_mut_ptr(),
346 )
347 };
348 if hr.is_ok() {
349 Ok(())
350 } else {
351 Err(Error::from_hresult(hr))
352 }
353 }
354
355 pub fn map_color_frame_to_camera_space(
356 &self,
357 depth_frame_data: &[UINT16],
358 camera_space_points: &mut [CameraSpacePoint],
359 ) -> Result<(), Error> {
360 if self.ptr.is_null() {
361 return Err(Error::from_hresult(E_POINTER));
362 }
363 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
364 let map_fn = vtbl.MapColorFrameToCameraSpace.ok_or(E_FAIL)?;
365 let hr = unsafe {
366 map_fn(
367 self.ptr,
368 depth_frame_data.len() as UINT,
369 depth_frame_data.as_ptr(),
370 camera_space_points.len() as UINT,
371 camera_space_points.as_mut_ptr(),
372 )
373 };
374 if hr.is_ok() {
375 Ok(())
376 } else {
377 Err(Error::from_hresult(hr))
378 }
379 }
380
381 pub fn get_depth_frame_to_camera_space_table(&self) -> Result<(UINT, *mut PointF), Error> {
382 if self.ptr.is_null() {
383 return Err(Error::from_hresult(E_POINTER));
384 }
385 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
386 let get_fn = vtbl.GetDepthFrameToCameraSpaceTable.ok_or(E_FAIL)?;
387 let mut table_entry_count: UINT = 0;
388 let mut table_entries: *mut PointF = ptr::null_mut();
389 let hr = unsafe { get_fn(self.ptr, &mut table_entry_count, &mut table_entries) };
390 if hr.is_ok() {
391 Ok((table_entry_count, table_entries))
392 } else {
393 Err(Error::from_hresult(hr))
394 }
395 }
396
397 pub fn get_depth_camera_intrinsics(&self) -> Result<CameraIntrinsics, Error> {
398 if self.ptr.is_null() {
399 return Err(Error::from_hresult(E_POINTER));
400 }
401 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
402 let get_fn = vtbl.GetDepthCameraIntrinsics.ok_or(E_FAIL)?;
403 let mut camera_intrinsics = CameraIntrinsics::default();
404 let hr = unsafe { get_fn(self.ptr, &mut camera_intrinsics) };
405 if hr.is_ok() {
406 Ok(camera_intrinsics)
407 } else {
408 Err(Error::from_hresult(hr))
409 }
410 }
411}
412
413impl Drop for CoordinateMapper {
414 fn drop(&mut self) {
415 if !self.ptr.is_null() {
416 unsafe {
417 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
418 if let Some(release_fn) = vtbl.Release {
419 release_fn(self.ptr);
420 }
421 }
422 }
423 self.ptr = ptr::null_mut();
424 }
425 }
426}
427
428pub struct CoordinateMappingChangedEventArgs {
429 ptr: *mut ICoordinateMappingChangedEventArgs,
430}
431
432impl CoordinateMappingChangedEventArgs {
433 pub(crate) fn new(ptr: *mut ICoordinateMappingChangedEventArgs) -> Self {
434 assert!(!ptr.is_null());
435 Self { ptr }
436 }
437}
438
439impl Drop for CoordinateMappingChangedEventArgs {
440 fn drop(&mut self) {
441 if !self.ptr.is_null() {
442 unsafe {
443 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
444 if let Some(release_fn) = vtbl.Release {
445 release_fn(self.ptr);
446 }
447 }
448 }
449 self.ptr = ptr::null_mut();
450 }
451 }
452}