From eaacd47152e280baf330f88591dda6a04953a628 Mon Sep 17 00:00:00 2001 From: Wim Vriend Date: Sat, 17 Jul 2010 12:20:26 +0000 Subject: Added TrackIR support git-svn-id: svn+ssh://svn.code.sf.net/p/facetracknoir/code@15 19e81ba0-9b1a-49c3-bd6c-561e1906d5fb --- FaceTrackNoIR/FTIRServer.cpp | 255 +++++++++++++++++++++ FaceTrackNoIR/FTIRServer.h | 118 ++++++++++ FaceTrackNoIR/FTIRTypes.h | 196 ++++++++++++++++ FaceTrackNoIR/FaceApp.cpp | 3 + FaceTrackNoIR/FaceApp.h | 2 + FaceTrackNoIR/FaceTrackNoIR.cpp | 4 + FaceTrackNoIR/FaceTrackNoIR.ui | 2 +- FaceTrackNoIR/FaceTrackNoIR.vcproj | 146 +++++------- FaceTrackNoIR/GeneratedFiles/qrc_FaceTrackNoIR.cpp | 2 +- .../GeneratedFiles/ui_FTNoIR_ppjoycontrols.h | 2 +- FaceTrackNoIR/GeneratedFiles/ui_FaceTrackNoIR.h | 4 +- FaceTrackNoIR/Release/BuildLog.htm | Bin 11016 -> 11096 bytes FaceTrackNoIR/Release/mt.dep | 2 +- FaceTrackNoIR/images/TrackIR.ico | Bin 0 -> 15086 bytes FaceTrackNoIR/tracker.cpp | 140 +++++------ FaceTrackNoIR/tracker.h | 5 +- 16 files changed, 717 insertions(+), 164 deletions(-) create mode 100644 FaceTrackNoIR/FTIRServer.cpp create mode 100644 FaceTrackNoIR/FTIRServer.h create mode 100644 FaceTrackNoIR/FTIRTypes.h create mode 100644 FaceTrackNoIR/images/TrackIR.ico (limited to 'FaceTrackNoIR') diff --git a/FaceTrackNoIR/FTIRServer.cpp b/FaceTrackNoIR/FTIRServer.cpp new file mode 100644 index 00000000..bee31ca0 --- /dev/null +++ b/FaceTrackNoIR/FTIRServer.cpp @@ -0,0 +1,255 @@ +/******************************************************************************** +* FTIRServer FTIRServer is the Class, that communicates headpose-data * +* to games, using the NPClient.dll. * +* * +* Copyright (C) 2010 Wim Vriend (Developing) * +* Ron Hendriks (Testing and Research) * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the * +* Free Software Foundation; either version 3 of the License, or (at your * +* option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but * +* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program; if not, see . * +* * +********************************************************************************/ +/* + Modifications (last one on top): +*/ +#include "FTIRServer.h" + + +float FTIRServer::virtPosX = 0.0f; +float FTIRServer::virtPosY = 0.0f; +float FTIRServer::virtPosZ = 0.0f; + +float FTIRServer::virtRotX = 0.0f; +float FTIRServer::virtRotY = 0.0f; +float FTIRServer::virtRotZ = 0.0f; + +/** constructor **/ +FTIRServer::FTIRServer() { + + // Create events + m_StopThread = CreateEvent(0, TRUE, FALSE, 0); + m_WaitThread = CreateEvent(0, TRUE, FALSE, 0); + + ProgramName = ""; +} + +/** destructor **/ +FTIRServer::~FTIRServer() { + + // Trigger thread to stop + ::SetEvent(m_StopThread); + + // Wait until thread finished + ::WaitForSingleObject(m_WaitThread, INFINITE); + + // Close handles + ::CloseHandle(m_StopThread); + ::CloseHandle(m_WaitThread); + + // + // Free the DLL + // + FTIRClientLib.unload(); + + //terminates the QThread and waits for finishing the QThread + terminate(); + wait(); +} + +/** QThread run @override **/ +void FTIRServer::run() { + importSetPosition setposition; + + // + // Get the setposition function from the DLL and use it! + // + setposition = (importSetPosition) FTIRClientLib.resolve("SetPosition"); + if (setposition == NULL) { + qDebug() << "FTIRServer::run() says: SetPosition function not found in DLL!"; + return; + } + else { + setposition (7.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f); + } + + forever + { + // Check event for stop thread + if(::WaitForSingleObject(m_StopThread, 0) == WAIT_OBJECT_0) + { + // Set event + ::SetEvent(m_WaitThread); + return; + } + + if ( (pMemData != NULL) && (WaitForSingleObject(hFTIRMutex, 100) == WAIT_OBJECT_0) ) { + +// qDebug() << "FTIRServer says: virtRotX =" << virtRotX << " virtRotY =" << virtRotY; + setposition (virtPosX, virtPosY, virtPosZ, virtRotZ, virtRotX, virtRotY ); + + //qDebug() << "FTIRServer says: pMemData.xRot =" << pMemData->data.xRot << " yRot =" << pMemData->data.yRot; + ReleaseMutex(hFTIRMutex); + } + + // just for lower cpu load + msleep(15); + yieldCurrentThread(); + } +} + +// +// Create a memory-mapping to the Freetrack data. +// It contains the tracking data, a handle to the main-window and the program-name of the Game! +// +// +bool FTIRServer::FTIRCreateMapping(HANDLE handle) +{ + bool result; + + qDebug() << "FTIRCreateMapping says: Starting Function"; + + // + // A FileMapping is used to create 'shared memory' between the FTIRServer and the FTClient. + // + // Try to create a FileMapping to the Shared Memory. + // If one already exists: close it. + // + hFTIRMemMap = CreateFileMappingA( INVALID_HANDLE_VALUE , 00 , PAGE_READWRITE , 0 , + sizeof( TRACKIRDATA ) + sizeof( HANDLE ) + 100, + (LPCSTR) FTIR_MM_DATA ); + + if ( hFTIRMemMap != 0 ) { + qDebug() << "FTIRCreateMapping says: FileMapping Created!" << hFTIRMemMap; + } + + if ( ( hFTIRMemMap != 0 ) && ( (long) GetLastError == ERROR_ALREADY_EXISTS ) ) { + CloseHandle( hFTIRMemMap ); + hFTIRMemMap = 0; + } + + // + // Create a new FileMapping, Read/Write access + // + hFTIRMemMap = OpenFileMappingA( FILE_MAP_ALL_ACCESS , false , (LPCSTR) FTIR_MM_DATA ); + if ( ( hFTIRMemMap != 0 ) ) { + qDebug() << "FTIRCreateMapping says: FileMapping Created again:" << hFTIRMemMap; + pMemData = (FTIRMemMap *) MapViewOfFile(hFTIRMemMap, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(TRACKIRDATA) + sizeof(hFTIRMemMap) + 100); + if (pMemData != NULL) { + pMemData->RegisteredHandle = handle; // The game uses the handle, to send a message that the Program-Name was set! + } + hFTIRMutex = CreateMutexA(NULL, false, FTIR_MUTEX); + } + else { + QMessageBox::information(0, "FaceTrackNoIR error", QString("FTIRServer Error! \n")); + return false; + } + + result = false; +return result; +} + +// +// Destory the FileMapping to the shared memory +// +void FTIRServer::FTIRDestroyMapping() +{ + if ( pMemData != NULL ) { + UnmapViewOfFile ( pMemData ); + } + + CloseHandle( hFTIRMutex ); + CloseHandle( hFTIRMemMap ); + hFTIRMemMap = 0; +} + +// +// Check if the Client DLL exists and load it (to test it), if so. +// Returns 'true' if all seems OK. +// +bool FTIRServer::FTIRCheckClientDLL() +{ + QSettings settings("NaturalPoint", "NATURALPOINT\\NPClient Location"); // Registry settings (in HK_USER) + QString aLocation; // Location of Client DLL + QString aFileName; // File Path and Name + + //importProvider provider; + //char *pProvider; + + qDebug() << "FTCheckClientDLL says: Starting Function"; + + try { + + // + // Load the NPClient.dll from the current path of FaceTrackNoIR, because there is no + // guarantee TrackIR or GlovePIE is also installed. + // + // Write this path in the registry (under NaturalPoint/NATURALPOINT, for the game(s). + // + aLocation = QCoreApplication::applicationDirPath() + "/"; + qDebug() << "FTCheckClientDLL says: Location of DLL =" << aLocation; + + // + // Append a '/' to the Path and then the name of the dll. + // + aFileName = aLocation; + aFileName.append(FTIR_CLIENT_FILENAME); + qDebug() << "FTCheckClientDLL says: Full path of DLL =" << aFileName; + + if ( QFile::exists( aFileName ) ) { + qDebug() << "FTCheckClientDLL says: DLL exists!"; + // + // Write the path to the key in the Registry, so the game(s) can find it too... + // + settings.setValue( "Path" , aLocation ); + + // + // Load the DLL and map to the functions in it. + // + FTIRClientLib.setFileName(aFileName); + FTIRClientLib.load(); + //provider = (importProvider) FTIRClientLib.resolve("FTProvider"); + //if (provider) { + // pProvider = provider(); + // qDebug() << "FTCheckClientDLL says: Provider =" << pProvider; + //} + } + else { + QMessageBox::information(0, "FaceTrackNoIR error", QString("Necessary file (NPClient.dll) was NOT found!\n")); + return false; + } + } catch(...) { + settings.~QSettings(); + } + return true; +} + +// +// Scale the measured value to the Joystick values +// +float FTIRServer::scale2AnalogLimits( float x, float min_x, float max_x ) { +double y; +double local_x; + + local_x = x; + if (local_x > max_x) { + local_x = max_x; + } + if (local_x < min_x) { + local_x = min_x; + } + y = ( NP_AXIS_MAX * local_x ) / max_x; + + return (float) y; +} + +//END diff --git a/FaceTrackNoIR/FTIRServer.h b/FaceTrackNoIR/FTIRServer.h new file mode 100644 index 00000000..868beaaf --- /dev/null +++ b/FaceTrackNoIR/FTIRServer.h @@ -0,0 +1,118 @@ +/******************************************************************************** +* FTIRServer FTIRServer is the Class, that communicates headpose-data * +* to games, using the NPClient.dll. * +* * +* Copyright (C) 2010 Wim Vriend (Developing) * +* Ron Hendriks (Testing and Research) * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the * +* Free Software Foundation; either version 3 of the License, or (at your * +* option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but * +* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program; if not, see . * +* * +********************************************************************************/ +#pragma once +#ifndef INCLUDED_FTIRSERVER_H +#define INCLUDED_FTIRSERVER_H + +//#include "Windows.h" +#include "FTIRTypes.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef void (WINAPI *importSetPosition)(float x, float y, float z, float xRot, float yRot, float zRot); +//typedef bool (WINAPI *importGetData)(TFreeTrackData * data); +//typedef HANDLE (WINAPI *importGetMapHandle)(void); + +using namespace std; + +class FTIRServer : public QThread { + Q_OBJECT + +public: + + // public member methods + FTIRServer(); + ~FTIRServer(); + + bool FTIRCreateMapping(HANDLE handle); + void FTIRDestroyMapping(); + bool FTIRCheckClientDLL(); + + // protected member methods +protected: + void run(); + +private: + // Handles to neatly terminate thread... + HANDLE m_StopThread; + HANDLE m_WaitThread; + + HANDLE hFTIRMemMap; + FTIRMemMap *pMemData; + HANDLE hFTIRMutex; + + ///** member varables for saving the head pose **/ + //float headPosX; + //float headPosY; + //float headPosZ; + // + //float headRotX; + //float headRotY; + //float headRotZ; + //bool confid; + + + // Private properties + QString ProgramName; + QLibrary FTIRClientLib; + float scale2AnalogLimits( float x, float min_x, float max_x ); + +public: + + // Settings for calculating the Virtual Pose + static float virtPosX; + static float virtPosY; + static float virtPosZ; + + static float virtRotX; + static float virtRotY; + static float virtRotZ; + + //void setHeadPosX(float x) { headPosX = x; } + //void setHeadPosY(float y) { headPosY = y; } + //void setHeadPosZ(float z) { headPosZ = z; } + + //void setHeadRotX(float x) { headRotX = x; } + //void setHeadRotY(float y) { headRotY = y; } + //void setHeadRotZ(float z) { headRotZ = z; } + + void setVirtRotX(float rot) { virtRotX = scale2AnalogLimits (rot, -180.0f, 180.0f); } + void setVirtRotY(float rot) { virtRotY = scale2AnalogLimits (rot, -180.0f, 180.0f); } + void setVirtRotZ(float rot) { virtRotZ = scale2AnalogLimits (rot, -180.0f, 180.0f); } + + void setVirtPosX(float pos) { virtPosX = scale2AnalogLimits (pos, -50.0f, 50.0f); } + void setVirtPosY(float pos) { virtPosY = scale2AnalogLimits (pos, -50.0f, 50.0f); } + void setVirtPosZ(float pos) { virtPosZ = scale2AnalogLimits (pos, -50.0f, 50.0f); } + +}; + + +#endif//INCLUDED_FTIRSERVER_H +//END diff --git a/FaceTrackNoIR/FTIRTypes.h b/FaceTrackNoIR/FTIRTypes.h new file mode 100644 index 00000000..6402245e --- /dev/null +++ b/FaceTrackNoIR/FTIRTypes.h @@ -0,0 +1,196 @@ +/******************************************************************************** +* FTIRTypes FTIRTypes contains the specific type definitions for the * +* Fake TrackIR protocol. * +* It was modelled after FTTypes.cpp. * +* * +* Copyright (C) 2010 Wim Vriend (Developing) * +* Ron Hendriks (Testing and Research) * +* * +* This program is free software; you can redistribute it and/or modify it * +* under the terms of the GNU General Public License as published by the * +* Free Software Foundation; either version 3 of the License, or (at your * +* option) any later version. * +* * +* This program is distributed in the hope that it will be useful, but * +* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * +* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * +* more details. * +* * +* You should have received a copy of the GNU General Public License along * +* with this program; if not, see . * +* * +********************************************************************************/ +#pragma once +#ifndef INCLUDED_FTIRTYPES_H +#define INCLUDED_FTIRTYPES_H + +#include "Windows.h" +#include +#include + +//#include "Registry.h" + +// +// Versioning hasn't been worked out yet... +// +// The following is the previous spec definition of versioning info -- I can probably do +// something very similar to this -- will keep you posted. +// +// request version information using 2 messages, they cannot be expected to arrive in a specific order - so always parse using the High byte +// the messages have a NPCONTROL byte in the first parameter, and the second parameter has packed bytes. +// Message 1) (first parameter)NPCONTROL : (second parameter) (High Byte)NPVERSIONMAJOR (Low Byte) major version number data +// Message 2) (first parameter)NPCONTROL : (second parameter) (High Byte)NPVERSIONMINOR (Low Byte) minor version number data + +#define NPQUERYVERSION 1040 + +// CONTROL DATA SUBFIELDS +#define NPVERSIONMAJOR 1 +#define NPVERSIONMINOR 2 + +// DATA FIELDS +#define NPControl 8 // indicates a control data field + // the second parameter of a message bearing control data information contains a packed data format. + // The High byte indicates what the data is, and the Low byte contains the actual data +// roll, pitch, yaw +#define NPRoll 1 // +/- 16383 (representing +/- 180) [data = input - 16383] +#define NPPitch 2 // +/- 16383 (representing +/- 180) [data = input - 16383] +#define NPYaw 4 // +/- 16383 (representing +/- 180) [data = input - 16383] + +// x, y, z - remaining 6dof coordinates +#define NPX 16 // +/- 16383 [data = input - 16383] +#define NPY 32 // +/- 16383 [data = input - 16383] +#define NPZ 64 // +/- 16383 [data = input - 16383] + +#define NP_AXIS_MIN -16383 +#define NP_AXIS_MAX 16383 + +// raw object position from imager +#define NPRawX 128 // 0..25600 (actual value is multiplied x 100 to pass two decimal places of precision) [data = input / 100] +#define NPRawY 256 // 0..25600 (actual value is multiplied x 100 to pass two decimal places of precision) [data = input / 100] +#define NPRawZ 512 // 0..25600 (actual value is multiplied x 100 to pass two decimal places of precision) [data = input / 100] + +// x, y, z deltas from raw imager position +#define NPDeltaX 1024 // +/- 2560 (actual value is multiplied x 10 to pass two decimal places of precision) [data = (input / 10) - 256] +#define NPDeltaY 2048 // +/- 2560 (actual value is multiplied x 10 to pass two decimal places of precision) [data = (input / 10) - 256] +#define NPDeltaZ 4096 // +/- 2560 (actual value is multiplied x 10 to pass two decimal places of precision) [data = (input / 10) - 256] + +// raw object position from imager +#define NPSmoothX 8192 // 0..32766 (actual value is multiplied x 10 to pass one decimal place of precision) [data = input / 10] +#define NPSmoothY 16384 // 0..32766 (actual value is multiplied x 10 to pass one decimal place of precision) [data = input / 10] +#define NPSmoothZ 32768 // 0..32766 (actual value is multiplied x 10 to pass one decimal place of precision) [data = input / 10] + +// NPESULT values are returned from the Game Client API functions. +// +typedef enum tagNPResult +{ + NP_OK = 0, + NP_ERR_DEVICE_NOT_PRESENT, + NP_ERR_UNSUPPORTED_OS, + NP_ERR_INVALID_ARG, + NP_ERR_DLL_NOT_FOUND, + NP_ERR_NO_DATA, + NP_ERR_INTERNAL_DATA +} NPRESULT; + +// static const char* FTIR_CLIENT_LOCATION = "Software\\NaturalPoint\\NATURALPOINT\\NPClient Location"; + static const char* FTIR_CLIENT_FILENAME = "NPClient.dll"; + static const char* FTIR_MM_DATA = "{0F98177E-0E5C-4F86-8837-229D19B1701D}"; +// static const char* FTIR_MM_DATA = "FT_TIR_SharedMem"; +// static const char* FREETRACK = "Freetrack"; + static const char* FTIR_MUTEX = "FT_TIR_Mutex"; +// static const char* FT_PROGRAMID = "FT_ProgramID"; + static const char* FTIR_REGISTER_PROGRAMHANDLE = "FT_Register_Program_Handle"; + static const char* FTIR_UNREGISTER_PROGRAMHANDLE = "FT_UnRegister_Program_Handle"; + +typedef struct tagTrackIRData +{ + unsigned short wNPStatus; + unsigned short wPFrameSignature; + unsigned long dwNPIOData; + + float fNPRoll; + float fNPPitch; + float fNPYaw; + float fNPX; + float fNPY; + float fNPZ; + float fNPRawX; + float fNPRawY; + float fNPRawZ; + float fNPDeltaX; + float fNPDeltaY; + float fNPDeltaZ; + float fNPSmoothX; + float fNPSmoothY; + float fNPSmoothZ; + + //// unsigned short wError; + //// short iFrame; + //// unsigned short wUnknown3; + ////float xRot, yRot, zRot; + //// float x,y,z; + ////int iPadding[9]; + +} TRACKIRDATA, *LPTRACKIRDATA; + +struct FTIRMemMap { + // Emulators can check this + int iRecordSize; + TRACKIRDATA data; + int Version; + // Emulators should read these + HANDLE RegisteredHandle; + bool Transmission, Cursor; + long int RequestFormat; + long int ProgramProfileID; + // Read/Write + int LastError; + int Param[16]; + unsigned short ClientNotify1, ClientNotify2; + char Signature[400]; +}; +typedef FTIRMemMap * PFTIRMemMap; + +// +// Typedef for pointer to the notify callback function that is implemented within +// the client -- this function receives head tester reports from the game client API +// +typedef NPRESULT (__stdcall *PF_NOTIFYCALLBACK)( unsigned short, unsigned short ); + +// Typedefs for game client API functions (useful for declaring pointers to these +// functions within the client for use during GetProcAddress() ops) +// +typedef NPRESULT (__stdcall *PF_NP_REGISTERWINDOWHANDLE)( HWND ); +typedef NPRESULT (__stdcall *PF_NP_UNREGISTERWINDOWHANDLE)( void ); +typedef NPRESULT (__stdcall *PF_NP_REGISTERPROGRAMPROFILEID)( unsigned short ); +typedef NPRESULT (__stdcall *PF_NP_QUERYVERSION)( unsigned short* ); +typedef NPRESULT (__stdcall *PF_NP_REQUESTDATA)( unsigned short ); +typedef NPRESULT (__stdcall *PF_NP_GETDATA)( LPTRACKIRDATA ); +typedef NPRESULT (__stdcall *PF_NP_REGISTERNOTIFY)( PF_NOTIFYCALLBACK ); +typedef NPRESULT (__stdcall *PF_NP_UNREGISTERNOTIFY)( void ); +typedef NPRESULT (__stdcall *PF_NP_STARTCURSOR)( void ); +typedef NPRESULT (__stdcall *PF_NP_STOPCURSOR)( void ); +typedef NPRESULT (__stdcall *PF_NP_STARTDATATRANSMISSION)( void ); +typedef NPRESULT (__stdcall *PF_NP_STOPDATATRANSMISSION)( void ); + +//// Function Prototypes /////////////////////////////////////////////// +// +// Functions exported from game client API DLL ( note __stdcall calling convention +// is used for ease of interface to clients of differing implementations including +// C, C++, Pascal (Delphi) and VB. ) +// +//NPRESULT __stdcall NP_RegisterWindowHandle( HWND hWnd ); +//NPRESULT __stdcall NP_RegisterWindowHandle( HWND ); +//NPRESULT __stdcall NP_UnregisterWindowHandle( void ); +//NPRESULT __stdcall NP_RegisterProgramProfileID( unsigned short wPPID ); +//NPRESULT __stdcall NP_QueryVersion( unsigned short* pwVersion ); +//NPRESULT __stdcall NP_RequestData( unsigned short wDataReq ); +//NPRESULT __stdcall NP_GetData( LPTRACKIRDATA pTID ); +//NPRESULT __stdcall NP_RegisterNotify( PF_NOTIFYCALLBACK pfNotify ); +//NPRESULT __stdcall NP_UnregisterNotify( void ); +//NPRESULT __stdcall NP_StartCursor( void ); +//NPRESULT __stdcall NP_StopCursor( void ); +//NPRESULT __stdcall NP_StartDataTransmission( void ); +//NPRESULT __stdcall NP_StopDataTransmission( void ); + +#endif//INCLUDED_FTIRTYPES_H diff --git a/FaceTrackNoIR/FaceApp.cpp b/FaceTrackNoIR/FaceApp.cpp index 433e9b2d..231a07c9 100644 --- a/FaceTrackNoIR/FaceApp.cpp +++ b/FaceTrackNoIR/FaceApp.cpp @@ -1,6 +1,7 @@ #include "FaceApp.h" #include "windows.h" #include "FTTypes.h" +#include "FTIRTypes.h" #include // @@ -41,6 +42,8 @@ void FaceApp::SetupEventFilter( FaceTrackNoIR *window ) { mainWindow = window; msgID_FTClient = RegisterWindowMessageA ( FT_PROGRAMID ); qDebug() << "FaceApp::SetupEventFilter says: Message ID =" << msgID_FTClient; + msgID_FTIR_Register = RegisterWindowMessageA ( FTIR_REGISTER_PROGRAMHANDLE ); + msgID_FTIR_UnRegister = RegisterWindowMessageA ( FTIR_UNREGISTER_PROGRAMHANDLE ); ////if ( RegisterHotKey( window->winId(), 777, MOD_WIN, VK_HOME ) ) { //// qDebug() << "FaceApp::SetupEventFilter says: RegisterHotKey HOME =" << VK_HOME; diff --git a/FaceTrackNoIR/FaceApp.h b/FaceTrackNoIR/FaceApp.h index 4edd3227..75eb6df2 100644 --- a/FaceTrackNoIR/FaceApp.h +++ b/FaceTrackNoIR/FaceApp.h @@ -19,6 +19,8 @@ protected: private: FaceTrackNoIR *mainWindow; int msgID_FTClient; + int msgID_FTIR_Register; + int msgID_FTIR_UnRegister; }; #endif // FACEAPP_H diff --git a/FaceTrackNoIR/FaceTrackNoIR.cpp b/FaceTrackNoIR/FaceTrackNoIR.cpp index c8b717cf..8556eb5b 100644 --- a/FaceTrackNoIR/FaceTrackNoIR.cpp +++ b/FaceTrackNoIR/FaceTrackNoIR.cpp @@ -682,6 +682,7 @@ void FaceTrackNoIR::createIconGroupBox() ui.iconcomboBox->addItem(QIcon(QCoreApplication::applicationDirPath() + "/images/FlightGear.ico"), tr("FlightGear")); ui.iconcomboBox->addItem(QIcon(QCoreApplication::applicationDirPath() + "/images/FaceTrackNoIR.ico"), tr("FTNoir client")); ui.iconcomboBox->addItem(QIcon(QCoreApplication::applicationDirPath() + "/images/PPJoy.ico"), tr("Virtual Joystick")); + ui.iconcomboBox->addItem(QIcon(QCoreApplication::applicationDirPath() + "/images/TrackIR.ico"), tr("Fake TrackIR")); ui.iconcomboTrackerSource->addItem(QIcon(QCoreApplication::applicationDirPath() + "/images/SeeingMachines.ico"), tr("Face API")); ui.iconcomboTrackerSource->addItem(QIcon(QCoreApplication::applicationDirPath() + "/images/FaceTrackNoIR.ico"), tr("FTNoir server")); @@ -750,6 +751,9 @@ void FaceTrackNoIR::setIcon(int index) ui.btnShowServerControls->show(); ui.btnShowServerControls->setEnabled ( true ); break; + case TRACKIR: + ui.btnShowServerControls->hide(); + break; default: break; } diff --git a/FaceTrackNoIR/FaceTrackNoIR.ui b/FaceTrackNoIR/FaceTrackNoIR.ui index cbd4c769..01213b37 100644 --- a/FaceTrackNoIR/FaceTrackNoIR.ui +++ b/FaceTrackNoIR/FaceTrackNoIR.ui @@ -914,7 +914,7 @@ color:#000; -1 - 3 + 5 diff --git a/FaceTrackNoIR/FaceTrackNoIR.vcproj b/FaceTrackNoIR/FaceTrackNoIR.vcproj index 9995eec2..32418646 100644 --- a/FaceTrackNoIR/FaceTrackNoIR.vcproj +++ b/FaceTrackNoIR/FaceTrackNoIR.vcproj @@ -198,11 +198,11 @@ > + + + + + + + + + + @@ -468,98 +498,10 @@ RelativePath=".\UIElements\bubble_2_big.png" > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + @@ -715,6 +669,18 @@ /> + + + + + diff --git a/FaceTrackNoIR/GeneratedFiles/qrc_FaceTrackNoIR.cpp b/FaceTrackNoIR/GeneratedFiles/qrc_FaceTrackNoIR.cpp index f14c187b..85287b60 100644 --- a/FaceTrackNoIR/GeneratedFiles/qrc_FaceTrackNoIR.cpp +++ b/FaceTrackNoIR/GeneratedFiles/qrc_FaceTrackNoIR.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** Resource object code ** -** Created: Sun 13. Jun 15:55:11 2010 +** Created: Tue 29. Jun 20:59:33 2010 ** by: The Resource Compiler for Qt version 4.6.2 ** ** WARNING! All changes made in this file will be lost! diff --git a/FaceTrackNoIR/GeneratedFiles/ui_FTNoIR_ppjoycontrols.h b/FaceTrackNoIR/GeneratedFiles/ui_FTNoIR_ppjoycontrols.h index c712202d..b361c21e 100644 --- a/FaceTrackNoIR/GeneratedFiles/ui_FTNoIR_ppjoycontrols.h +++ b/FaceTrackNoIR/GeneratedFiles/ui_FTNoIR_ppjoycontrols.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'FTNoIR_ppjoycontrols.ui' ** -** Created: Mon 14. Jun 20:32:49 2010 +** Created: Tue 29. Jun 20:59:28 2010 ** by: Qt User Interface Compiler version 4.6.2 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! diff --git a/FaceTrackNoIR/GeneratedFiles/ui_FaceTrackNoIR.h b/FaceTrackNoIR/GeneratedFiles/ui_FaceTrackNoIR.h index 03e07ccb..b4200594 100644 --- a/FaceTrackNoIR/GeneratedFiles/ui_FaceTrackNoIR.h +++ b/FaceTrackNoIR/GeneratedFiles/ui_FaceTrackNoIR.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'FaceTrackNoIR.ui' ** -** Created: Sun 13. Jun 16:10:04 2010 +** Created: Tue 29. Jun 20:59:30 2010 ** by: Qt User Interface Compiler version 4.6.2 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! @@ -522,7 +522,7 @@ public: iconcomboBox->setObjectName(QString::fromUtf8("iconcomboBox")); iconcomboBox->setGeometry(QRect(10, 20, 151, 22)); iconcomboBox->setStyleSheet(QString::fromUtf8("")); - iconcomboBox->setMaxVisibleItems(3); + iconcomboBox->setMaxVisibleItems(5); btnShowServerControls = new QPushButton(groupGameProtocol); btnShowServerControls->setObjectName(QString::fromUtf8("btnShowServerControls")); btnShowServerControls->setEnabled(true); diff --git a/FaceTrackNoIR/Release/BuildLog.htm b/FaceTrackNoIR/Release/BuildLog.htm index 35239261..09e7b3af 100644 Binary files a/FaceTrackNoIR/Release/BuildLog.htm and b/FaceTrackNoIR/Release/BuildLog.htm differ diff --git a/FaceTrackNoIR/Release/mt.dep b/FaceTrackNoIR/Release/mt.dep index da1401d7..7f6bad00 100644 --- a/FaceTrackNoIR/Release/mt.dep +++ b/FaceTrackNoIR/Release/mt.dep @@ -1 +1 @@ -Manifest resource last updated at 21:14:55.58 on di 15-06-2010 +Manifest resource last updated at 9:54:44.39 on za 17-07-2010 diff --git a/FaceTrackNoIR/images/TrackIR.ico b/FaceTrackNoIR/images/TrackIR.ico new file mode 100644 index 00000000..99e02e7b Binary files /dev/null and b/FaceTrackNoIR/images/TrackIR.ico differ diff --git a/FaceTrackNoIR/tracker.cpp b/FaceTrackNoIR/tracker.cpp index 666f9c34..4cbd4453 100644 --- a/FaceTrackNoIR/tracker.cpp +++ b/FaceTrackNoIR/tracker.cpp @@ -95,6 +95,7 @@ Tracker::Tracker( int clientID ) { server_FT = 0; server_FG = 0; server_PPJoy = 0; + server_FTIR = 0; switch (selectedClient) { case FREE_TRACK: server_FT = new FTServer; // Create Free-track protocol-server @@ -111,6 +112,10 @@ Tracker::Tracker( int clientID ) { server_PPJoy = new PPJoyServer ( this ); // Create PPJoy protocol-server break; + case TRACKIR: + server_FTIR = new FTIRServer; // Create Fake-TIR protocol-server + break; + default: // should never be reached break; @@ -131,6 +136,9 @@ Tracker::~Tracker() { if (server_PPJoy) { server_PPJoy->deleteLater(); } + if (server_FTIR) { + server_FTIR->deleteLater(); + } // Trigger thread to stop ::SetEvent(m_StopThread); @@ -194,6 +202,19 @@ void Tracker::setup(QWidget *head, FaceTrackNoIR *parent) { if (server_PPJoy) { server_PPJoy->start(); // Start the thread } + + // + // Check if the NP Client DLL is available + // and create the necessary mapping to shared memory. + // The handle of the MainWindow is sent to 'The Game', so it can send a message back. + // + if (server_FTIR) { + DLL_Ok = server_FTIR->FTIRCheckClientDLL(); + DLL_Ok = server_FTIR->FTIRCreateMapping( mainApp->winId() ); + + server_FTIR->start(); // Start the thread + } + } /** QThread run method @override **/ @@ -356,6 +377,19 @@ void Tracker::run() { server_FT->setHeadPosY( Tracker::Y.headPos * 1000.0f); server_FT->setHeadPosZ( ( Tracker::Z.headPos - Tracker::Z.initial_headPos ) * 1000.0f); } + + // + // Copy the Raw values directly to Fake-trackIR server + // + //if (server_FTIR) { + // server_FTIR->setHeadRotX( Tracker::Pitch.headPos ); // rads + // server_FTIR->setHeadRotY( Tracker::Yaw.headPos ); + // server_FTIR->setHeadRotZ( Tracker::Roll.headPos); + + // server_FTIR->setHeadPosX( Tracker::X.headPos * 1000.0f); // From m to mm + // server_FTIR->setHeadPosY( Tracker::Y.headPos * 1000.0f); + // server_FTIR->setHeadPosZ( ( Tracker::Z.headPos - Tracker::Z.initial_headPos ) * 1000.0f); + //} } // @@ -437,6 +471,24 @@ void Tracker::run() { server_PPJoy->setVirtPosY ( ( Tracker::Y.invert * Tracker::Y.sens * (getSmoothFromList( &Y.rawList ) - Y.offset_headPos) ) * 100.0f ); server_PPJoy->setVirtPosZ ( ( Tracker::Z.invert * Tracker::Z.sens * (getSmoothFromList( &Z.rawList ) - Z.offset_headPos - Tracker::Z.initial_headPos) ) * 100.0f ); } + + // Fake-trackIR + if (server_FTIR) { + + float rotX = getDegreesFromRads ( Tracker::Pitch.invert * Tracker::Pitch.sens * Pitch.newPos ); + float rotY = getDegreesFromRads ( Tracker::Yaw.invert * Tracker::Yaw.sens * Yaw.newPos ); + float rotZ = getDegreesFromRads ( Tracker::Roll.invert * Tracker::Roll.sens * Roll.newPos ); + qDebug() << "Tracker::run() says: virtRotX =" << rotX << " virtRotY =" << rotY; + + server_FTIR->setVirtRotX ( rotX ); + server_FTIR->setVirtRotY ( rotY ); + server_FTIR->setVirtRotZ ( rotZ ); + + server_FTIR->setVirtPosX ( ( Tracker::X.invert * Tracker::X.sens * (getSmoothFromList( &X.rawList ) - X.offset_headPos) ) * 1000.0f); + server_FTIR->setVirtPosY ( ( Tracker::Y.invert * Tracker::Y.sens * (getSmoothFromList( &Y.rawList ) - Y.offset_headPos) ) * 1000.0f ); + server_FTIR->setVirtPosZ ( ( Tracker::Z.invert * Tracker::Z.sens * (getSmoothFromList( &Z.rawList ) - Z.offset_headPos - Tracker::Z.initial_headPos) ) * 1000.0f ); + } + } else { // @@ -468,6 +520,15 @@ void Tracker::run() { server_PPJoy->setVirtPosY ( 0.0f ); server_PPJoy->setVirtPosZ ( 0.0f ); } + + if (server_FTIR) { + server_FTIR->setVirtRotX ( 0.0f ); + server_FTIR->setVirtRotY ( 0.0f ); + server_FTIR->setVirtRotZ ( 0.0f ); + server_FTIR->setVirtPosX ( 0.0f ); + server_FTIR->setVirtPosY ( 0.0f ); + server_FTIR->setVirtPosZ ( 0.0f ); + } } //for lower cpu load @@ -486,11 +547,6 @@ void Tracker::registerHeadPoseCallback() { /** Callback function for head-pose - only static methods could be called **/ void Tracker::receiveHeadPose(void *,smEngineHeadPoseData head_pose, smCameraVideoFrame video_frame) { - //SYSTEMTIME now; - //long newHeadPoseTime; - //float dT; -// float rate; - // // Perform actions, when valid data is received from faceAPI. // @@ -504,33 +560,18 @@ void Tracker::receiveHeadPose(void *,smEngineHeadPoseData head_pose, smCameraVid Tracker::setHeadRotY(head_pose.head_rot.y_rads); Tracker::setHeadRotZ(head_pose.head_rot.z_rads); - //// - //// Get the System-time and substract the time from the previous call. - //// dT will be used for the EWMA-filter. - //// - //GetSystemTime ( &now ); - //newHeadPoseTime = (((now.wHour * 3600) + (now.wMinute * 60) + now.wSecond) * 1000) + now.wMilliseconds; - //dT = (newHeadPoseTime - Tracker::prevHeadPoseTime) / 1000.0f; - - //// Remember time for next call - //Tracker::prevHeadPoseTime = newHeadPoseTime; - - - - // - // Calculate the new values, applying a low-pass filter. - // Add the values to their respective QList, for further smoothing - // // Pitch - //if (Tracker::useFilter) { - // Pitch.newPos = lowPassFilter ( getCorrectedNewRaw ( rateLimiter ( Tracker::Pitch.headPos, &Tracker::Pitch.prevRawPos, dT, 1.0f ), rotNeutralZone ), - // &Pitch.prevPos, dT, Tracker::Pitch.red ); - //} - //else { - Pitch.newPos = getCorrectedNewRaw ( Tracker::Pitch.headPos, rotNeutralZone ); - //} + Pitch.newPos = getCorrectedNewRaw ( Tracker::Pitch.headPos, rotNeutralZone ); addRaw2List ( &Pitch.rawList, Pitch.maxItems, Pitch.newPos ); + // Yaw + Yaw.newPos = getCorrectedNewRaw ( Tracker::Yaw.headPos, rotNeutralZone ); + addRaw2List ( &Yaw.rawList, Yaw.maxItems, Yaw.newPos ); + + // Roll + Roll.newPos = getCorrectedNewRaw ( Tracker::Roll.headPos, rotNeutralZone ); + addRaw2List ( &Roll.rawList, Roll.maxItems, Roll.newPos ); + // // Log something // @@ -540,54 +581,19 @@ void Tracker::receiveHeadPose(void *,smEngineHeadPoseData head_pose, smCameraVid // QTextStream out(&data); // out << "Limited Raw= " << rate << " dT= " << dT << " Raw= " << Tracker::Pitch.headPos << " Filtered= " << Pitch.newPos << '\n'; //} -// Tracker::Pitch.prevRawPos = Tracker::Pitch.headPos; - - // Yaw - //if (Tracker::useFilter) { - // Yaw.newPos = lowPassFilter ( getCorrectedNewRaw ( rateLimiter ( Tracker::Yaw.headPos, &Tracker::Yaw.prevRawPos, dT, 1.0f ), rotNeutralZone ), - // &Yaw.prevPos, dT, Tracker::Yaw.red ); - //} - //else { - Yaw.newPos = getCorrectedNewRaw ( Tracker::Yaw.headPos, rotNeutralZone ); - //} - addRaw2List ( &Yaw.rawList, Yaw.maxItems, Yaw.newPos ); - // Roll - //if (Tracker::useFilter) { - // Roll.newPos = lowPassFilter ( getCorrectedNewRaw (rateLimiter ( Tracker::Roll.headPos, &Tracker::Roll.prevRawPos, dT, 1.0f ), rotNeutralZone ), - // &Roll.prevPos, dT, Tracker::Roll.red ); - //} - //else { - Roll.newPos = getCorrectedNewRaw ( Tracker::Roll.headPos, rotNeutralZone ); - //} - addRaw2List ( &Roll.rawList, Roll.maxItems, Roll.newPos ); // X-position - //if (Tracker::useFilter) { - // X.newPos = lowPassFilter ( Tracker::X.headPos, &X.prevPos, dT, Tracker::X.red ); - //} - //else { - X.newPos = Tracker::X.headPos; - //} + X.newPos = Tracker::X.headPos; addRaw2List ( &X.rawList, X.maxItems, X.newPos ); // Y-position - //if (Tracker::useFilter) { - // Y.newPos = lowPassFilter ( Tracker::Y.headPos, &Y.prevPos, dT, Tracker::Y.red ); - //} - //else { - Y.newPos = Tracker::Y.headPos; - //} + Y.newPos = Tracker::Y.headPos; addRaw2List ( &Y.rawList, Y.maxItems, Y.newPos ); // Z-position (distance to camera, absolute!) - //if (Tracker::useFilter) { - // Z.newPos = lowPassFilter ( Tracker::Z.headPos, &Z.prevPos, dT, Tracker::Z.red ); - //} - //else { - Z.newPos = Tracker::Z.headPos; - //} + Z.newPos = Tracker::Z.headPos; addRaw2List ( &Z.rawList, Z.maxItems, Z.newPos ); } else { diff --git a/FaceTrackNoIR/tracker.h b/FaceTrackNoIR/tracker.h index 10021ffb..b535324f 100644 --- a/FaceTrackNoIR/tracker.h +++ b/FaceTrackNoIR/tracker.h @@ -38,6 +38,7 @@ #include "FTServer.h" // Freetrack-server #include "FGServer.h" // FlightGear-server #include "PPJoyServer.h" // Virtual Joystick +#include "FTIRServer.h" // FakeTIR-server // include the DirectX Library files #pragma comment (lib, "dinput8.lib") @@ -59,7 +60,8 @@ enum FTNoIR_Client { FREE_TRACK = 0, FLIGHTGEAR = 1, FTNOIR = 2, - PPJOY = 3 + PPJOY = 3, + TRACKIR = 4 }; class FaceTrackNoIR; // pre-define parent-class to avoid circular includes @@ -137,6 +139,7 @@ private: FTServer *server_FT; // Freetrack Server FGServer *server_FG; // FlightGear Server PPJoyServer *server_PPJoy; // PPJoy Server + FTIRServer *server_FTIR; // Fake TIR Server protected: // qthread override run method -- cgit v1.2.3