diff --git a/LiveScanClient/KinectClient.vcxproj b/LiveScanClient/KinectClient.vcxproj index 9c01116..4ce212d 100644 --- a/LiveScanClient/KinectClient.vcxproj +++ b/LiveScanClient/KinectClient.vcxproj @@ -13,6 +13,7 @@ + @@ -28,6 +29,7 @@ + diff --git a/LiveScanClient/KinectClient.vcxproj.filters b/LiveScanClient/KinectClient.vcxproj.filters index 679951e..8bed42e 100644 --- a/LiveScanClient/KinectClient.vcxproj.filters +++ b/LiveScanClient/KinectClient.vcxproj.filters @@ -54,6 +54,9 @@ Header Files + + Header Files + @@ -86,6 +89,9 @@ Source Files + + Source Files + diff --git a/bin/LiveScanClient.exe b/bin/LiveScanClient.exe new file mode 100644 index 0000000..14811a4 Binary files /dev/null and b/bin/LiveScanClient.exe differ diff --git a/bin/LiveScanServer.exe b/bin/LiveScanServer.exe new file mode 100644 index 0000000..e2684b7 Binary files /dev/null and b/bin/LiveScanServer.exe differ diff --git a/include/LiveScanClient/framesFileWriterReader.h b/include/LiveScanClient/framesFileWriterReader.h new file mode 100644 index 0000000..48a4429 --- /dev/null +++ b/include/LiveScanClient/framesFileWriterReader.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#include +#include +#include "utils.h" + +class FramesFileWriterReader +{ +public: + FramesFileWriterReader(); + void openNewFileForWriting(); + void openCurrentFileForReading(); + + // leave filename blank if you want the filename to be generated from the date + void setCurrentFilename(std::string filename = ""); + + void writeFrame(std::vector points, std::vector colors); + bool readFrame(std::vector &outPoints, std::vector &outColors); + + bool openedForWriting() { return m_bFileOpenedForWriting; } + bool openedForReading() { return m_bFileOpenedForReading; } + + + void closeFileIfOpened(); + + ~FramesFileWriterReader(); + +private: + void resetTimer(); + int getRecordingTimeMilliseconds(); + + FILE *m_pFileHandle = nullptr; + bool m_bFileOpenedForWriting = false; + bool m_bFileOpenedForReading = false; + + std::string m_sFilename = ""; + + std::chrono::steady_clock::time_point recording_start_time; +}; \ No newline at end of file diff --git a/include/LiveScanClient/liveScanClient.h b/include/LiveScanClient/liveScanClient.h index 9c83d7f..350a692 100644 --- a/include/LiveScanClient/liveScanClient.h +++ b/include/LiveScanClient/liveScanClient.h @@ -20,6 +20,7 @@ #include "calibration.h" #include "utils.h" #include "KinectCapture.h" +#include "framesFileWriterReader.h" #include #include @@ -54,7 +55,11 @@ private: bool m_bShowDepth; bool m_bFrameCompression; int m_iCompressionLevel; - + bool m_bCaptureToFile; // false if capture frames to memory + + FramesFileWriterReader m_framesFileWriterReader; + + SocketClient *m_pClientSocket; std::vector m_vBounds; diff --git a/src/LiveScanClient/framesFileWriterReader.cpp b/src/LiveScanClient/framesFileWriterReader.cpp new file mode 100644 index 0000000..dfe8482 --- /dev/null +++ b/src/LiveScanClient/framesFileWriterReader.cpp @@ -0,0 +1,109 @@ +#include "framesFileWriterReader.h" + +#include + +FramesFileWriterReader::FramesFileWriterReader() +{ + +} + +void FramesFileWriterReader::closeFileIfOpened() +{ + if (m_pFileHandle == nullptr) + return; + + fclose(m_pFileHandle); + m_pFileHandle = nullptr; + m_bFileOpenedForReading = false; + m_bFileOpenedForWriting = false; +} + +void FramesFileWriterReader::resetTimer() +{ + recording_start_time = std::chrono::steady_clock::now(); +} + +int FramesFileWriterReader::getRecordingTimeMilliseconds() +{ + std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); + return static_cast(std::chrono::duration_cast(end - recording_start_time).count()); +} + +void FramesFileWriterReader::openCurrentFileForReading() +{ + closeFileIfOpened(); + + m_pFileHandle = fopen(m_sFilename.c_str(), "rb"); + + m_bFileOpenedForReading = true; + m_bFileOpenedForWriting = false; +} + +void FramesFileWriterReader::openNewFileForWriting() +{ + closeFileIfOpened(); + + char filename[1024]; + time_t t = time(0); + struct tm * now = localtime(&t); + sprintf(filename, "recording_%04d_%02d_%02d_%02d_%02d.bin", now->tm_year, now->tm_mon, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec); + m_sFilename = filename; + m_pFileHandle = fopen(filename, "wb"); + + m_bFileOpenedForReading = false; + m_bFileOpenedForWriting = true; + + resetTimer(); +} + +bool FramesFileWriterReader::readFrame(std::vector &outPoints, std::vector &outColors) +{ + if (!m_bFileOpenedForReading) + openCurrentFileForReading(); + + outPoints.clear(); + outColors.clear(); + FILE *f = m_pFileHandle; + int nPoints, timestamp; + char tmp[1024]; + int nread = fscanf_s(f, "%s %d %s %d", tmp, 1024, &nPoints, tmp, 1024, ×tamp); + + if (nread < 4) + return false; + + if (nPoints == 0) + return true; + + fgetc(f); // '\n' + outPoints.resize(nPoints); + outColors.resize(nPoints); + + fread((void*)outPoints.data(), sizeof(outPoints[0]), nPoints, f); + fread((void*)outColors.data(), sizeof(outColors[0]), nPoints, f); + fgetc(f); // '\n' + return true; + +} + + +void FramesFileWriterReader::writeFrame(std::vector points, std::vector colors) +{ + if (!m_bFileOpenedForWriting) + openNewFileForWriting(); + + FILE *f = m_pFileHandle; + + int nPoints = static_cast(points.size()); + fprintf(f, "n_points= %d\nframe_timestamp= %d\n", nPoints, getRecordingTimeMilliseconds()); + if (nPoints > 0) + { + fwrite((void*)points.data(), sizeof(points[0]), nPoints, f); + fwrite((void*)colors.data(), sizeof(colors[0]), nPoints, f); + } + fprintf(f, "\n"); +} + +FramesFileWriterReader::~FramesFileWriterReader() +{ + closeFileIfOpened(); +} \ No newline at end of file diff --git a/src/LiveScanClient/liveScanClient.cpp b/src/LiveScanClient/liveScanClient.cpp index 825aa93..1eaa269 100644 --- a/src/LiveScanClient/liveScanClient.cpp +++ b/src/LiveScanClient/liveScanClient.cpp @@ -53,6 +53,7 @@ LiveScanClient::LiveScanClient() : m_bFilter(false), m_bStreamOnlyBodies(false), m_bCaptureFrame(false), + m_bCaptureToFile(true), m_bConnected(false), m_bConfirmCaptured(false), m_bConfirmCalibrated(false), @@ -183,6 +184,8 @@ int LiveScanClient::Run(HINSTANCE hInstance, int nCmdShow) return static_cast(msg.wParam); } + + void LiveScanClient::UpdateFrame() { if (!pCapture->bInitialized) @@ -203,10 +206,19 @@ void LiveScanClient::UpdateFrame() if (m_bCaptureFrame) { - m_vGatheredVertices.push_back(m_vLastFrameVertices); - m_vGatheredRGBPoints.push_back(m_vLastFrameRGB); - m_bConfirmCaptured = true; - m_bCaptureFrame = false; + if (m_bCaptureToFile) + { + m_framesFileWriterReader.writeFrame(m_vLastFrameVertices, m_vLastFrameRGB); + m_bConfirmCaptured = true; + m_bCaptureFrame = false; + } + else + { + m_vGatheredVertices.push_back(m_vLastFrameVertices); + m_vGatheredRGBPoints.push_back(m_vLastFrameRGB); + m_bConfirmCaptured = true; + m_bCaptureFrame = false; + } } } @@ -515,18 +527,32 @@ void LiveScanClient::HandleSocket() { byteToSend = MSG_STORED_FRAME; m_pClientSocket->SendBytes(&byteToSend, 1); - - if (m_vGatheredRGBPoints.size() > 0) + if (m_bCaptureToFile) { - 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); + vector points; + vector colors; + bool res = m_framesFileWriterReader.readFrame(points, colors); + if (res == false) + { + int size = -1; + m_pClientSocket->SendBytes((char*)&size, 4); + } else + SendFrame(points, colors, m_vLastFrameBody); } else { - int size = -1; - m_pClientSocket->SendBytes((char*)&size, 4); + 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 @@ -692,7 +718,6 @@ void LiveScanClient::SendFrame(vector vertices, vector RGB, vector if (m_bFrameCompression) { - char buf[8]; // *2, because according to zstd documentation, increasing the size of the output buffer above a // bound should speed up the compression. int cBuffSize = ZSTD_compressBound(size) * 2;