`
#include "stdafx.h"
#include <strsafe.h>
#include "CHand.h"
#include "resource.h"
#include <Windows.h>
#include <NuiApi.h>
#include <NuiSensor.h>
#include <string>
#include <KinectInteraction.h>
using namespace std;
double x_cur,x_pre = 500;
double y_cur,y_pre = 500;
static const float g_JointThickness = 3.0f;
static const float g_TrackedBoneThickness = 6.0f;
static const float g_InferredBoneThickness = 1.0f;
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
CHand application;
CInteractionClient interaction;
application.Run(hInstance, nCmdShow);
}
CHand::CHand():
m_hNextSkeletonFrameEvent(INVALID_HANDLE_VALUE),
m_pSkeletonStreamHandle(INVALID_HANDLE_VALUE),
m_hNextColorFrameEvent(INVALID_HANDLE_VALUE),
m_hNextDepthFrameEvent(INVALID_HANDLE_VALUE),
m_hNextInteractionEvent(INVALID_HANDLE_VALUE),
m_pColorStreamHandle(INVALID_HANDLE_VALUE),
m_pDepthStreamHandle(INVALID_HANDLE_VALUE),
m_hEvNuiProcessStop(INVALID_HANDLE_VALUE),
m_bSeatedMode(false),
m_pNuiSensor(NULL),
m_pRenderTarget(NULL),
m_pBrushJointTracked(NULL),
m_pBrushJointInferred(NULL),
m_pBrushBoneTracked(NULL),
m_pBrushBoneInferred(NULL)
{
ZeroMemory(m_Points,sizeof(m_Points));
}
CHand::~CHand()
{
if (m_pNuiSensor)
{
m_pNuiSensor->NuiShutdown();
}
if (m_hNextSkeletonFrameEvent && (m_hNextSkeletonFrameEvent != INVALID_HANDLE_VALUE))
{
CloseHandle(m_hNextSkeletonFrameEvent);
}
DiscardDirect2DResources();
//SafeRelease(m_pD2DFactory);
//SafeRelease(m_pNuiSensor);
//SafeRelease(m_InteractionFrame);
//SafeRelease(m_InteractionStream);
CloseHandle(m_hNextColorFrameEvent);
CloseHandle(m_hEvNuiProcessStop);
CloseHandle(m_hNextDepthFrameEvent);
CloseHandle(m_hNextInteractionEvent);
CloseHandle(m_hNextSkeletonFrameEvent);
}
int CHand::Run(HINSTANCE hInstance, int nCmdShow)
{
MSG msg = {0};
WNDCLASS wc = {0};
// Dialog custom window class
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInstance;
wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
wc.hIcon = LoadIconW(hInstance, MAKEINTRESOURCE(IDD_APP));
wc.lpfnWndProc = DefDlgProcW;
wc.lpszClassName = L"SkeletonBasicsAppDlgWndClass";
if (!RegisterClassW(&wc))
{
return 0;
}
HWND hWndApp = CreateDialogParamW(
hInstance,
MAKEINTRESOURCE(IDD_APP),
NULL,
(DLGPROC)CHand::MessageRouter,
reinterpret_cast<LPARAM>(this));
ShowWindow(hWndApp, nCmdShow);
const int eventCount = 1;
//HANDLE hEvents[eventCount];
while (WM_QUIT != msg.message)
{
Update();
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
{
// If a dialog message will be taken care of by the dialog proc
if ((hWndApp != NULL) && IsDialogMessageW(hWndApp, &msg))
{
continue;
}
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return static_cast<int>(msg.wParam);
}
}
void CHand::Update()
{
if (NULL == m_pNuiSensor)
{
return;
}
/*
if (WAIT_OBJECT_0 == WaitForSingleObject(m_hEvNuiProcessStop, 0))
{
//ProcessInteraction();
}
// Process signal events
if (WAIT_OBJECT_0 == WaitForSingleObject(m_hNextColorFrameEvent, 0))
{
ProcessColorFrame();
}
*/
if (WAIT_OBJECT_0 == WaitForSingleObject(m_hNextDepthFrameEvent, 0))
{
ProcessDepthFrame();
}
if (WAIT_OBJECT_0 == WaitForSingleObject(m_hNextSkeletonFrameEvent, 0))
{
ProcessSkeleton();
}
if (WAIT_OBJECT_0 == WaitForSingleObject(m_hNextInteractionEvent, 0))
{
ProcessInteraction();
}
}
LRESULT CALLBACK CHand::DlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
// Bind application window handle
m_hWnd = hWnd;
// Init Direct2D
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2DFactory);
// Look for a connected Kinect, and create it if found
CreateFirstConnected();
}
break;
// If the titlebar X is clicked, destroy app
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
// Quit the main message pump
PostQuitMessage(0);
break;
// Handle button press
case WM_COMMAND:
// If it was for the near mode control and a clicked event, change near mode
if (IDC_SEATEDMODE == LOWORD(wParam) && BN_CLICKED == HIWORD(wParam))
{
// Toggle out internal state for near mode
m_bSeatedMode = !m_bSeatedMode;
if (NULL != m_pNuiSensor)
{
// Set near mode for sensor based on our internal state
m_pNuiSensor->NuiSkeletonTrackingEnable(m_hNextSkeletonFrameEvent,
m_bSeatedMode ? NUI_SKELETON_TRACKING_FLAG_ENABLE_SEATED_SUPPORT : 0);
}
}
break;
}
return FALSE;
}
LRESULT CALLBACK CHand::MessageRouter(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CHand* pThis = NULL;
if (WM_INITDIALOG == uMsg)
{
pThis = reinterpret_cast<CHand*>(lParam);
SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pThis));
}
else
{
pThis = reinterpret_cast<CHand*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
}
if (pThis)
{
return pThis->DlgProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
HRESULT CHand::CreateFirstConnected()
{
INuiSensor * pNuiSensor;
HRESULT hr;
int iSensorCount = 0;
hr = NuiGetSensorCount(&iSensorCount);
if (FAILED(hr))
{
return hr;
}
// Look at each Kinect sensor
for (int i = 0; i < iSensorCount; ++i)
{
// Create the sensor so we can check status, if we can't create it, move on to the next
hr = NuiCreateSensorByIndex(i, &pNuiSensor);
if (FAILED(hr))
{
continue;
}
// Get the status of the sensor, and if connected, then we can initialize it
hr = pNuiSensor->NuiStatus();
if (S_OK == hr)
{
m_pNuiSensor = pNuiSensor;
break;
}
// This sensor wasn't OK, so release it since we're not using it
pNuiSensor->Release();
}
if (NULL != m_pNuiSensor)
{
if (SUCCEEDED(hr))
{
hr = m_pNuiSensor->NuiInitialize(\
NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX|\
NUI_INITIALIZE_FLAG_USES_COLOR|\
NUI_INITIALIZE_FLAG_USES_SKELETON);
if( hr != S_OK )
{
SetStatusMessage(L"NuiInitialize failed");
return hr;
}
m_hNextColorFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_pColorStreamHandle = NULL;
hr = m_pNuiSensor->NuiImageStreamOpen(
NUI_IMAGE_TYPE_COLOR,NUI_IMAGE_RESOLUTION_640x480, 0, 2,
m_hNextColorFrameEvent, &m_pColorStreamHandle);
if( FAILED( hr ) )
{
SetStatusMessage(L"Could not open image stream video");
return hr;
}
m_hNextDepthFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_pDepthStreamHandle = NULL;
hr = m_pNuiSensor->NuiImageStreamOpen(
NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX,
NUI_IMAGE_RESOLUTION_640x480, 0, 2,
m_hNextDepthFrameEvent, &m_pDepthStreamHandle);
if( FAILED( hr ) )
{
SetStatusMessage(L"Could not open depth stream video");
return hr;
}
m_hNextSkeletonFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
hr = m_pNuiSensor->NuiSkeletonTrackingEnable(
m_hNextSkeletonFrameEvent,
NUI_SKELETON_TRACKING_FLAG_ENABLE_IN_NEAR_RANGE//|
);
if( FAILED( hr ) )
{
SetStatusMessage(L"Could not open skeleton stream video");
return hr;
}
}
}
if (NULL == m_pNuiSensor || FAILED(hr))
{
SetStatusMessage(L"No ready Kinect found!");
return E_FAIL;
}
return hr;
}
void CHand::ProcessDepthFrame()
{
NUI_IMAGE_FRAME pImageFrame = {0};
INuiFrameTexture* pDepthImagePixelFrame = 0 ;
HRESULT hr = m_pNuiSensor->NuiImageStreamGetNextFrame( pDepthImagePixelFrame, 0, &pImageFrame );
BOOL nearMode = m_bSeatedMode;
m_pNuiSensor->NuiImageFrameGetDepthImagePixelFrameTexture(m_pDepthStreamHandle, &pImageFrame,
&nearMode, &pDepthImagePixelFrame);
INuiFrameTexture * pTexture = pDepthImagePixelFrame;
NUI_LOCKED_RECT LockedRect = {0};
pTexture->LockRect( 0, &LockedRect, NULL, 0 );
if( LockedRect.Pitch != 0 )
{
HRESULT hr = m_InteractionStream ->ProcessDepth(LockedRect.size,PBYTE(LockedRect.pBits),pImageFrame.liTimeStamp);
if( FAILED( hr ) )
{
SetStatusMessage(L"ProcessDepth failed");
}
}
pTexture->UnlockRect(0);
m_pNuiSensor->NuiImageStreamReleaseFrame( m_pDepthStreamHandle, &pImageFrame );
return ;
}
void CHand::ProcessSkeleton()
{
SetMessage(L"Process Skeleton");
NUI_SKELETON_FRAME SkeletonFrame = {0};
HRESULT hr = m_pNuiSensor->NuiSkeletonGetNextFrame(0, &SkeletonFrame);
if ( FAILED(hr) )
{
return;
}
// smooth out the skeleton data
m_pNuiSensor->NuiTransformSmooth(&SkeletonFrame, NULL);
Vector4 v = {0};
m_pNuiSensor->NuiAccelerometerGetCurrentReading(&v);
hr =m_InteractionStream->ProcessSkeleton(NUI_SKELETON_COUNT, SkeletonFrame.SkeletonData, &v, SkeletonFrame.liTimeStamp);
/*
// Endure Direct2D is ready to draw
hr = EnsureDirect2DResources( );
if ( FAILED(hr) )
{
return;
}
m_pRenderTarget->BeginDraw();
m_pRenderTarget->Clear( );
RECT rct;
GetClientRect( GetDlgItem( m_hWnd, IDC_VIDEOVIEW ), &rct);
int width = rct.right;
int height = rct.bottom;
for (int i = 0 ; i < NUI_SKELETON_COUNT; ++i)
{
NUI_SKELETON_TRACKING_STATE trackingState = SkeletonFrame.SkeletonData[i].eTrackingState;
if (NUI_SKELETON_TRACKED == trackingState)
{
// We're tracking the skeleton, draw it
DrawSkeleton(SkeletonFrame.SkeletonData[i], width, height);
}
else if (NUI_SKELETON_POSITION_ONLY == trackingState)
{
// we've only received the center point of the skeleton, draw that
D2D1_ELLIPSE ellipse = D2D1::Ellipse(
SkeletonToScreen(skeletonFrame.SkeletonData[i].Position, width, height),
g_JointThickness,
g_JointThickness
);
m_pRenderTarget->DrawEllipse(ellipse, m_pBrushJointTracked);
}
}
hr = m_pRenderTarget->EndDraw();
// Device lost, need to recreate the render target
// We'll dispose it now and retry drawing
if (D2DERR_RECREATE_TARGET == hr)
{
hr = S_OK;
DiscardDirect2DResources();
}
*/
if( FAILED( hr ) )
{
SetStatusMessage(L"Process Skeleton failed");
}
return;
}
void CHand::ProcessInteraction()
{
NUI_INTERACTION_FRAME Interaction_Frame = {0};
m_InteractionStream->GetNextFrame( 0,&Interaction_Frame );
int trackingID = 0;
int Event =0 ;
SetStatusMessage(L"show Interactions!");
for(int i=0;i<NUI_SKELETON_COUNT;i++)
{
trackingID = Interaction_Frame.UserInfos[i].SkeletonTrackingId;
Event = Interaction_Frame.UserInfos[i].HandPointerInfos->HandEventType;
if (trackingID != 0 )
{
if (Event == NUI_HAND_EVENT_TYPE::NUI_HAND_EVENT_TYPE_GRIP)
{
SetStatusMessage(L"Grip");
}
if (Event == NUI_HAND_EVENT_TYPE::NUI_HAND_EVENT_TYPE_GRIPRELEASE)
{
SetStatusMessage(L"Release");
}
}
}
}
`