1use crate::bindings::{
2 self, BOOLEAN, CreateBodyHandPair, DetectionResult, FrameEdges, HandState, HandType, IBody,
3 IBodyFrame, IBodyFrameArrivedEventArgs, IBodyFrameReader, IBodyFrameReference,
4 IBodyFrameSource, IBodyHandPair, IFrameCapturedEventArgs, IKinectSensor, INT32, Joint,
5 JointOrientation, TIMESPAN, TrackingConfidence, UINT, WAITABLE_HANDLE,
6};
7use crate::frame::FrameCapturedEventArgs;
8use crate::kinect::KinectSensor;
9use std::ptr;
10use windows::Win32::Foundation::{E_FAIL, E_POINTER};
11use windows::core::Error;
12
13pub struct Body {
14 ptr: *mut IBody,
15}
16
17impl Body {
18 pub(crate) fn new(ptr: *mut IBody) -> Self {
19 assert!(!ptr.is_null());
20 Self { ptr }
21 }
22
23 pub fn get_joints(&self, joints: &mut [Joint]) -> Result<(), Error> {
24 if self.ptr.is_null() {
25 return Err(Error::from_hresult(E_POINTER));
26 }
27 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
28 let get_fn = vtbl.GetJoints.ok_or(E_FAIL)?;
29 let capacity = joints.len() as UINT;
30 let hr = unsafe { get_fn(self.ptr, capacity, joints.as_mut_ptr()) };
31 if hr.is_ok() {
32 Ok(())
33 } else {
34 Err(Error::from_hresult(hr))
35 }
36 }
37
38 pub fn get_joint_orientations(
39 &self,
40 joint_orientations: &mut [JointOrientation],
41 ) -> Result<(), Error> {
42 if self.ptr.is_null() {
43 return Err(Error::from_hresult(E_POINTER));
44 }
45 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
46 let get_fn = vtbl.GetJointOrientations.ok_or(E_FAIL)?;
47 let capacity = joint_orientations.len() as UINT;
48 let hr = unsafe { get_fn(self.ptr, capacity, joint_orientations.as_mut_ptr()) };
49 if hr.is_ok() {
50 Ok(())
51 } else {
52 Err(Error::from_hresult(hr))
53 }
54 }
55
56 pub fn get_engaged(&self) -> Result<DetectionResult, 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.get_Engaged.ok_or(E_FAIL)?;
62 let mut detection_result: DetectionResult = unsafe { std::mem::zeroed() };
63 let hr = unsafe { get_fn(self.ptr, &mut detection_result) };
64 if hr.is_ok() {
65 Ok(detection_result)
66 } else {
67 Err(Error::from_hresult(hr))
68 }
69 }
70
71 pub fn get_expression_detection_results(
72 &self,
73 detection_results: &mut [DetectionResult],
74 ) -> Result<(), 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 get_fn = vtbl.GetExpressionDetectionResults.ok_or(E_FAIL)?;
80 let capacity = detection_results.len() as UINT;
81 let hr = unsafe { get_fn(self.ptr, capacity, detection_results.as_mut_ptr()) };
82 if hr.is_ok() {
83 Ok(())
84 } else {
85 Err(Error::from_hresult(hr))
86 }
87 }
88
89 pub fn get_activity_detection_results(
90 &self,
91 detection_results: &mut [DetectionResult],
92 ) -> Result<(), 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 get_fn = vtbl.GetActivityDetectionResults.ok_or(E_FAIL)?;
98 let capacity = detection_results.len() as UINT;
99 let hr = unsafe { get_fn(self.ptr, capacity, detection_results.as_mut_ptr()) };
100 if hr.is_ok() {
101 Ok(())
102 } else {
103 Err(Error::from_hresult(hr))
104 }
105 }
106
107 pub fn get_appearance_detection_results(
108 &self,
109 detection_results: &mut [DetectionResult],
110 ) -> Result<(), Error> {
111 if self.ptr.is_null() {
112 return Err(Error::from_hresult(E_POINTER));
113 }
114 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
115 let get_fn = vtbl.GetAppearanceDetectionResults.ok_or(E_FAIL)?;
116 let capacity = detection_results.len() as UINT;
117 let hr = unsafe { get_fn(self.ptr, capacity, detection_results.as_mut_ptr()) };
118 if hr.is_ok() {
119 Ok(())
120 } else {
121 Err(Error::from_hresult(hr))
122 }
123 }
124
125 pub fn get_hand_left_state(&self) -> Result<HandState, Error> {
126 if self.ptr.is_null() {
127 return Err(Error::from_hresult(E_POINTER));
128 }
129 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
130 let get_fn = vtbl.get_HandLeftState.ok_or(E_FAIL)?;
131 let mut hand_state: HandState = unsafe { std::mem::zeroed() };
132 let hr = unsafe { get_fn(self.ptr, &mut hand_state) };
133 if hr.is_ok() {
134 Ok(hand_state)
135 } else {
136 Err(Error::from_hresult(hr))
137 }
138 }
139
140 pub fn get_hand_left_confidence(&self) -> Result<TrackingConfidence, Error> {
141 if self.ptr.is_null() {
142 return Err(Error::from_hresult(E_POINTER));
143 }
144 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
145 let get_fn = vtbl.get_HandLeftConfidence.ok_or(E_FAIL)?;
146 let mut confidence: TrackingConfidence = unsafe { std::mem::zeroed() };
147 let hr = unsafe { get_fn(self.ptr, &mut confidence) };
148 if hr.is_ok() {
149 Ok(confidence)
150 } else {
151 Err(Error::from_hresult(hr))
152 }
153 }
154
155 pub fn get_hand_right_state(&self) -> Result<HandState, Error> {
156 if self.ptr.is_null() {
157 return Err(Error::from_hresult(E_POINTER));
158 }
159 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
160 let get_fn = vtbl.get_HandRightState.ok_or(E_FAIL)?;
161 let mut hand_state: HandState = unsafe { std::mem::zeroed() };
162 let hr = unsafe { get_fn(self.ptr, &mut hand_state) };
163 if hr.is_ok() {
164 Ok(hand_state)
165 } else {
166 Err(Error::from_hresult(hr))
167 }
168 }
169
170 pub fn get_hand_right_confidence(&self) -> Result<TrackingConfidence, Error> {
171 if self.ptr.is_null() {
172 return Err(Error::from_hresult(E_POINTER));
173 }
174 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
175 let get_fn = vtbl.get_HandRightConfidence.ok_or(E_FAIL)?;
176 let mut confidence: TrackingConfidence = unsafe { std::mem::zeroed() };
177 let hr = unsafe { get_fn(self.ptr, &mut confidence) };
178 if hr.is_ok() {
179 Ok(confidence)
180 } else {
181 Err(Error::from_hresult(hr))
182 }
183 }
184
185 pub fn get_clipped_edges(&self) -> Result<FrameEdges, Error> {
186 if self.ptr.is_null() {
187 return Err(Error::from_hresult(E_POINTER));
188 }
189 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
190 let get_fn = vtbl.get_ClippedEdges.ok_or(E_FAIL)?;
191 let mut clipped_edges: FrameEdges = unsafe { std::mem::zeroed() };
192 let hr = unsafe { get_fn(self.ptr, &mut clipped_edges) };
193 if hr.is_ok() {
194 Ok(clipped_edges)
195 } else {
196 Err(Error::from_hresult(hr))
197 }
198 }
199
200 pub fn get_tracking_id(&self) -> Result<u64, Error> {
201 if self.ptr.is_null() {
202 return Err(Error::from_hresult(E_POINTER));
203 }
204 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
205 let get_fn = vtbl.get_TrackingId.ok_or(E_FAIL)?;
206 let mut tracking_id: bindings::UINT64 = 0;
207 let hr = unsafe { get_fn(self.ptr, &mut tracking_id) };
208 if hr.is_ok() {
209 Ok(tracking_id)
210 } else {
211 Err(Error::from_hresult(hr))
212 }
213 }
214
215 pub fn get_is_tracked(&self) -> Result<bool, Error> {
216 if self.ptr.is_null() {
217 return Err(Error::from_hresult(E_POINTER));
218 }
219 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
220 let get_fn = vtbl.get_IsTracked.ok_or(E_FAIL)?;
221 let mut tracked: BOOLEAN = 0;
222 let hr = unsafe { get_fn(self.ptr, &mut tracked) };
223 if hr.is_ok() {
224 Ok(tracked != 0)
225 } else {
226 Err(Error::from_hresult(hr))
227 }
228 }
229
230 pub fn get_is_restricted(&self) -> Result<bool, Error> {
231 if self.ptr.is_null() {
232 return Err(Error::from_hresult(E_POINTER));
233 }
234 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
235 let get_fn = vtbl.get_IsRestricted.ok_or(E_FAIL)?;
236 let mut is_restricted: BOOLEAN = 0;
237 let hr = unsafe { get_fn(self.ptr, &mut is_restricted) };
238 if hr.is_ok() {
239 Ok(is_restricted != 0)
240 } else {
241 Err(Error::from_hresult(hr))
242 }
243 }
244
245 pub fn get_lean(&self) -> Result<bindings::PointF, Error> {
246 if self.ptr.is_null() {
247 return Err(Error::from_hresult(E_POINTER));
248 }
249 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
250 let get_fn = vtbl.get_Lean.ok_or(E_FAIL)?;
251 let mut amount: bindings::PointF = unsafe { std::mem::zeroed() };
252 let hr = unsafe { get_fn(self.ptr, &mut amount) };
253 if hr.is_ok() {
254 Ok(amount)
255 } else {
256 Err(Error::from_hresult(hr))
257 }
258 }
259
260 pub fn get_lean_tracking_state(&self) -> Result<bindings::TrackingState, Error> {
261 if self.ptr.is_null() {
262 return Err(Error::from_hresult(E_POINTER));
263 }
264 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
265 let get_fn = vtbl.get_LeanTrackingState.ok_or(E_FAIL)?;
266 let mut tracking_state: bindings::TrackingState = unsafe { std::mem::zeroed() };
267 let hr = unsafe { get_fn(self.ptr, &mut tracking_state) };
268 if hr.is_ok() {
269 Ok(tracking_state)
270 } else {
271 Err(Error::from_hresult(hr))
272 }
273 }
274}
275
276impl Drop for Body {
277 fn drop(&mut self) {
278 if !self.ptr.is_null() {
279 unsafe {
280 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
281 if let Some(release_fn) = vtbl.Release {
282 release_fn(self.ptr);
283 }
284 }
285 }
286 self.ptr = ptr::null_mut();
287 }
288 }
289}
290
291pub struct BodyHandPair {
292 ptr: *mut IBodyHandPair,
293}
294
295impl BodyHandPair {
296 pub(crate) fn new(ptr: *mut IBodyHandPair) -> Self {
297 assert!(!ptr.is_null());
298 Self { ptr }
299 }
300
301 pub fn get_body_tracking_id(&self) -> Result<u64, Error> {
302 if self.ptr.is_null() {
303 return Err(Error::from_hresult(E_POINTER));
304 }
305 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
306 let get_fn = vtbl.get_BodyTrackingId.ok_or(E_FAIL)?;
307 let mut value: bindings::UINT64 = 0;
308 let hr = unsafe { get_fn(self.ptr, &mut value) };
309 if hr.is_ok() {
310 Ok(value)
311 } else {
312 Err(Error::from_hresult(hr))
313 }
314 }
315
316 pub fn put_body_tracking_id(&self, value: u64) -> Result<(), Error> {
317 if self.ptr.is_null() {
318 return Err(Error::from_hresult(E_POINTER));
319 }
320 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
321 let put_fn = vtbl.put_BodyTrackingId.ok_or(E_FAIL)?;
322 let hr = unsafe { put_fn(self.ptr, value) };
323 if hr.is_ok() {
324 Ok(())
325 } else {
326 Err(Error::from_hresult(hr))
327 }
328 }
329
330 pub fn get_hand_type(&self) -> Result<HandType, Error> {
331 if self.ptr.is_null() {
332 return Err(Error::from_hresult(E_POINTER));
333 }
334 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
335 let get_fn = vtbl.get_HandType.ok_or(E_FAIL)?;
336 let mut value: HandType = unsafe { std::mem::zeroed() };
337 let hr = unsafe { get_fn(self.ptr, &mut value) };
338 if hr.is_ok() {
339 Ok(value)
340 } else {
341 Err(Error::from_hresult(hr))
342 }
343 }
344
345 pub fn put_hand_type(&self, value: HandType) -> Result<(), Error> {
346 if self.ptr.is_null() {
347 return Err(Error::from_hresult(E_POINTER));
348 }
349 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
350 let put_fn = vtbl.put_HandType.ok_or(E_FAIL)?;
351 let hr = unsafe { put_fn(self.ptr, value) };
352 if hr.is_ok() {
353 Ok(())
354 } else {
355 Err(Error::from_hresult(hr))
356 }
357 }
358}
359
360impl Drop for BodyHandPair {
361 fn drop(&mut self) {
362 if !self.ptr.is_null() {
363 unsafe {
364 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
365 if let Some(release_fn) = vtbl.Release {
366 release_fn(self.ptr);
367 }
368 }
369 }
370 self.ptr = ptr::null_mut();
371 }
372 }
373}
374
375pub struct BodyFrameSource {
376 ptr: *mut IBodyFrameSource,
377}
378impl BodyFrameSource {
379 pub(crate) fn new(ptr: *mut IBodyFrameSource) -> Self {
380 assert!(!ptr.is_null());
381 Self { ptr }
382 }
383
384 pub fn subscribe_frame_captured(
385 &self,
386 waitable_handle: &mut WAITABLE_HANDLE,
387 ) -> Result<(), Error> {
388 if self.ptr.is_null() {
389 return Err(Error::from_hresult(E_POINTER));
390 }
391 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
392 let sub_fn = vtbl.SubscribeFrameCaptured.ok_or(E_FAIL)?;
393 let hr = unsafe { sub_fn(self.ptr, waitable_handle) };
394 if hr.is_ok() {
395 Ok(())
396 } else {
397 Err(Error::from_hresult(hr))
398 }
399 }
400
401 pub fn unsubscribe_frame_captured(&self, handle: WAITABLE_HANDLE) -> Result<(), Error> {
402 if self.ptr.is_null() {
403 return Err(Error::from_hresult(E_POINTER));
404 }
405 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
406 let unsub_fn = vtbl.UnsubscribeFrameCaptured.ok_or(E_FAIL)?;
407 let hr = unsafe { unsub_fn(self.ptr, handle) };
408 if hr.is_ok() {
409 Ok(())
410 } else {
411 Err(Error::from_hresult(hr))
412 }
413 }
414
415 pub fn get_frame_captured_event_data(
416 &self,
417 handle: WAITABLE_HANDLE,
418 ) -> Result<FrameCapturedEventArgs, Error> {
419 if self.ptr.is_null() {
420 return Err(Error::from_hresult(E_POINTER));
421 }
422 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
423 let get_fn = vtbl.GetFrameCapturedEventData.ok_or(E_FAIL)?;
424 let mut event_data_ptr: *mut IFrameCapturedEventArgs = ptr::null_mut();
425 let hr = unsafe { get_fn(self.ptr, handle, &mut event_data_ptr) };
426 if hr.is_ok() {
427 if event_data_ptr.is_null() {
428 return Err(Error::from_hresult(E_FAIL));
429 }
430 Ok(FrameCapturedEventArgs::new(event_data_ptr))
431 } else {
432 Err(Error::from_hresult(hr))
433 }
434 }
435
436 pub fn get_is_active(&self) -> Result<bool, Error> {
437 if self.ptr.is_null() {
438 return Err(Error::from_hresult(E_POINTER));
439 }
440 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
441 let get_fn = vtbl.get_IsActive.ok_or(E_FAIL)?;
442 let mut is_active: BOOLEAN = 0;
443 let hr = unsafe { get_fn(self.ptr, &mut is_active) };
444 if hr.is_ok() {
445 Ok(is_active != 0)
446 } else {
447 Err(Error::from_hresult(hr))
448 }
449 }
450
451 pub fn get_body_count(&self) -> Result<i32, Error> {
452 if self.ptr.is_null() {
453 return Err(Error::from_hresult(E_POINTER));
454 }
455 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
456 let get_fn = vtbl.get_BodyCount.ok_or(E_FAIL)?;
457 let mut count: INT32 = 0;
458 let hr = unsafe { get_fn(self.ptr, &mut count) };
459 if hr.is_ok() {
460 Ok(count)
461 } else {
462 Err(Error::from_hresult(hr))
463 }
464 }
465
466 pub fn open_reader(&self) -> Result<BodyFrameReader, Error> {
467 if self.ptr.is_null() {
468 return Err(Error::from_hresult(E_POINTER));
469 }
470 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
471 let open_fn = vtbl.OpenReader.ok_or(E_FAIL)?;
472 let mut reader_ptr: *mut IBodyFrameReader = ptr::null_mut();
473 let hr = unsafe { open_fn(self.ptr, &mut reader_ptr) };
474 if hr.is_ok() {
475 if reader_ptr.is_null() {
476 return Err(Error::from_hresult(E_FAIL));
477 }
478 Ok(BodyFrameReader::new(reader_ptr))
479 } else {
480 Err(Error::from_hresult(hr))
481 }
482 }
483
484 pub fn get_kinect_sensor(&self) -> Result<KinectSensor, Error> {
485 if self.ptr.is_null() {
486 return Err(Error::from_hresult(E_POINTER));
487 }
488 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
489 let get_fn = vtbl.get_KinectSensor.ok_or(E_FAIL)?;
490 let mut sensor_ptr: *mut IKinectSensor = ptr::null_mut();
491 let hr = unsafe { get_fn(self.ptr, &mut sensor_ptr) };
492 if hr.is_ok() {
493 if sensor_ptr.is_null() {
494 return Err(Error::from_hresult(E_FAIL));
495 }
496 Ok(KinectSensor::new(sensor_ptr))
497 } else {
498 Err(Error::from_hresult(hr))
499 }
500 }
501
502 pub fn override_hand_tracking(&self, tracking_id: u64) -> Result<(), Error> {
503 if self.ptr.is_null() {
504 return Err(Error::from_hresult(E_POINTER));
505 }
506 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
507 let override_fn = vtbl.OverrideHandTracking.ok_or(E_FAIL)?;
508 let hr = unsafe { override_fn(self.ptr, tracking_id) };
509 if hr.is_ok() {
510 Ok(())
511 } else {
512 Err(Error::from_hresult(hr))
513 }
514 }
515
516 pub fn override_and_replace_hand_tracking(
517 &self,
518 old_tracking_id: u64,
519 new_tracking_id: u64,
520 ) -> Result<(), Error> {
521 if self.ptr.is_null() {
522 return Err(Error::from_hresult(E_POINTER));
523 }
524 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
525 let override_fn = vtbl.OverrideAndReplaceHandTracking.ok_or(E_FAIL)?;
526 let hr = unsafe { override_fn(self.ptr, old_tracking_id, new_tracking_id) };
527 if hr.is_ok() {
528 Ok(())
529 } else {
530 Err(Error::from_hresult(hr))
531 }
532 }
533}
534impl Drop for BodyFrameSource {
535 fn drop(&mut self) {
536 if !self.ptr.is_null() {
537 unsafe {
538 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
539 if let Some(release_fn) = vtbl.Release {
540 release_fn(self.ptr);
541 }
542 }
543 }
544 self.ptr = ptr::null_mut();
545 }
546 }
547}
548
549pub struct BodyFrameReference {
550 ptr: *mut IBodyFrameReference,
551}
552
553impl BodyFrameReference {
554 pub(crate) fn new(ptr: *mut IBodyFrameReference) -> Self {
555 assert!(!ptr.is_null());
556 Self { ptr }
557 }
558
559 pub fn acquire_frame(&self) -> Result<BodyFrame, Error> {
560 if self.ptr.is_null() {
561 return Err(Error::from_hresult(E_POINTER));
562 }
563 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
564 let acquire_fn = vtbl.AcquireFrame.ok_or(E_FAIL)?;
565 let mut frame_ptr: *mut IBodyFrame = ptr::null_mut();
566 let hr = unsafe { acquire_fn(self.ptr, &mut frame_ptr) };
567 if hr.is_ok() {
568 if frame_ptr.is_null() {
569 return Err(Error::from_hresult(E_FAIL));
570 }
571 Ok(BodyFrame::new(frame_ptr))
572 } else {
573 Err(Error::from_hresult(hr))
574 }
575 }
576
577 pub fn get_relative_time(&self) -> Result<TIMESPAN, Error> {
578 if self.ptr.is_null() {
579 return Err(Error::from_hresult(E_POINTER));
580 }
581 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
582 let get_fn = vtbl.get_RelativeTime.ok_or(E_FAIL)?;
583 let mut time: TIMESPAN = 0;
584 let hr = unsafe { get_fn(self.ptr, &mut time) };
585 if hr.is_ok() {
586 Ok(time)
587 } else {
588 Err(Error::from_hresult(hr))
589 }
590 }
591}
592impl Drop for BodyFrameReference {
593 fn drop(&mut self) {
594 if !self.ptr.is_null() {
595 unsafe {
596 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
597 if let Some(release_fn) = vtbl.Release {
598 release_fn(self.ptr);
599 }
600 }
601 }
602 self.ptr = ptr::null_mut();
603 }
604 }
605}
606
607pub struct BodyFrameReader {
608 ptr: *mut IBodyFrameReader,
609}
610
611impl BodyFrameReader {
612 pub(crate) fn new(ptr: *mut IBodyFrameReader) -> Self {
613 assert!(!ptr.is_null());
614 Self { ptr }
615 }
616
617 pub fn acquire_latest_frame(&self) -> Result<BodyFrame, Error> {
618 if self.ptr.is_null() {
619 return Err(Error::from_hresult(E_POINTER));
620 }
621 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
622 let acquire_fn = vtbl.AcquireLatestFrame.ok_or(E_FAIL)?;
623 let mut frame_ptr: *mut IBodyFrame = ptr::null_mut();
624 let hr = unsafe { acquire_fn(self.ptr, &mut frame_ptr) };
625 if hr.is_ok() {
626 if frame_ptr.is_null() {
627 return Err(Error::from_hresult(hr));
628 }
629 Ok(BodyFrame::new(frame_ptr))
630 } else {
631 Err(Error::from_hresult(hr))
632 }
633 }
634
635 pub fn subscribe_frame_arrived(
636 &self,
637 waitable_handle: &mut WAITABLE_HANDLE,
638 ) -> Result<(), Error> {
639 if self.ptr.is_null() {
640 return Err(Error::from_hresult(E_POINTER));
641 }
642 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
643 let sub_fn = vtbl.SubscribeFrameArrived.ok_or(E_FAIL)?;
644 let hr = unsafe { sub_fn(self.ptr, waitable_handle) };
645 if hr.is_ok() {
646 Ok(())
647 } else {
648 Err(Error::from_hresult(hr))
649 }
650 }
651
652 pub fn unsubscribe_frame_arrived(&self, handle: WAITABLE_HANDLE) -> Result<(), Error> {
653 if self.ptr.is_null() {
654 return Err(Error::from_hresult(E_POINTER));
655 }
656 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
657 let unsub_fn = vtbl.UnsubscribeFrameArrived.ok_or(E_FAIL)?;
658 let hr = unsafe { unsub_fn(self.ptr, handle) };
659 if hr.is_ok() {
660 Ok(())
661 } else {
662 Err(Error::from_hresult(hr))
663 }
664 }
665
666 pub fn get_frame_arrived_event_data(
667 &self,
668 handle: WAITABLE_HANDLE,
669 ) -> Result<BodyFrameArrivedEventArgs, Error> {
670 if self.ptr.is_null() {
671 return Err(Error::from_hresult(E_POINTER));
672 }
673 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
674 let get_fn = vtbl.GetFrameArrivedEventData.ok_or(E_FAIL)?;
675 let mut event_data_ptr: *mut IBodyFrameArrivedEventArgs = ptr::null_mut();
676 let hr = unsafe { get_fn(self.ptr, handle, &mut event_data_ptr) };
677 if hr.is_ok() {
678 if event_data_ptr.is_null() {
679 return Err(Error::from_hresult(E_FAIL));
680 }
681 Ok(BodyFrameArrivedEventArgs::new(event_data_ptr))
682 } else {
683 Err(Error::from_hresult(hr))
684 }
685 }
686
687 pub fn get_is_paused(&self) -> Result<bool, Error> {
688 if self.ptr.is_null() {
689 return Err(Error::from_hresult(E_POINTER));
690 }
691 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
692 let get_fn = vtbl.get_IsPaused.ok_or(E_FAIL)?;
693 let mut is_paused: BOOLEAN = 0;
694 let hr = unsafe { get_fn(self.ptr, &mut is_paused) };
695 if hr.is_ok() {
696 Ok(is_paused != 0)
697 } else {
698 Err(Error::from_hresult(hr))
699 }
700 }
701
702 pub fn put_is_paused(&self, is_paused: bool) -> Result<(), Error> {
703 if self.ptr.is_null() {
704 return Err(Error::from_hresult(E_POINTER));
705 }
706 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
707 let put_fn = vtbl.put_IsPaused.ok_or(E_FAIL)?;
708 let hr = unsafe { put_fn(self.ptr, is_paused as BOOLEAN) };
709 if hr.is_ok() {
710 Ok(())
711 } else {
712 Err(Error::from_hresult(hr))
713 }
714 }
715
716 pub fn get_body_frame_source(&self) -> Result<BodyFrameSource, Error> {
717 if self.ptr.is_null() {
718 return Err(Error::from_hresult(E_POINTER));
719 }
720 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
721 let get_fn = vtbl.get_BodyFrameSource.ok_or(E_FAIL)?;
722 let mut source_ptr: *mut IBodyFrameSource = ptr::null_mut();
723 let hr = unsafe { get_fn(self.ptr, &mut source_ptr) };
724 if hr.is_ok() {
725 if source_ptr.is_null() {
726 return Err(Error::from_hresult(E_FAIL));
727 }
728 Ok(BodyFrameSource::new(source_ptr))
729 } else {
730 Err(Error::from_hresult(hr))
731 }
732 }
733}
734impl Drop for BodyFrameReader {
735 fn drop(&mut self) {
736 if !self.ptr.is_null() {
737 unsafe {
738 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
739 if let Some(release_fn) = vtbl.Release {
740 release_fn(self.ptr);
741 }
742 }
743 }
744 self.ptr = ptr::null_mut();
745 }
746 }
747}
748
749pub struct BodyFrame {
750 ptr: *mut IBodyFrame,
751}
752
753impl BodyFrame {
754 pub(crate) fn new(ptr: *mut IBodyFrame) -> Self {
755 assert!(!ptr.is_null());
756 Self { ptr }
757 }
758
759 pub fn get_floor_clip_plane(&self) -> Result<bindings::Vector4, Error> {
760 if self.ptr.is_null() {
761 return Err(Error::from_hresult(E_POINTER));
762 }
763 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
764 let get_fn = vtbl.get_FloorClipPlane.ok_or(E_FAIL)?;
765 let mut floor_clip_plane: bindings::Vector4 = unsafe { std::mem::zeroed() };
766 let hr = unsafe { get_fn(self.ptr, &mut floor_clip_plane) };
767 if hr.is_ok() {
768 Ok(floor_clip_plane)
769 } else {
770 Err(Error::from_hresult(hr))
771 }
772 }
773 pub fn get_and_refresh_body_data(&self) -> Result<Vec<Body>, Error> {
774 if self.ptr.is_null() {
775 return Err(Error::from_hresult(E_POINTER));
776 }
777
778 let body_source = self.get_body_frame_source()?;
780 let body_count = body_source.get_body_count()? as usize;
781
782 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
783 let get_fn = vtbl.GetAndRefreshBodyData.ok_or(E_FAIL)?;
784
785 let mut raw_ptrs: Vec<*mut IBody> = vec![ptr::null_mut(); body_count];
787 let hr = unsafe { get_fn(self.ptr, body_count as UINT, raw_ptrs.as_mut_ptr()) };
788
789 if hr.is_ok() {
790 let bodies: Vec<Body> = raw_ptrs
792 .into_iter()
793 .filter(|&ptr| !ptr.is_null())
794 .map(Body::new)
795 .collect();
796 Ok(bodies)
797 } else {
798 Err(Error::from_hresult(hr))
799 }
800 }
801
802 pub fn get_body_frame_source(&self) -> Result<BodyFrameSource, Error> {
803 if self.ptr.is_null() {
804 return Err(Error::from_hresult(E_POINTER));
805 }
806 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
807 let get_fn = vtbl.get_BodyFrameSource.ok_or(E_FAIL)?;
808 let mut source_ptr: *mut IBodyFrameSource = ptr::null_mut();
809 let hr = unsafe { get_fn(self.ptr, &mut source_ptr) };
810 if hr.is_ok() {
811 if source_ptr.is_null() {
812 return Err(Error::from_hresult(E_FAIL));
813 }
814 Ok(BodyFrameSource::new(source_ptr))
815 } else {
816 Err(Error::from_hresult(hr))
817 }
818 }
819
820 pub fn get_relative_time(&self) -> Result<TIMESPAN, Error> {
821 if self.ptr.is_null() {
822 return Err(Error::from_hresult(E_POINTER));
823 }
824 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
825 let get_fn = vtbl.get_RelativeTime.ok_or(E_FAIL)?;
826 let mut time: TIMESPAN = 0;
827 let hr = unsafe { get_fn(self.ptr, &mut time) };
828 if hr.is_ok() {
829 Ok(time)
830 } else {
831 Err(Error::from_hresult(hr))
832 }
833 }
834}
835impl Drop for BodyFrame {
836 fn drop(&mut self) {
837 if !self.ptr.is_null() {
838 unsafe {
839 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
840 if let Some(release_fn) = vtbl.Release {
841 release_fn(self.ptr);
842 }
843 }
844 }
845 self.ptr = ptr::null_mut();
846 }
847 }
848}
849
850pub struct BodyFrameArrivedEventArgs {
851 ptr: *mut IBodyFrameArrivedEventArgs,
852}
853
854impl BodyFrameArrivedEventArgs {
855 pub(crate) fn new(ptr: *mut IBodyFrameArrivedEventArgs) -> Self {
856 assert!(!ptr.is_null());
857 Self { ptr }
858 }
859
860 pub fn get_frame_reference(&self) -> Result<BodyFrameReference, Error> {
861 if self.ptr.is_null() {
862 return Err(Error::from_hresult(E_POINTER));
863 }
864 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or(E_POINTER)?;
865 let get_fn = vtbl.get_FrameReference.ok_or(E_FAIL)?;
866 let mut frame_ref_ptr: *mut IBodyFrameReference = ptr::null_mut();
867 let hr = unsafe { get_fn(self.ptr, &mut frame_ref_ptr) };
868 if hr.is_ok() {
869 if frame_ref_ptr.is_null() {
870 return Err(Error::from_hresult(E_FAIL));
871 }
872 Ok(BodyFrameReference::new(frame_ref_ptr))
873 } else {
874 Err(Error::from_hresult(hr))
875 }
876 }
877}
878
879impl Drop for BodyFrameArrivedEventArgs {
880 fn drop(&mut self) {
881 if !self.ptr.is_null() {
882 unsafe {
883 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref() {
884 if let Some(release_fn) = vtbl.Release {
885 release_fn(self.ptr);
886 }
887 }
888 }
889 self.ptr = ptr::null_mut();
890 }
891 }
892}
893
894pub fn create_body_hand_pair(
895 body_tracking_id: u64,
896 hand_type: HandType,
897) -> Result<BodyHandPair, Error> {
898 let mut pair_ptr: *mut IBodyHandPair = ptr::null_mut();
899 let hr = unsafe { CreateBodyHandPair(body_tracking_id, hand_type, &mut pair_ptr) };
900 if hr.is_ok() {
901 if pair_ptr.is_null() {
902 Err(Error::from_hresult(E_POINTER))
903 } else {
904 Ok(BodyHandPair::new(pair_ptr))
905 }
906 } else {
907 Err(Error::from_hresult(hr))
908 }
909}