diff options
-rw-r--r-- | FTNoIR_Tracker_UDP/FTNoIR_Tracker_UDP.vcproj | 236 | ||||
-rw-r--r-- | FTNoIR_Tracker_UDP/ftnoir_tracker_base.h | 48 | ||||
-rw-r--r-- | FTNoIR_Tracker_UDP/ftnoir_tracker_base_global.h | 12 | ||||
-rw-r--r-- | FTNoIR_Tracker_UDP/ftnoir_tracker_udp.cpp | 181 | ||||
-rw-r--r-- | FaceTrackNoIR.suo | bin | 314880 -> 317440 bytes | |||
-rw-r--r-- | FaceTrackNoIR/tracker.cpp | 43 | ||||
-rw-r--r-- | FaceTrackNoIR/tracker.h | 1 | ||||
-rw-r--r-- | bin/FaceTrackNoIR.exe | bin | 737280 -> 741376 bytes |
8 files changed, 519 insertions, 2 deletions
diff --git a/FTNoIR_Tracker_UDP/FTNoIR_Tracker_UDP.vcproj b/FTNoIR_Tracker_UDP/FTNoIR_Tracker_UDP.vcproj new file mode 100644 index 00000000..d5df6fc0 --- /dev/null +++ b/FTNoIR_Tracker_UDP/FTNoIR_Tracker_UDP.vcproj @@ -0,0 +1,236 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="FTNoIR_Tracker_UDP"
+ ProjectGUID="{A42E7DE9-C1C5-48A2-8FEA-86D31CE3DA31}"
+ RootNamespace="FTNoIR_Tracker_UDP"
+ Keyword="Qt4VSv1.0"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)/bin"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=".\GeneratedFiles;"$(QTDIR)\include";".\GeneratedFiles\$(ConfigurationName)";"$(QTDIR)\include\qtmain";"$(QTDIR)\include\QtCore";"$(QTDIR)\include\QtNetwork";.\"
+ PreprocessorDefinitions="UNICODE;WIN32;QT_LARGEFILE_SUPPORT;QT_THREAD_SUPPORT;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;FTNOIR_TRACKER_BASE_LIB"
+ RuntimeLibrary="2"
+ TreatWChar_tAsBuiltInType="false"
+ DebugInformationFormat="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qtmain.lib QtCore4.lib QtNetwork4.lib"
+ OutputFile="$(OutDir)\$(ProjectName).dll"
+ AdditionalLibraryDirectories="$(QTDIR)\lib"
+ GenerateDebugInformation="false"
+ SubSystem="2"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".\GeneratedFiles;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\qtmain;$(QTDIR)\include\QtCore;.\"
+ PreprocessorDefinitions="UNICODE,WIN32,QT_LARGEFILE_SUPPORT,QT_THREAD_SUPPORT,QT_CORE_LIB,FTNOIR_TRACKER_UDP_LIB"
+ RuntimeLibrary="3"
+ TreatWChar_tAsBuiltInType="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qtmaind.lib QtCored4.lib"
+ OutputFile="$(OutDir)\$(ProjectName).dll"
+ AdditionalLibraryDirectories="$(QTDIR)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;c;def"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\ftnoir_tracker_udp.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\ftnoir_tracker_base.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ftnoir_tracker_base_global.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Form Files"
+ Filter="ui"
+ UniqueIdentifier="{99349809-55BA-4b9d-BF79-8FDBB0286EB3}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="qrc;*"
+ UniqueIdentifier="{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}"
+ ParseFiles="false"
+ >
+ </Filter>
+ <Filter
+ Name="Generated Files"
+ Filter="moc;h;cpp"
+ UniqueIdentifier="{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}"
+ SourceControlFiles="false"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ <Global
+ Name="lupdateOnBuild"
+ Value="0"
+ />
+ <Global
+ Name="MocDir"
+ Value=".\GeneratedFiles\$(ConfigurationName)"
+ />
+ <Global
+ Name="MocOptions"
+ Value=""
+ />
+ <Global
+ Name="QtVersion Win32"
+ Value="QT462_VS2005"
+ />
+ <Global
+ Name="RccDir"
+ Value=".\GeneratedFiles"
+ />
+ <Global
+ Name="UicDir"
+ Value=".\GeneratedFiles"
+ />
+ </Globals>
+</VisualStudioProject>
diff --git a/FTNoIR_Tracker_UDP/ftnoir_tracker_base.h b/FTNoIR_Tracker_UDP/ftnoir_tracker_base.h new file mode 100644 index 00000000..60c26ee1 --- /dev/null +++ b/FTNoIR_Tracker_UDP/ftnoir_tracker_base.h @@ -0,0 +1,48 @@ +#ifndef FTNOIR_TRACKER_BASE_H
+#define FTNOIR_TRACKER_BASE_H
+
+#include "ftnoir_tracker_base_global.h"
+
+//
+// x,y,z position in centimetres, yaw, pitch and roll in degrees...
+//
+#pragma pack(push, 2)
+struct THeadPoseData {
+ double x, y, z, yaw, pitch, roll;
+};
+#pragma pack(pop)
+
+// COM-Like abstract interface.
+// This interface doesn't require __declspec(dllexport/dllimport) specifier.
+// Method calls are dispatched via virtual table.
+// Any C++ compiler can use it.
+// Instances are obtained via factory function.
+struct ITracker
+{
+ virtual int Foo(int n) = 0;
+ virtual void Release() = 0;
+ virtual void Initialize() = 0;
+ virtual void StartTracker() = 0;
+ virtual void GiveHeadPoseData(THeadPoseData *data) = 0;
+};
+
+// Handle type. In C++ language the iterface type is used.
+typedef ITracker* TRACKERHANDLE;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+#ifdef __cplusplus
+# define EXTERN_C extern "C"
+#else
+# define EXTERN_C
+#endif // __cplusplus
+
+// Factory function that creates instances of the Xyz object.
+EXTERN_C
+FTNOIR_TRACKER_BASE_EXPORT
+TRACKERHANDLE
+__stdcall
+GetTracker(
+ void);
+
+#endif // FTNOIR_TRACKER_BASE_H
diff --git a/FTNoIR_Tracker_UDP/ftnoir_tracker_base_global.h b/FTNoIR_Tracker_UDP/ftnoir_tracker_base_global.h new file mode 100644 index 00000000..9f4a6118 --- /dev/null +++ b/FTNoIR_Tracker_UDP/ftnoir_tracker_base_global.h @@ -0,0 +1,12 @@ +#ifndef FTNOIR_TRACKER_BASE_GLOBAL_H
+#define FTNOIR_TRACKER_BASE_GLOBAL_H
+
+#include <Qt/qglobal.h>
+
+#ifdef FTNOIR_TRACKER_BASE_LIB
+# define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_EXPORT
+#else
+# define FTNOIR_TRACKER_BASE_EXPORT Q_DECL_IMPORT
+#endif
+
+#endif // FTNOIR_TRACKER_BASE_GLOBAL_H
diff --git a/FTNoIR_Tracker_UDP/ftnoir_tracker_udp.cpp b/FTNoIR_Tracker_UDP/ftnoir_tracker_udp.cpp new file mode 100644 index 00000000..005671cb --- /dev/null +++ b/FTNoIR_Tracker_UDP/ftnoir_tracker_udp.cpp @@ -0,0 +1,181 @@ +#include "ftnoir_tracker_base.h"
+#include <QThread>
+#include <QUdpSocket>
+#include "Windows.h"
+
+class FTNoIR_Tracker_UDP : public ITracker, QThread
+{
+public:
+ FTNoIR_Tracker_UDP();
+ ~FTNoIR_Tracker_UDP();
+
+ int Foo(int n);
+ void Release();
+ void Initialize();
+ void StartTracker();
+ void GiveHeadPoseData(THeadPoseData *data);
+
+protected:
+ void run(); // qthread override run method
+
+private:
+ // Handles to neatly terminate thread...
+ HANDLE m_StopThread;
+ HANDLE m_WaitThread;
+
+ // UDP socket-variables
+ QUdpSocket *inSocket; // Receive from ...
+ QUdpSocket *outSocket; // Send to ...
+ QHostAddress destIP; // Destination IP-address
+ int destPort; // Destination port-number
+ QHostAddress srcIP; // Source IP-address
+ int srcPort; // Source port-number
+
+ THeadPoseData newHeadPose; // Structure with new headpose
+};
+
+FTNoIR_Tracker_UDP::FTNoIR_Tracker_UDP()
+{
+ inSocket = 0;
+ outSocket = 0;
+
+ // Create events
+ m_StopThread = CreateEvent(0, TRUE, FALSE, 0);
+ m_WaitThread = CreateEvent(0, TRUE, FALSE, 0);
+
+ newHeadPose.x = 1.0f;
+ newHeadPose.y = 2.0f;
+ newHeadPose.z = 3.0f;
+ newHeadPose.yaw = 4.0f;
+ newHeadPose.pitch = 5.0f;
+ newHeadPose.roll = 6.0f;
+}
+
+FTNoIR_Tracker_UDP::~FTNoIR_Tracker_UDP()
+{
+ // Trigger thread to stop
+ ::SetEvent(m_StopThread);
+
+ // Wait until thread finished
+ if (isRunning()) {
+ ::WaitForSingleObject(m_WaitThread, INFINITE);
+ }
+
+ // Close handles
+ ::CloseHandle(m_StopThread);
+ ::CloseHandle(m_WaitThread);
+
+ if (inSocket) {
+ inSocket->disconnectFromHost();
+ inSocket->waitForDisconnected();
+ delete inSocket;
+ }
+
+ if (outSocket) {
+ outSocket->disconnectFromHost();
+ outSocket->waitForDisconnected();
+ delete outSocket;
+ }
+}
+
+/** QThread run @override **/
+void FTNoIR_Tracker_UDP::run() {
+
+int no_bytes;
+QHostAddress sender;
+quint16 senderPort;
+
+ //
+ // Create UDP-sockets if they don't exist already.
+ // They must be created here, because they must be in the new thread (FTNoIR_Tracker_UDP::run())
+ //
+ if (inSocket == 0) {
+ qDebug() << "FTNoIR_Tracker_UDP::run() creating insocket";
+ inSocket = new QUdpSocket();
+ // Connect the inSocket to the port, to receive messages
+ inSocket->bind(QHostAddress::Any, destPort+1);
+ }
+
+ //
+ // Read the data that was received.
+ //
+ forever {
+
+ // Check event for stop thread
+ if(::WaitForSingleObject(m_StopThread, 0) == WAIT_OBJECT_0)
+ {
+ // Set event
+ ::SetEvent(m_WaitThread);
+ qDebug() << "FTNoIR_Tracker_UDP::run() terminated run()";
+ return;
+ }
+
+ while (inSocket->hasPendingDatagrams()) {
+
+ QByteArray datagram;
+ datagram.resize(inSocket->pendingDatagramSize());
+
+ inSocket->readDatagram( (char * ) &newHeadPose, sizeof(newHeadPose), &sender, &senderPort);
+ }
+
+ //for lower cpu load
+ usleep(5000);
+ yieldCurrentThread();
+
+ }
+}
+
+int FTNoIR_Tracker_UDP::Foo(int n)
+{
+ return n * n;
+}
+
+void FTNoIR_Tracker_UDP::Release()
+{
+ delete this;
+}
+
+void FTNoIR_Tracker_UDP::Initialize()
+{
+ return;
+}
+
+void FTNoIR_Tracker_UDP::StartTracker()
+{
+ start( QThread::TimeCriticalPriority );
+ return;
+}
+
+void FTNoIR_Tracker_UDP::GiveHeadPoseData(THeadPoseData *data)
+{
+
+ newHeadPose.x += 1.0f;
+ newHeadPose.y += 2.0f;
+ newHeadPose.z += 3.0f;
+ newHeadPose.yaw += 4.0f;
+ newHeadPose.pitch += 5.0f;
+ newHeadPose.roll += 6.0f;
+
+ data->x = newHeadPose.x;
+ data->y = newHeadPose.y;
+ data->z = newHeadPose.z;
+ data->yaw = newHeadPose.yaw;
+ data->pitch = newHeadPose.pitch;
+ data->roll = newHeadPose.roll;
+ return;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Factory function that creates instances if the Tracker object.
+
+// Export both decorated and undecorated names.
+// GetTracker - Undecorated name, which can be easily used with GetProcAddress
+// Win32 API function.
+// _GetTracker@0 - Common name decoration for __stdcall functions in C language.
+#pragma comment(linker, "/export:GetTracker=_GetTracker@0")
+
+FTNOIR_TRACKER_BASE_EXPORT TRACKERHANDLE __stdcall GetTracker()
+{
+ return new FTNoIR_Tracker_UDP;
+}
+
diff --git a/FaceTrackNoIR.suo b/FaceTrackNoIR.suo Binary files differindex d64f82f7..48e0d28e 100644 --- a/FaceTrackNoIR.suo +++ b/FaceTrackNoIR.suo diff --git a/FaceTrackNoIR/tracker.cpp b/FaceTrackNoIR/tracker.cpp index 974b1251..73023b2f 100644 --- a/FaceTrackNoIR/tracker.cpp +++ b/FaceTrackNoIR/tracker.cpp @@ -194,7 +194,9 @@ Tracker::~Tracker() { ::SetEvent(m_StopThread);
// Wait until thread finished
- ::WaitForSingleObject(m_WaitThread, INFINITE);
+ if (isRunning()) {
+ ::WaitForSingleObject(m_WaitThread, INFINITE);
+ }
// Close handles
::CloseHandle(m_StopThread);
@@ -245,6 +247,7 @@ void Tracker::setup(QWidget *head, FaceTrackNoIR *parent) { if (selectedTracker == FT_FTNOIR) {
int fooResult = pTracker->Foo(42);
qDebug() << "Tracker::setup Foo gives: " << fooResult;
+ pTracker->StartTracker();
}
// set up the line edits for calling
@@ -438,6 +441,13 @@ void Tracker::run() { }
# endif
+ if (selectedTracker == FT_FTNOIR) {
+ THeadPoseData newpose;
+ pTracker->GiveHeadPoseData(&newpose);
+ addHeadPose(newpose);
+ Tracker::confid = true;
+ }
+
//
// Get the System-time and substract the time from the previous call.
// dT will be used for the EWMA-filter.
@@ -653,7 +663,6 @@ void Tracker::run() { ReleaseMutex(Tracker::hTrackMutex);
server_Game->sendHeadposeToGame();
-
//for lower cpu load
usleep(10000);
yieldCurrentThread();
@@ -720,6 +729,36 @@ void Tracker::addHeadPose( smEngineHeadPoseData head_pose ) addRaw2List ( &Z.rawList, Z.maxItems, Tracker::Z.headPos );
}
+/** Add the headpose-data to the Lists **/
+void Tracker::addHeadPose( THeadPoseData head_pose )
+{
+ // Pitch
+ Tracker::Pitch.headPos = head_pose.pitch; // degrees
+ addRaw2List ( &Pitch.rawList, Pitch.maxItems, Tracker::Pitch.headPos );
+// Tracker::Pitch.confidence = head_pose.confidence; // Just this one ...
+ Tracker::Pitch.newSample = true;
+
+ // Yaw
+ Tracker::Yaw.headPos = head_pose.yaw; // degrees
+ addRaw2List ( &Yaw.rawList, Yaw.maxItems, Tracker::Yaw.headPos );
+
+ // Roll
+ Tracker::Roll.headPos = head_pose.roll; // degrees
+ addRaw2List ( &Roll.rawList, Roll.maxItems, Tracker::Roll.headPos );
+
+ // X-position
+ Tracker::X.headPos = head_pose.x; // centimeters
+ addRaw2List ( &X.rawList, X.maxItems, Tracker::X.headPos );
+
+ // Y-position
+ Tracker::Y.headPos = head_pose.y; // centimeters
+ addRaw2List ( &Y.rawList, Y.maxItems, Tracker::Y.headPos );
+
+ // Z-position (distance to camera, absolute!)
+ Tracker::Z.headPos = head_pose.z; // centimeters
+ addRaw2List ( &Z.rawList, Z.maxItems, Tracker::Z.headPos );
+}
+
//
// Get the ProgramName from the Game and return it.
//
diff --git a/FaceTrackNoIR/tracker.h b/FaceTrackNoIR/tracker.h index 20fd60d8..ab14e06a 100644 --- a/FaceTrackNoIR/tracker.h +++ b/FaceTrackNoIR/tracker.h @@ -143,6 +143,7 @@ private: /** static callback method for the head pose tracking **/
static void STDCALL receiveHeadPose(void *,smEngineHeadPoseData head_pose, smCameraVideoFrame video_frame);
static void addHeadPose( smEngineHeadPoseData head_pose );
+ static void addHeadPose( THeadPoseData head_pose );
static void addRaw2List ( QList<float> *rawList, float maxIndex, float raw );
static float lowPassFilter ( float newvalue, float *oldvalue, float dt, float coeff);
static float rateLimiter ( float newvalue, float *oldvalue, float dt, float max_rate);
diff --git a/bin/FaceTrackNoIR.exe b/bin/FaceTrackNoIR.exe Binary files differindex f15da144..438e6f3c 100644 --- a/bin/FaceTrackNoIR.exe +++ b/bin/FaceTrackNoIR.exe |