/// <summary> /// Handle new body data /// <param name="nTime">timestamp of frame</param> /// <param name="nBodyCount">body data count</param> /// <param name="ppBodies">body data in frame</param> /// </summary> void CBodyBasics::ProcessBody(INT64 nTime, int nBodyCount, IBody** ppBodies) { if (m_hWnd) { HRESULT hr = EnsureDirect2DResources(); DetectionResult nEngaged[6] = { DetectionResult_Unknown }; int width = 0; int height = 0; if (SUCCEEDED(hr) && m_pRenderTarget && m_pCoordinateMapper) { m_pRenderTarget->BeginDraw(); m_pRenderTarget->Clear(); RECT rct; GetClientRect(GetDlgItem(m_hWnd, IDC_VIDEOVIEW), &rct); width = rct.right; height = rct.bottom; for (int i = 0; i < nBodyCount; ++i) { nEngaged[i] = DetectionResult_Maybe; IBody* pBody = ppBodies[i]; if (pBody) { BOOLEAN bTracked = false; hr = pBody->get_IsTracked(&bTracked); // Engaged()は使えるみたい。これは、視野に入ってきた人を認識するものだろう。 hr = pBody->get_Engaged( &nEngaged[i] ); // 以下はまだ使えないようだ //hr = pBody->GetAppearanceDetectionResults((UINT)i, &nEngaged[i]); if (SUCCEEDED(hr) && bTracked) { Joint joints[JointType_Count]; D2D1_POINT_2F jointPoints[JointType_Count]; HandState leftHandState = HandState_Unknown; HandState rightHandState = HandState_Unknown; pBody->get_HandLeftState(&leftHandState); pBody->get_HandRightState(&rightHandState); hr = pBody->GetJoints(_countof(joints), joints); if (SUCCEEDED(hr)) { for (int j = 0; j < _countof(joints); ++j) { jointPoints[j] = BodyToScreen(joints[j].Position, width, height); } DrawBody(joints, jointPoints); // ここに頭部に丸を描いて、ボディ番号を表示 DrawHead(jointPoints[JointType_Head], i, nEngaged[i]); DrawHand(leftHandState, jointPoints[JointType_HandLeft]); DrawHand(rightHandState, jointPoints[JointType_HandRight]); } } } } 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 (!m_nStartTime) { m_nStartTime = nTime; } double fps = 0.0; LARGE_INTEGER qpcNow = {0}; if (m_fFreq) { if (QueryPerformanceCounter(&qpcNow)) { if (m_nLastCounter) { m_nFramesSinceUpdate++; fps = m_fFreq * m_nFramesSinceUpdate / double(qpcNow.QuadPart - m_nLastCounter); } } } WCHAR szStatusMessage[128] ; StringCchPrintf( szStatusMessage, _countof(szStatusMessage), L" FPS = %0.2f Time = %I64d width:%d height:%d", fps, (nTime - m_nStartTime), width, height); if (SetStatusMessage(szStatusMessage, 1000, false)) { m_nLastCounter = qpcNow.QuadPart; m_nFramesSinceUpdate = 0; } } }
/// <summary> /// Handle new body data /// <param name="nTime">timestamp of frame</param> /// <param name="nBodyCount">body data count</param> /// <param name="ppBodies">body data in frame</param> /// </summary> void CColorBasics::ProcessBody(INT64 nTime, int nBodyCount, IBody** ppBodies) { if (m_hWnd) { HRESULT hr = S_OK; D2D1_POINT_2F start; start.x = 1500.0; start.y = 800.0; D2D1_POINT_2F quit; quit.x = 300.0; quit.y = 800.0; //int width = 0; //int height = 0; if (SUCCEEDED(hr) && m_pCoordinateMapper) { // 先に実行しているProcessColor()にて行っているのでコメント //hr = m_pDrawColor->BeginDraw(); DetectionResult nEngaged[6] = { DetectionResult_Unknown }; PointF lean; //RECT rct; //GetClientRect(GetDlgItem(m_hWnd, IDC_VIDEOVIEW), &rct); //width = rct.right; //height = rct.bottom; UINT64 nTrackBody = 10; for (int i = 0; i < nBodyCount; ++i) { IBody* pBody = ppBodies[i]; if (pBody) { // 手旗二人での対戦モードを想定してインデックスを取得する。 // 本来はゲーム前に対戦の二人wフィックスしておくべきだろうが。 // // トラッキングされているボディかはちゃんと確かめること。 BOOLEAN bTracked = false; hr = pBody->get_IsTracked(&bTracked); // Engaged()は使えるみたい。これは、視野に入ってきた人を認識するものだろう。 hr = pBody->get_Engaged(&nEngaged[i]); pBody->get_Lean(&lean); // 以下はまだ使えないようだ //hr = pBody->GetAppearanceDetectionResults((UINT)i, &nEngaged[i]); if (SUCCEEDED(hr) && bTracked) { // トラッキングが無効な場合のインデックスは0が返るので使い方に注意!! UINT64 nBodyIndex = 0; hr = pBody->get_TrackingId(&nBodyIndex); Joint joints[JointType_Count]; D2D1_POINT_2F jointPoints[JointType_Count]; HandState leftHandState = HandState_Unknown; HandState rightHandState = HandState_Unknown; pBody->get_HandLeftState(&leftHandState); pBody->get_HandRightState(&rightHandState); hr = pBody->GetJoints(_countof(joints), joints); if (SUCCEEDED(hr)) { // スクリーン座標に変換 for (int j = 0; j < _countof(joints); ++j) { jointPoints[j] = BodyToScreen(joints[j].Position); } // ここに頭部に丸を描いて、ボディ番号を表示 m_pDrawColor->DrawHead(jointPoints[JointType_Head], i, nEngaged[i], lean); // 手先がある領域にきたら実行 // ボタンのような // 現状、複数人が認識されても実行するので、本来は最初に認識された一人のみにする必要がある。 float xy[2] = { 0.0 }; if (!m_bSemaphore) { if (m_pSemaphore[0]) { delete m_pSemaphore[0]; m_pSemaphore[0] = NULL; } if (m_pSemaphore[1]) { delete m_pSemaphore[1]; m_pSemaphore[1] = NULL; } m_nButton = 1; xy[0] = jointPoints[JointType_HandTipRight].x - start.x; xy[1] = jointPoints[JointType_HandTipRight].y - start.y; if (sqrt( xy[0]*xy[0] + xy[1]*xy[1] ) < 100.0 ) { if (nTrackBody == 10 || nTrackBody == nBodyIndex) { m_nButton = 0; nTrackBody = nBodyIndex; } } } else { // 手旗スタート // 手旗判定 if (m_pSemaphore[0] == NULL) { m_pSemaphore[0] = new Semaphore( &nBodyIndex ); } else { if (m_pSemaphore[1] == NULL && !m_pSemaphore[0]->ItsMe(&nBodyIndex)) { m_pSemaphore[1] = new Semaphore(&nBodyIndex); } } // カウント // 基本ポーズでのデータ取得 // 手旗本番処理 // 手旗の判定に画像と同等のフレームは必要はないのでは。 // タイマーでBodyフレームを取得し、それで手旗判定を行う。 if (m_pSemaphore[0]) { m_pSemaphore[0]->SetSignalType(&nBodyIndex, jointPoints, m_pDrawColor); } if (m_pSemaphore[1]) { m_pSemaphore[1]->SetSignalType(&nBodyIndex, jointPoints, m_pDrawColor); } //m_pSemaphore[0]->Practice(nTime, jointPoints, m_pDrawColor); // quitボタン処理 m_nButton = 2; // 基本ポーズ用の表示 xy[0] = jointPoints[JointType_HandTipLeft].x - quit.x; xy[1] = jointPoints[JointType_HandTipLeft].y - quit.y; if (sqrt( xy[0]*xy[0] + xy[1]*xy[1] ) < 100.0 ) { if (nTrackBody == 10 || nTrackBody == nBodyIndex) { m_nButton = 0; nTrackBody = nBodyIndex; } } } m_pDrawColor->DrawBody(joints, jointPoints); //m_pDrawColor->DrawHand(leftHandState, jointPoints[JointType_HandLeft]); //m_pDrawColor->DrawHand(rightHandState, jointPoints[JointType_HandRight]); Detect(pBody); //break; } } } } if (!m_bSemaphore) { // このボタン処理でウィンドウにメッセージを送っている m_pDrawColor->DrawButton(start, m_nButton); } else { m_pDrawColor->DrawButton(quit, m_nButton); } // 二人対戦モードのお題表示 if (Question(nTime)) { m_pDrawColor->DrawButton(quit, 0); } m_pDrawColor->EndDraw(); } } }