Files
LiveScan3D/src/LiveScanClient/liveScanClient.cpp
T

812 lines
21 KiB
C++

// Copyright (C) 2015 Marek Kowalski (M.Kowalski@ire.pw.edu.pl), Jacek Naruniec (J.Naruniec@ire.pw.edu.pl)
// License: MIT Software License See LICENSE.txt for the full license.
// If you use this software in your research, then please use the following citation:
// Kowalski, M.; Naruniec, J.; Daniluk, M.: "LiveScan3D: A Fast and Inexpensive 3D Data
// Acquisition System for Multiple Kinect v2 Sensors". in 3D Vision (3DV), 2015 International Conference on, Lyon, France, 2015
// @INPROCEEDINGS{Kowalski15,
// author={Kowalski, M. and Naruniec, J. and Daniluk, M.},
// booktitle={3D Vision (3DV), 2015 International Conference on},
// title={LiveScan3D: A Fast and Inexpensive 3D Data Acquisition System for Multiple Kinect v2 Sensors},
// year={2015},
// }
#include "stdafx.h"
#include "resource.h"
#include "LiveScanClient.h"
#include "filter.h"
#include <chrono>
#include <strsafe.h>
#include <fstream>
std::mutex m_mSocketThreadMutex;
int APIENTRY wWinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nShowCmd
)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
LiveScanClient application;
application.Run(hInstance, nShowCmd);
}
LiveScanClient::LiveScanClient() :
m_hWnd(NULL),
m_nLastCounter(0),
m_nFramesSinceUpdate(0),
m_fFreq(0),
m_nNextStatusTime(0LL),
m_pD2DFactory(NULL),
m_pDrawColor(NULL),
m_pDepthRGBX(NULL),
m_pCameraSpaceCoordinates(NULL),
m_pColorCoordinatesOfDepth(NULL),
m_pDepthCoordinatesOfColor(NULL),
m_bCalibrate(false),
m_bFilter(false),
m_bStreamOnlyBodies(false),
m_bCaptureFrame(false),
m_bConnected(false),
m_bConfirmCaptured(false),
m_bConfirmCalibrated(false),
m_bShowDepth(false),
m_bSocketThread(true),
m_pClientSocket(NULL),
m_nFilterNeighbors(10),
m_fFilterThreshold(0.01f)
{
pCapture = new KinectCapture();
LARGE_INTEGER qpf = {0};
if (QueryPerformanceFrequency(&qpf))
{
m_fFreq = double(qpf.QuadPart);
}
m_vBounds.push_back(-0.5);
m_vBounds.push_back(-0.5);
m_vBounds.push_back(-0.5);
m_vBounds.push_back(0.5);
m_vBounds.push_back(0.5);
m_vBounds.push_back(0.5);
}
LiveScanClient::~LiveScanClient()
{
// clean up Direct2D renderer
if (m_pDrawColor)
{
delete m_pDrawColor;
m_pDrawColor = NULL;
}
if (pCapture)
{
delete pCapture;
pCapture = NULL;
}
if (m_pDepthRGBX)
{
delete[] m_pDepthRGBX;
m_pDepthRGBX = NULL;
}
if (m_pCameraSpaceCoordinates)
{
delete[] m_pCameraSpaceCoordinates;
m_pCameraSpaceCoordinates = NULL;
}
if (m_pColorCoordinatesOfDepth)
{
delete[] m_pColorCoordinatesOfDepth;
m_pColorCoordinatesOfDepth = NULL;
}
if (m_pDepthCoordinatesOfColor)
{
delete[] m_pDepthCoordinatesOfColor;
m_pDepthCoordinatesOfColor = NULL;
}
if (m_pClientSocket)
{
delete m_pClientSocket;
m_pClientSocket = NULL;
}
// clean up Direct2D
SafeRelease(m_pD2DFactory);
}
int LiveScanClient::Run(HINSTANCE hInstance, int nCmdShow)
{
MSG msg = {0};
WNDCLASS wc;
// Dialog custom window class
ZeroMemory(&wc, sizeof(wc));
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
wc.hIcon = LoadIconW(hInstance, MAKEINTRESOURCE(IDI_APP));
wc.lpfnWndProc = DefDlgProcW;
wc.lpszClassName = L"LiveScanClientAppDlgWndClass";
if (!RegisterClassW(&wc))
{
return 0;
}
// Create main application window
HWND hWndApp = CreateDialogParamW(
NULL,
MAKEINTRESOURCE(IDD_APP),
NULL,
(DLGPROC)LiveScanClient::MessageRouter,
reinterpret_cast<LPARAM>(this));
// Show window
ShowWindow(hWndApp, nCmdShow);
std::thread t1(&LiveScanClient::SocketThreadFunction, this);
// Main message loop
while (WM_QUIT != msg.message)
{
//HandleSocket();
UpdateFrame();
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
{
// If a dialog message will be taken care of by the dialog proc
if (hWndApp && IsDialogMessageW(hWndApp, &msg))
{
continue;
}
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
m_bSocketThread = false;
t1.join();
return static_cast<int>(msg.wParam);
}
void LiveScanClient::UpdateFrame()
{
if (!pCapture->bInitialized)
{
return;
}
bool bNewFrameAcquired = pCapture->AcquireFrame();
if (!bNewFrameAcquired)
return;
pCapture->MapDepthFrameToCameraSpace(m_pCameraSpaceCoordinates);
pCapture->MapDepthFrameToColorSpace(m_pColorCoordinatesOfDepth);
{
std::lock_guard<std::mutex> lock(m_mSocketThreadMutex);
StoreFrame(m_pCameraSpaceCoordinates, m_pColorCoordinatesOfDepth, pCapture->pColorRGBX, pCapture->vBodies, pCapture->pBodyIndex);
if (m_bCaptureFrame)
{
m_vGatheredVertices.push_back(m_vLastFrameVertices);
m_vGatheredRGBPoints.push_back(m_vLastFrameRGB);
m_bConfirmCaptured = true;
m_bCaptureFrame = false;
}
}
if (m_bCalibrate)
{
std::lock_guard<std::mutex> lock(m_mSocketThreadMutex);
Point3f *pCameraCoordinates = new Point3f[pCapture->nColorFrameWidth * pCapture->nColorFrameHeight];
pCapture->MapColorFrameToCameraSpace(pCameraCoordinates);
bool res = calibration.Calibrate(pCapture->pColorRGBX, pCameraCoordinates, pCapture->nColorFrameWidth, pCapture->nColorFrameHeight);
delete[] pCameraCoordinates;
if (res)
{
m_bConfirmCalibrated = true;
m_bCalibrate = false;
}
}
if (!m_bShowDepth)
ProcessColor(pCapture->pColorRGBX, pCapture->nColorFrameWidth, pCapture->nColorFrameHeight);
else
ProcessDepth(pCapture->pDepth, pCapture->nDepthFrameWidth, pCapture->nDepthFrameHeight);
ShowFPS();
}
LRESULT CALLBACK LiveScanClient::MessageRouter(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LiveScanClient* pThis = NULL;
if (WM_INITDIALOG == uMsg)
{
pThis = reinterpret_cast<LiveScanClient*>(lParam);
SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pThis));
}
else
{
pThis = reinterpret_cast<LiveScanClient*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
}
if (pThis)
{
return pThis->DlgProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK LiveScanClient::DlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(wParam);
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
{
// Bind application window handle
m_hWnd = hWnd;
// Init Direct2D
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2DFactory);
// Get and initialize the default Kinect sensor
bool res = pCapture->Initialize();
if (res)
{
m_pDepthRGBX = new RGB[pCapture->nColorFrameWidth * pCapture->nColorFrameHeight];
m_pCameraSpaceCoordinates = new Point3f[pCapture->nDepthFrameWidth * pCapture->nDepthFrameHeight];
m_pColorCoordinatesOfDepth = new Point2f[pCapture->nDepthFrameWidth * pCapture->nDepthFrameHeight];
m_pDepthCoordinatesOfColor = new Point2f[pCapture->nColorFrameWidth * pCapture->nColorFrameHeight];
}
else
{
SetStatusMessage(L"Capture device failed to initialize!", 10000, true);
}
// Create and initialize a new Direct2D image renderer (take a look at ImageRenderer.h)
// We'll use this to draw the data we receive from the Kinect to the screen
HRESULT hr;
m_pDrawColor = new ImageRenderer();
hr = m_pDrawColor->Initialize(GetDlgItem(m_hWnd, IDC_VIDEOVIEW), m_pD2DFactory, pCapture->nColorFrameWidth, pCapture->nColorFrameHeight, pCapture->nColorFrameWidth * sizeof(RGB));
if (FAILED(hr))
{
SetStatusMessage(L"Failed to initialize the Direct2D draw device.", 10000, true);
}
ReadIPFromFile();
}
break;
// If the titlebar X is clicked, destroy app
case WM_CLOSE:
WriteIPToFile();
DestroyWindow(hWnd);
break;
case WM_DESTROY:
// Quit the main message pump
PostQuitMessage(0);
break;
// Handle button press
case WM_COMMAND:
if (IDC_BUTTON_CONNECT == LOWORD(wParam) && BN_CLICKED == HIWORD(wParam))
{
std::lock_guard<std::mutex> lock(m_mSocketThreadMutex);
if (m_bConnected)
{
delete m_pClientSocket;
m_pClientSocket = NULL;
m_bConnected = false;
SetDlgItemTextA(m_hWnd, IDC_BUTTON_CONNECT, "Connect");
}
else
{
m_vGatheredVertices.clear();
m_vGatheredRGBPoints.clear();
try
{
char address[20];
GetDlgItemTextA(m_hWnd, IDC_IP, address, 20);
m_pClientSocket = new SocketClient(address, 48001);
m_bConnected = true;
SetDlgItemTextA(m_hWnd, IDC_BUTTON_CONNECT, "Disconnect");
//Clear the status bar so that the "Failed to connect..." disappears.
SetStatusMessage(L"", 1, true);
}
catch (...)
{
SetStatusMessage(L"Failed to connect. Did you start the server?", 10000, true);
}
}
}
if (IDC_BUTTON_SWITCH == LOWORD(wParam) && BN_CLICKED == HIWORD(wParam))
{
m_bShowDepth = !m_bShowDepth;
if (m_bShowDepth)
{
SetDlgItemTextA(m_hWnd, IDC_BUTTON_SWITCH, "Show color");
}
else
{
SetDlgItemTextA(m_hWnd, IDC_BUTTON_SWITCH, "Show depth");
}
}
break;
}
return FALSE;
}
void LiveScanClient::ProcessDepth(const UINT16* pBuffer, int nWidth, int nHeight)
{
// Make sure we've received valid data
if (m_pDepthRGBX && m_pDepthCoordinatesOfColor && pBuffer && (nWidth == pCapture->nDepthFrameWidth) && (nHeight == pCapture->nDepthFrameHeight))
{
// end pixel is start + width*height - 1
const UINT16* pBufferEnd = pBuffer + (nWidth * nHeight);
pCapture->MapColorFrameToDepthSpace(m_pDepthCoordinatesOfColor);
for (int i = 0; i < pCapture->nColorFrameWidth * pCapture->nColorFrameHeight; i++)
{
Point2f depthPoint = m_pDepthCoordinatesOfColor[i];
BYTE intensity = 0;
if (depthPoint.X >= 0 && depthPoint.Y >= 0)
{
int depthIdx = (int)(depthPoint.X + depthPoint.Y * pCapture->nDepthFrameWidth);
USHORT depth = pBuffer[depthIdx];
intensity = static_cast<BYTE>(depth % 256);
}
m_pDepthRGBX[i].rgbRed = intensity;
m_pDepthRGBX[i].rgbGreen = intensity;
m_pDepthRGBX[i].rgbBlue = intensity;
}
// Draw the data with Direct2D
m_pDrawColor->Draw(reinterpret_cast<BYTE*>(m_pDepthRGBX), pCapture->nColorFrameWidth * pCapture->nColorFrameHeight * sizeof(RGB), pCapture->vBodies);
}
}
void LiveScanClient::ProcessColor(RGB* pBuffer, int nWidth, int nHeight)
{
// Make sure we've received valid data
if (pBuffer && (nWidth == pCapture->nColorFrameWidth) && (nHeight == pCapture->nColorFrameHeight))
{
// Draw the data with Direct2D
m_pDrawColor->Draw(reinterpret_cast<BYTE*>(pBuffer), pCapture->nColorFrameWidth * pCapture->nColorFrameHeight * sizeof(RGB), pCapture->vBodies);
}
}
bool LiveScanClient::SetStatusMessage(_In_z_ WCHAR* szMessage, DWORD nShowTimeMsec, bool bForce)
{
INT64 now = GetTickCount64();
if (m_hWnd && (bForce || (m_nNextStatusTime <= now)))
{
SetDlgItemText(m_hWnd, IDC_STATUS, szMessage);
m_nNextStatusTime = now + nShowTimeMsec;
return true;
}
return false;
}
void LiveScanClient::SocketThreadFunction()
{
while (m_bSocketThread)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
HandleSocket();
}
}
void LiveScanClient::HandleSocket()
{
char byteToSend;
std::lock_guard<std::mutex> lock(m_mSocketThreadMutex);
if (!m_bConnected)
{
return;
}
string received = m_pClientSocket->ReceiveBytes();
for (unsigned int i = 0; i < received.length(); i++)
{
//capture a frame
if (received[i] == MSG_CAPTURE_FRAME)
m_bCaptureFrame = true;
//calibrate
else if (received[i] == MSG_CALIBRATE)
m_bCalibrate = true;
//receive settings
//TODO: what if packet is split?
else if (received[i] == MSG_RECEIVE_SETTINGS)
{
vector<float> bounds(6);
i++;
int nBytes = *(int*)(received.c_str() + i);
i += sizeof(int);
for (int j = 0; j < 6; j++)
{
bounds[j] = *(float*)(received.c_str() + i);
i += sizeof(float);
}
m_bFilter = (received[i]!=0);
i++;
m_nFilterNeighbors = *(int*)(received.c_str() + i);
i += sizeof(int);
m_fFilterThreshold = *(float*)(received.c_str() + i);
i += sizeof(float);
m_vBounds = bounds;
int nMarkers = *(int*)(received.c_str() + i);
i += sizeof(int);
calibration.markerPoses.resize(nMarkers);
for (int j = 0; j < nMarkers; j++)
{
for (int k = 0; k < 3; k++)
{
for (int l = 0; l < 3; l++)
{
calibration.markerPoses[j].R[k][l] = *(float*)(received.c_str() + i);
i += sizeof(float);
}
}
for (int k = 0; k < 3; k++)
{
calibration.markerPoses[j].t[k] = *(float*)(received.c_str() + i);
i += sizeof(float);
}
calibration.markerPoses[j].markerId = *(int*)(received.c_str() + i);
i += sizeof(int);
}
m_bStreamOnlyBodies = (received[i] != 0);
i++;
//so that we do not lose the next character in the stream
i--;
}
//send stored frame
else if (received[i] == MSG_REQUEST_STORED_FRAME)
{
byteToSend = MSG_STORED_FRAME;
m_pClientSocket->SendBytes(&byteToSend, 1);
if (m_vGatheredRGBPoints.size() > 0)
{
SendFrame(m_vGatheredVertices[0], m_vGatheredRGBPoints[0], m_vLastFrameBody);
m_vGatheredRGBPoints.erase(m_vGatheredRGBPoints.begin(), m_vGatheredRGBPoints.begin() + 1);
m_vGatheredVertices.erase(m_vGatheredVertices.begin(), m_vGatheredVertices.begin() + 1);
}
else
{
int size = -1;
m_pClientSocket->SendBytes((char*)&size, 4);
}
}
//send last frame
else if (received[i] == MSG_REQUEST_LAST_FRAME)
{
byteToSend = MSG_LAST_FRAME;
m_pClientSocket->SendBytes(&byteToSend, 1);
SendFrame(m_vLastFrameVertices, m_vLastFrameRGB, m_vLastFrameBody);
}
//receive calibration data
else if (received[i] == MSG_RECEIVE_CALIBRATION)
{
i++;
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 3; k++)
{
calibration.worldR[j][k] = *(float*)(received.c_str() + i);
i += sizeof(float);
}
}
for (int j = 0; j < 3; j++)
{
calibration.worldT[j] = *(float*)(received.c_str() + i);
i += sizeof(float);
}
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 3; k++)
{
calibration.cameraR[j][k] = *(float*)(received.c_str() + i);
i += sizeof(float);
}
}
for (int j = 0; j < 3; j++)
{
calibration.cameraT[j] = *(float*)(received.c_str() + i);
i += sizeof(float);
}
//so that we do not lose the next character in the stream
i--;
}
else if (received[i] == MSG_CLEAR_STORED_FRAMES)
{
m_vGatheredVertices.clear();
m_vGatheredRGBPoints.clear();
}
}
if (m_bConfirmCaptured)
{
byteToSend = MSG_CONFIRM_CAPTURED;
m_pClientSocket->SendBytes(&byteToSend, 1);
m_bConfirmCaptured = false;
}
if (m_bConfirmCalibrated)
{
int size = 2 * (9 + 3) * sizeof(float) + sizeof(int) + 1;
char *buffer = new char[size];
buffer[0] = MSG_CONFIRM_CALIBRATED;
int i = 1;
memcpy(buffer + i, &calibration.iUsedMarkerId, 1 * sizeof(int));
i += 1 * sizeof(int);
memcpy(buffer + i, calibration.worldR[0].data(), 3 * sizeof(float));
i += 3 * sizeof(float);
memcpy(buffer + i, calibration.worldR[1].data(), 3 * sizeof(float));
i += 3 * sizeof(float);
memcpy(buffer + i, calibration.worldR[2].data(), 3 * sizeof(float));
i += 3 * sizeof(float);
memcpy(buffer + i, calibration.worldT.data(), 3 * sizeof(float));
i += 3 * sizeof(float);
memcpy(buffer + i, calibration.cameraR[0].data(), 3 * sizeof(float));
i += 3 * sizeof(float);
memcpy(buffer + i, calibration.cameraR[1].data(), 3 * sizeof(float));
i += 3 * sizeof(float);
memcpy(buffer + i, calibration.cameraR[2].data(), 3 * sizeof(float));
i += 3 * sizeof(float);
memcpy(buffer + i, calibration.cameraT.data(), 3 * sizeof(float));
m_pClientSocket->SendBytes(buffer, size);
m_bConfirmCalibrated = false;
}
}
void LiveScanClient::SendFrame(vector<Point3s> vertices, vector<RGB> RGB, vector<Body> body)
{
int size = RGB.size() * (3 + 3 * sizeof(short)) + sizeof(int);
vector<char> buffer(size);
char *ptr2 = (char*)vertices.data();
int pos = 0;
int nVertices = RGB.size();
memcpy(buffer.data() + pos, &nVertices, sizeof(nVertices));
pos += sizeof(nVertices);
for (unsigned int i = 0; i < RGB.size(); i++)
{
buffer[pos++] = RGB[i].rgbRed;
buffer[pos++] = RGB[i].rgbGreen;
buffer[pos++] = RGB[i].rgbBlue;
memcpy(buffer.data() + pos, ptr2, sizeof(short)* 3);
ptr2 += sizeof(short) * 3;
pos += sizeof(short) * 3;
}
int nBodies = body.size();
size += sizeof(nBodies);
for (int i = 0; i < nBodies; i++)
{
size += sizeof(body[i].bTracked);
int nJoints = body[i].vJoints.size();
size += sizeof(nJoints);
size += nJoints * (3 * sizeof(float) + 2 * sizeof(int));
size += nJoints * 2 * sizeof(float);
}
buffer.resize(size);
memcpy(buffer.data() + pos, &nBodies, sizeof(nBodies));
pos += sizeof(nBodies);
for (int i = 0; i < nBodies; i++)
{
memcpy(buffer.data() + pos, &body[i].bTracked, sizeof(body[i].bTracked));
pos += sizeof(body[i].bTracked);
int nJoints = body[i].vJoints.size();
memcpy(buffer.data() + pos, &nJoints, sizeof(nJoints));
pos += sizeof(nJoints);
for (int j = 0; j < nJoints; j++)
{
//Joint
memcpy(buffer.data() + pos, &body[i].vJoints[j].JointType, sizeof(JointType));
pos += sizeof(JointType);
memcpy(buffer.data() + pos, &body[i].vJoints[j].TrackingState, sizeof(TrackingState));
pos += sizeof(TrackingState);
//Joint position
memcpy(buffer.data() + pos, &body[i].vJoints[j].Position.X, sizeof(float));
pos += sizeof(float);
memcpy(buffer.data() + pos, &body[i].vJoints[j].Position.Y, sizeof(float));
pos += sizeof(float);
memcpy(buffer.data() + pos, &body[i].vJoints[j].Position.Z, sizeof(float));
pos += sizeof(float);
//JointInColorSpace
memcpy(buffer.data() + pos, &body[i].vJointsInColorSpace[j].X, sizeof(float));
pos += sizeof(float);
memcpy(buffer.data() + pos, &body[i].vJointsInColorSpace[j].Y, sizeof(float));
pos += sizeof(float);
}
}
m_pClientSocket->SendBytes((char*)&size, sizeof(int));
m_pClientSocket->SendBytes(buffer.data(), size);
}
void LiveScanClient::StoreFrame(Point3f *vertices, Point2f *mapping, RGB *color, vector<Body> &bodies, BYTE* bodyIndex)
{
std::vector<Point3f> goodVertices;
std::vector<RGB> goodColorPoints;
unsigned int nVertices = pCapture->nDepthFrameWidth * pCapture->nDepthFrameHeight;
for (unsigned int vertexIndex = 0; vertexIndex < nVertices; vertexIndex++)
{
if (m_bStreamOnlyBodies && bodyIndex[vertexIndex] >= bodies.size())
continue;
if (vertices[vertexIndex].Z >= 0 && mapping[vertexIndex].Y >= 0 && mapping[vertexIndex].Y < pCapture->nColorFrameHeight)
{
Point3f temp = vertices[vertexIndex];
RGB tempColor = color[(int)mapping[vertexIndex].X + (int)mapping[vertexIndex].Y * pCapture->nColorFrameWidth];
if (calibration.bCalibrated)
{
temp.X += calibration.worldT[0];
temp.Y += calibration.worldT[1];
temp.Z += calibration.worldT[2];
temp = RotatePoint(temp, calibration.worldR);
if (temp.X < m_vBounds[0] || temp.X > m_vBounds[3]
|| temp.Y < m_vBounds[1] || temp.Y > m_vBounds[4]
|| temp.Z < m_vBounds[2] || temp.Z > m_vBounds[5])
continue;
}
goodVertices.push_back(temp);
goodColorPoints.push_back(tempColor);
}
}
for (unsigned int i = 0; i < bodies.size(); i++)
{
for (unsigned int j = 0; j < bodies[i].vJoints.size(); j++)
{
if (calibration.bCalibrated)
{
bodies[i].vJoints[j].Position.X += calibration.worldT[0];
bodies[i].vJoints[j].Position.Y += calibration.worldT[1];
bodies[i].vJoints[j].Position.Z += calibration.worldT[2];
Point3f tempPoint(bodies[i].vJoints[j].Position.X, bodies[i].vJoints[j].Position.Y, bodies[i].vJoints[j].Position.Z);
tempPoint = RotatePoint(tempPoint, calibration.worldR);
bodies[i].vJoints[j].Position.X = tempPoint.X;
bodies[i].vJoints[j].Position.Y = tempPoint.Y;
bodies[i].vJoints[j].Position.Z = tempPoint.Z;
}
}
}
if (m_bFilter)
filter(goodVertices, goodColorPoints, m_nFilterNeighbors, m_fFilterThreshold);
vector<Point3s> goodVerticesShort(goodVertices.size());
for (unsigned int i = 0; i < goodVertices.size(); i++)
{
goodVerticesShort[i] = goodVertices[i];
}
m_vLastFrameBody = bodies;
m_vLastFrameVertices = goodVerticesShort;
m_vLastFrameRGB = goodColorPoints;
}
void LiveScanClient::ShowFPS()
{
if (m_hWnd)
{
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[64];
StringCchPrintf(szStatusMessage, _countof(szStatusMessage), L" FPS = %0.2f", fps);
if (SetStatusMessage(szStatusMessage, 1000, false))
{
m_nLastCounter = qpcNow.QuadPart;
m_nFramesSinceUpdate = 0;
}
}
}
void LiveScanClient::ReadIPFromFile()
{
ifstream file;
file.open("lastIP.txt");
if (file.is_open())
{
char lastUsedIPAddress[20];
file.getline(lastUsedIPAddress, 20);
file.close();
SetDlgItemTextA(m_hWnd, IDC_IP, lastUsedIPAddress);
}
}
void LiveScanClient::WriteIPToFile()
{
ofstream file;
file.open("lastIP.txt");
char lastUsedIPAddress[20];
GetDlgItemTextA(m_hWnd, IDC_IP, lastUsedIPAddress, 20);
file << lastUsedIPAddress;
file.close();
}