kinect_v2_sys/
coordinate.rs

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}