@@ -17,9 +17,7 @@ inline void (*status_changed_event)();
1717class  KinectWrapper 
1818{
1919    IKinectSensor* kinectSensor = nullptr ;
20-     IBodyFrameReader* bodyFrameReader = nullptr ;
21-     IColorFrameReader* colorFrameReader = nullptr ;
22-     IDepthFrameReader* depthFrameReader = nullptr ;
20+     IMultiSourceFrameReader* multiFrameReader = nullptr ;
2321    IMultiSourceFrame* multiFrame = nullptr ;
2422    ICoordinateMapper* coordMapper = nullptr ;
2523    BOOLEAN isTracking = false ;
@@ -29,9 +27,7 @@ class KinectWrapper
2927    IBody* kinectBodies[BODY_COUNT] = {nullptr };
3028
3129    WAITABLE_HANDLE h_statusChangedEvent;
32-     WAITABLE_HANDLE h_bodyFrameEvent;
33-     WAITABLE_HANDLE h_colorFrameEvent;
34-     bool  newBodyFrameArrived = false ;
30+     WAITABLE_HANDLE h_multiFrameEvent;
3531
3632    std::array<JointOrientation, JointType_Count> bone_orientations_;
3733    std::array<Joint, JointType_Count> skeleton_positions_;
@@ -48,17 +44,28 @@ class KinectWrapper
4844        while  (true )update ();
4945    }
5046
51-     void  updateSkeletalData ( )
47+     void  updateFrameData (IMultiSourceFrameArrivedEventArgs* args )
5248    {
53-         if  (!bodyFrameReader)return ; //  Give up already
49+         if  (!multiFrameReader) return ; //  Give up already
50+ 
51+         //  Acquire the multi-source frame reference
52+         IMultiSourceFrameReference* frameReference = nullptr ;
53+         args->get_FrameReference (&frameReference);
54+ 
55+         IMultiSourceFrame* multiFrame = nullptr ;
56+         frameReference->AcquireFrame (&multiFrame);
57+ 
58+         if  (!multiFrame) return ;
59+ 
60+         //  Get the body frame and process it
61+         IBodyFrameReference* bodyFrameReference = nullptr ;
62+         multiFrame->get_BodyFrameReference (&bodyFrameReference);
5463
5564        IBodyFrame* bodyFrame = nullptr ;
56-         bodyFrameReader-> AcquireLatestFrame (&bodyFrame);
65+         bodyFrameReference-> AcquireFrame (&bodyFrame);
5766
5867        if  (!bodyFrame) return ;
59- 
6068        bodyFrame->GetAndRefreshBodyData (BODY_COUNT, kinectBodies);
61-         newBodyFrameArrived = true ;
6269        if  (bodyFrame) bodyFrame->Release ();
6370
6471        //  We have the frame, now parse it
@@ -75,28 +82,32 @@ class KinectWrapper
7582
7683                //  Copy joint positions & orientations
7784                std::copy (std::begin (joints), std::end (joints),
78-                            skeleton_positions_.begin ());
85+                     skeleton_positions_.begin ());
7986                std::copy (std::begin (boneOrientations), std::end (boneOrientations),
80-                            bone_orientations_.begin ());
87+                     bone_orientations_.begin ());
8188
8289                break ;
8390            }
8491            skeleton_tracked_ = false ;
8592        }
86-     }
8793
88-     void  updateColorData ()
89-     {
90-         if  (!colorFrameReader)return ; //  Give up already
94+         //  Don't process color if not requested
95+         if  (!camera_enabled ()) return ;
96+         
97+         //  Get the color frame and process it
98+         IColorFrameReference* colorFrameReference = nullptr ;
99+         multiFrame->get_ColorFrameReference (&colorFrameReference);
91100
92101        IColorFrame* colorFrame = nullptr ;
93-         colorFrameReader-> AcquireLatestFrame (&colorFrame);
102+         colorFrameReference-> AcquireFrame (&colorFrame);
94103
95104        if  (!colorFrame) return ;
96105        ResetBuffer (CameraBufferSize ()); //  Allocate buffer for image for copy
97106
98107        colorFrame->CopyConvertedFrameDataToArray (
99108            CameraBufferSize (), color_buffer_, ColorImageFormat_Bgra);
109+ 
110+         if  (colorFrame) colorFrame->Release ();
100111    }
101112
102113    bool  initKinect ()
@@ -114,6 +125,11 @@ class KinectWrapper
114125            BOOLEAN available = false ;
115126            kinectSensor->get_IsAvailable (&available);
116127
128+ #ifdef  _DEBUG
129+             //  Emulation support bypass
130+             available = true ;
131+ #endif 
132+ 
117133            //  Check the sensor (just in case)
118134            if  (FAILED (hr_open) || !available || kinectSensor == nullptr )
119135            {
@@ -130,76 +146,38 @@ class KinectWrapper
130146        return  false ;
131147    }
132148
133-     void  initializeSkeleton ()
134-     {
135-         if  (bodyFrameReader)
136-             bodyFrameReader->Release ();
137- 
138-         IBodyFrameSource* bodyFrameSource;
139-         kinectSensor->get_BodyFrameSource (&bodyFrameSource);
140-         bodyFrameSource->OpenReader (&bodyFrameReader);
141- 
142-         //  Newfangled event based frame capture
143-         //  https://github.com/StevenHickson/PCL_Kinect2SDK/blob/master/src/Microsoft_grabber2.cpp
144-         h_bodyFrameEvent = (WAITABLE_HANDLE)CreateEvent (nullptr , FALSE , FALSE , nullptr );
145-         bodyFrameReader->SubscribeFrameArrived (&h_bodyFrameEvent);
146-         if  (bodyFrameSource) bodyFrameSource->Release ();
147-     }
148- 
149-     void  initializeColor ()
149+     void  initializeFrameReader ()
150150    {
151-         if  (colorFrameReader )
152-             colorFrameReader ->Release ();
151+         if  (multiFrameReader )
152+             multiFrameReader ->Release ();
153153
154-         IColorFrameSource* colorFrameSource;
155-         kinectSensor->get_ColorFrameSource (&colorFrameSource);
156-         colorFrameSource->OpenReader (&colorFrameReader);
154+         kinectSensor->OpenMultiSourceFrameReader (
155+             FrameSourceTypes_Body | FrameSourceTypes_Color, &multiFrameReader);
157156
158157        //  Newfangled event based frame capture
159158        //  https://github.com/StevenHickson/PCL_Kinect2SDK/blob/master/src/Microsoft_grabber2.cpp
160-         h_colorFrameEvent = (WAITABLE_HANDLE)CreateEvent (nullptr , FALSE , FALSE , nullptr );
161-         colorFrameReader->SubscribeFrameArrived (&h_colorFrameEvent);
162-         if  (colorFrameSource) colorFrameSource->Release ();
159+         h_multiFrameEvent = (WAITABLE_HANDLE)CreateEvent (nullptr , FALSE , FALSE , nullptr );
160+         multiFrameReader->SubscribeMultiSourceFrameArrived (&h_multiFrameEvent);
163161    }
164162
165-     void  terminateSkeleton ()
163+     void  terminateMultiFrame ()
166164    {
167-         if  (!bodyFrameReader )return ; //  No need to do anything
168-         if  (FAILED (bodyFrameReader-> UnsubscribeFrameArrived (h_bodyFrameEvent )))
165+         if  (!multiFrameReader )return ; //  No need to do anything
166+         if  (FAILED (multiFrameReader-> UnsubscribeMultiSourceFrameArrived (h_multiFrameEvent )))
169167        {
170168            throw  std::exception (" Couldn't unsubscribe frame!"  );
171169        }
172170        __try
173171        {
174-             CloseHandle ((HANDLE)h_bodyFrameEvent );
175-             bodyFrameReader ->Release ();
172+             CloseHandle ((HANDLE)h_multiFrameEvent );
173+             multiFrameReader ->Release ();
176174        }
177175        __except  (EXCEPTION_EXECUTE_HANDLER)
178176        {
179177            //  ignored
180178        }
181-         h_bodyFrameEvent = NULL ;
182-         bodyFrameReader = nullptr ;
183-     }
184- 
185-     void  terminateColor ()
186-     {
187-         if  (!colorFrameReader)return ; //  No need to do anything
188-         if  (FAILED (colorFrameReader->UnsubscribeFrameArrived (h_colorFrameEvent)))
189-         {
190-             throw  std::exception (" Couldn't unsubscribe frame!"  );
191-         }
192-         __try
193-         {
194-             CloseHandle ((HANDLE)h_colorFrameEvent);
195-             colorFrameReader->Release ();
196-         }
197-         __except  (EXCEPTION_EXECUTE_HANDLER)
198-         {
199-             //  ignored
200-         }
201-         h_colorFrameEvent = NULL ;
202-         colorFrameReader = nullptr ;
179+         h_multiFrameEvent = NULL ;
180+         multiFrameReader = nullptr ;
203181    }
204182
205183    HRESULT kinect_status_result ()
@@ -277,28 +255,35 @@ class KinectWrapper
277255public: 
278256    bool  is_initialized ()
279257    {
258+ #ifdef  _DEBUG
259+         return  true ;
260+ #else 
280261        return  initialized_;
262+ #endif 
281263    }
282264
283265    HRESULT status_result ()
284266    {
267+ #ifdef  _DEBUG
268+         return  0 ;
269+ #else 
285270        switch  (kinect_status_result ())
286271        {
287272        case  S_OK: return  0 ;
288273        case  S_FALSE: return  1 ;
289274        default : return  -1 ;
290275        }
276+ #endif 
291277    }
292278
293279    int  initialize ()
294280    {
295281        try 
296282        {
297283            initialized_ = initKinect ();
298-             if  (!initialized_ ) return  1 ;
284+             if  (!is_initialized () ) return  1 ;
299285
300-             initializeSkeleton ();
301-             initializeColor ();
286+             initializeFrameReader ();
302287
303288            //  Recreate the updater thread
304289            if  (!updater_thread_)
@@ -324,56 +309,50 @@ class KinectWrapper
324309                {
325310                    BOOLEAN isAvailable = false ;
326311                    args->get_IsAvailable (&isAvailable);
312+ 
313+ #ifdef  _DEBUG
314+                     //  Emulation support bypass
315+                     isAvailable = true ;
316+ #endif 
317+ 
327318                    initialized_ = isAvailable; //  Update the status
328319                    status_changed_event (); //  Notify the CLR listener
329320                }
330321            }
331322        });
332323
333324        //  Update (only if the sensor is on and its status is ok)
334-         if  (initialized_  && kinectSensor)
325+         if  (is_initialized ()  && kinectSensor)
335326        {
336327            BOOLEAN isAvailable = false ;
337328            HRESULT kinectStatus = kinectSensor->get_IsAvailable (&isAvailable);
329+ 
330+ #ifdef  _DEBUG
331+             //  Emulation support bypass
332+             isAvailable = true ;
333+ #endif 
334+ 
338335            if  (kinectStatus == S_OK)
339336            {
340337                //  NEW ARRIVED FRAMES ------------------------
341338                MSG msg;
342339                while  (PeekMessage (&msg, nullptr , 0 , 0 , PM_REMOVE)) //  Unnecessary?
343340                    DispatchMessage (&msg);
344341
345-                 if  (h_bodyFrameEvent )
346-                     if  (HANDLE handles[] = {reinterpret_cast <HANDLE>(h_bodyFrameEvent )};
342+                 if  (h_multiFrameEvent )
343+                     if  (HANDLE handles[] = {reinterpret_cast <HANDLE>(h_multiFrameEvent )};
347344                        //  Wait for a frame to arrive, give up after >3s of nothing
348345                        MsgWaitForMultipleObjects (_countof (handles), handles,
349-                                                   false , 3000 , QS_ALLINPUT) == WAIT_OBJECT_0)
346+                                                   false , 100 , QS_ALLINPUT) == WAIT_OBJECT_0)
350347                    {
351-                         IBodyFrameArrivedEventArgs * pArgs = nullptr ;
352-                         if  (bodyFrameReader  &&
353-                             SUCCEEDED (bodyFrameReader-> GetFrameArrivedEventData (h_bodyFrameEvent , &pArgs)))
348+                         IMultiSourceFrameArrivedEventArgs * pArgs = nullptr ;
349+                         if  (multiFrameReader  &&
350+                             SUCCEEDED (multiFrameReader-> GetMultiSourceFrameArrivedEventData (h_multiFrameEvent , &pArgs)))
354351                        {
355-                             [&,this ](IBodyFrameReader & sender, IBodyFrameArrivedEventArgs & eventArgs)
352+                             [&,this ](IMultiSourceFrameReader & sender, IMultiSourceFrameArrivedEventArgs & eventArgs)
356353                            {
357-                                 updateSkeletalData ();
358-                             }(*bodyFrameReader, *pArgs);
359-                             pArgs->Release (); //  Release the frame
360-                         }
361-                     }
362- 
363-                 if  (h_colorFrameEvent && rgb_stream_enabled_)
364-                     if  (HANDLE handles[] = {reinterpret_cast <HANDLE>(h_colorFrameEvent)};
365-                         //  Wait for a frame to arrive, give up after >3s of nothing
366-                         MsgWaitForMultipleObjects (_countof (handles), handles,
367-                                                   false , 3000 , QS_ALLINPUT) == WAIT_OBJECT_0)
368-                     {
369-                         IColorFrameArrivedEventArgs* pArgs = nullptr ;
370-                         if  (colorFrameReader &&
371-                             SUCCEEDED (colorFrameReader->GetFrameArrivedEventData (h_colorFrameEvent, &pArgs)))
372-                         {
373-                             [&,this ](IColorFrameReader& sender, IColorFrameArrivedEventArgs& eventArgs)
374-                             {
375-                                 updateColorData ();
376-                             }(*colorFrameReader, *pArgs);
354+                                 updateFrameData (&eventArgs);
355+                             }(*multiFrameReader, *pArgs);
377356                            pArgs->Release (); //  Release the frame
378357                        }
379358                    }
@@ -389,8 +368,7 @@ class KinectWrapper
389368            if  (kinectSensor)
390369            {
391370                //  Protect from null call
392-                 terminateSkeleton ();
393-                 terminateColor ();
371+                 terminateMultiFrame ();
394372
395373                return  [&, this ]
396374                {
@@ -486,8 +464,11 @@ class KinectWrapper
486464
487465    std::pair<int , int > MapCoordinate (const  CameraSpacePoint& skeletonPoint)
488466    {
467+         auto  _skeletonPoint = skeletonPoint;
468+         if  (_skeletonPoint.Z  < 0 ) _skeletonPoint.Z  = 0 .1f ;
469+ 
489470        ColorSpacePoint spacePoint; //  Holds the mapped coordinate
490-         const  auto & result = coordMapper->MapCameraPointToColorSpace (skeletonPoint , &spacePoint);
471+         const  auto & result = coordMapper->MapCameraPointToColorSpace (_skeletonPoint , &spacePoint);
491472
492473        return  SUCCEEDED (result) && !std::isnan (spacePoint.X ) && !std::isnan (spacePoint.Y )
493474                   ? std::make_pair (spacePoint.X , spacePoint.Y ) //  Send the mapped ones
@@ -501,6 +482,7 @@ class KinectWrapper
501482
502483    BYTE* ResetBuffer (UINT size)
503484    {
485+         size_in_bytes_last_ = size;
504486        if  (!color_buffer_ || size_in_bytes_ != size)
505487        {
506488            if  (color_buffer_)
0 commit comments